fix(op): do not redirect to unverified uri on error (#640)

Closes #627
This commit is contained in:
Tim Möhlmann 2024-08-21 10:29:14 +03:00 committed by GitHub
parent de034c8d24
commit 0aa61b0b98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -83,19 +83,27 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) {
if authReq.RequestParam != "" && authorizer.RequestObjectSupported() { if authReq.RequestParam != "" && authorizer.RequestObjectSupported() {
err = ParseRequestObject(ctx, authReq, authorizer.Storage(), IssuerFromContext(ctx)) err = ParseRequestObject(ctx, authReq, authorizer.Storage(), IssuerFromContext(ctx))
if err != nil { if err != nil {
AuthRequestError(w, r, authReq, err, authorizer) AuthRequestError(w, r, nil, err, authorizer)
return return
} }
} }
if authReq.ClientID == "" { if authReq.ClientID == "" {
AuthRequestError(w, r, authReq, fmt.Errorf("auth request is missing client_id"), authorizer) AuthRequestError(w, r, nil, fmt.Errorf("auth request is missing client_id"), authorizer)
return return
} }
if authReq.RedirectURI == "" { if authReq.RedirectURI == "" {
AuthRequestError(w, r, authReq, fmt.Errorf("auth request is missing redirect_uri"), authorizer) AuthRequestError(w, r, nil, fmt.Errorf("auth request is missing redirect_uri"), authorizer)
return return
} }
validation := ValidateAuthRequest
var client Client
validation := func(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) {
client, err = authorizer.Storage().GetClientByClientID(ctx, authReq.ClientID)
if err != nil {
return "", oidc.ErrInvalidRequestRedirectURI().WithDescription("unable to retrieve client by id").WithParent(err)
}
return ValidateAuthRequestClient(ctx, authReq, client, verifier)
}
if validater, ok := authorizer.(AuthorizeValidator); ok { if validater, ok := authorizer.(AuthorizeValidator); ok {
validation = validater.ValidateAuthRequest validation = validater.ValidateAuthRequest
} }
@ -113,11 +121,6 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) {
AuthRequestError(w, r, authReq, oidc.DefaultToServerError(err, "unable to save auth request"), authorizer) AuthRequestError(w, r, authReq, oidc.DefaultToServerError(err, "unable to save auth request"), authorizer)
return return
} }
client, err := authorizer.Storage().GetClientByClientID(ctx, req.GetClientID())
if err != nil {
AuthRequestError(w, r, req, oidc.DefaultToServerError(err, "unable to retrieve client by id"), authorizer)
return
}
RedirectToLogin(req.GetID(), client, w, r) RedirectToLogin(req.GetID(), client, w, r)
} }
@ -212,26 +215,37 @@ func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oi
authReq.RequestParam = "" authReq.RequestParam = ""
} }
// ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed // ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed.
//
// Deprecated: Use [ValidateAuthRequestClient] to prevent querying for the Client twice.
func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) { func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) {
ctx, span := tracer.Start(ctx, "ValidateAuthRequest") ctx, span := tracer.Start(ctx, "ValidateAuthRequest")
defer span.End() defer span.End()
client, err := storage.GetClientByClientID(ctx, authReq.ClientID)
if err != nil {
return "", oidc.ErrInvalidRequestRedirectURI().WithDescription("unable to retrieve client by id").WithParent(err)
}
return ValidateAuthRequestClient(ctx, authReq, client, verifier)
}
// ValidateAuthRequestClient validates the Auth request against the passed client.
// If id_token_hint is part of the request, the subject of the token is returned.
func ValidateAuthRequestClient(ctx context.Context, authReq *oidc.AuthRequest, client Client, verifier *IDTokenHintVerifier) (sub string, err error) {
ctx, span := tracer.Start(ctx, "ValidateAuthRequestClient")
defer span.End()
if err := ValidateAuthReqRedirectURI(client, authReq.RedirectURI, authReq.ResponseType); err != nil {
return "", err
}
authReq.MaxAge, err = ValidateAuthReqPrompt(authReq.Prompt, authReq.MaxAge) authReq.MaxAge, err = ValidateAuthReqPrompt(authReq.Prompt, authReq.MaxAge)
if err != nil { if err != nil {
return "", err return "", err
} }
client, err := storage.GetClientByClientID(ctx, authReq.ClientID)
if err != nil {
return "", oidc.DefaultToServerError(err, "unable to retrieve client by id")
}
authReq.Scopes, err = ValidateAuthReqScopes(client, authReq.Scopes) authReq.Scopes, err = ValidateAuthReqScopes(client, authReq.Scopes)
if err != nil { if err != nil {
return "", err return "", err
} }
if err := ValidateAuthReqRedirectURI(client, authReq.RedirectURI, authReq.ResponseType); err != nil {
return "", err
}
if err := ValidateAuthReqResponseType(client, authReq.ResponseType); err != nil { if err := ValidateAuthReqResponseType(client, authReq.ResponseType); err != nil {
return "", err return "", err
} }