fix: use default redirect uri when not passed on end_session endpoint (#201)
This commit is contained in:
parent
b84bcbed76
commit
53ede2ee8c
3 changed files with 44 additions and 26 deletions
|
@ -4,6 +4,7 @@ package oidc
|
||||||
//https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout
|
//https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout
|
||||||
type EndSessionRequest struct {
|
type EndSessionRequest struct {
|
||||||
IdTokenHint string `schema:"id_token_hint"`
|
IdTokenHint string `schema:"id_token_hint"`
|
||||||
|
ClientID string `schema:"client_id"`
|
||||||
PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"`
|
PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"`
|
||||||
State string `schema:"state"`
|
State string `schema:"state"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package op
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
httphelper "github.com/zitadel/oidc/pkg/http"
|
httphelper "github.com/zitadel/oidc/pkg/http"
|
||||||
"github.com/zitadel/oidc/pkg/oidc"
|
"github.com/zitadel/oidc/pkg/oidc"
|
||||||
|
@ -32,11 +33,7 @@ func EndSession(w http.ResponseWriter, r *http.Request, ender SessionEnder) {
|
||||||
RequestError(w, r, err)
|
RequestError(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var clientID string
|
err = ender.Storage().TerminateSession(r.Context(), session.UserID, session.ClientID)
|
||||||
if session.Client != nil {
|
|
||||||
clientID = session.Client.GetID()
|
|
||||||
}
|
|
||||||
err = ender.Storage().TerminateSession(r.Context(), session.UserID, clientID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
RequestError(w, r, oidc.DefaultToServerError(err, "error terminating session"))
|
RequestError(w, r, oidc.DefaultToServerError(err, "error terminating session"))
|
||||||
return
|
return
|
||||||
|
@ -58,28 +55,48 @@ func ParseEndSessionRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, ender SessionEnder) (*EndSessionRequest, error) {
|
func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, ender SessionEnder) (*EndSessionRequest, error) {
|
||||||
session := new(EndSessionRequest)
|
session := &EndSessionRequest{
|
||||||
if req.IdTokenHint == "" {
|
RedirectURI: ender.DefaultLogoutRedirectURI(),
|
||||||
return session, nil
|
|
||||||
}
|
}
|
||||||
|
if req.IdTokenHint != "" {
|
||||||
claims, err := VerifyIDTokenHint(ctx, req.IdTokenHint, ender.IDTokenHintVerifier())
|
claims, err := VerifyIDTokenHint(ctx, req.IdTokenHint, ender.IDTokenHintVerifier())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, oidc.ErrInvalidRequest().WithDescription("id_token_hint invalid").WithParent(err)
|
return nil, oidc.ErrInvalidRequest().WithDescription("id_token_hint invalid").WithParent(err)
|
||||||
}
|
}
|
||||||
session.UserID = claims.GetSubject()
|
session.UserID = claims.GetSubject()
|
||||||
session.Client, err = ender.Storage().GetClientByClientID(ctx, claims.GetAuthorizedParty())
|
if req.ClientID != "" && req.ClientID != claims.GetAuthorizedParty() {
|
||||||
|
return nil, oidc.ErrInvalidRequest().WithDescription("client_id does not match azp of id_token_hint")
|
||||||
|
}
|
||||||
|
req.ClientID = claims.GetAuthorizedParty()
|
||||||
|
}
|
||||||
|
if req.ClientID != "" {
|
||||||
|
client, err := ender.Storage().GetClientByClientID(ctx, req.ClientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, oidc.DefaultToServerError(err, "")
|
return nil, oidc.DefaultToServerError(err, "")
|
||||||
}
|
}
|
||||||
if req.PostLogoutRedirectURI == "" {
|
session.ClientID = client.GetID()
|
||||||
session.RedirectURI = ender.DefaultLogoutRedirectURI()
|
if req.PostLogoutRedirectURI != "" {
|
||||||
|
if err := ValidateEndSessionPostLogoutRedirectURI(req.PostLogoutRedirectURI, client); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
session.RedirectURI = req.PostLogoutRedirectURI
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.State != "" {
|
||||||
|
redirect, err := url.Parse(session.RedirectURI)
|
||||||
|
if err != nil {
|
||||||
|
return nil, oidc.DefaultToServerError(err, "")
|
||||||
|
}
|
||||||
|
session.RedirectURI = mergeQueryParams(redirect, url.Values{"state": {req.State}})
|
||||||
|
}
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
for _, uri := range session.Client.PostLogoutRedirectURIs() {
|
|
||||||
if uri == req.PostLogoutRedirectURI {
|
func ValidateEndSessionPostLogoutRedirectURI(postLogoutRedirectURI string, client Client) error {
|
||||||
session.RedirectURI = uri + "?state=" + req.State
|
for _, uri := range client.PostLogoutRedirectURIs() {
|
||||||
return session, nil
|
if uri == postLogoutRedirectURI {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, oidc.ErrInvalidRequest().WithDescription("post_logout_redirect_uri invalid")
|
return oidc.ErrInvalidRequest().WithDescription("post_logout_redirect_uri invalid")
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,6 @@ type StorageNotFoundError interface {
|
||||||
|
|
||||||
type EndSessionRequest struct {
|
type EndSessionRequest struct {
|
||||||
UserID string
|
UserID string
|
||||||
Client Client
|
ClientID string
|
||||||
RedirectURI string
|
RedirectURI string
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue