124 lines
5.3 KiB
Go
124 lines
5.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/ory/fosite"
|
|
|
|
"github.com/authelia/authelia/v4/internal/middlewares"
|
|
"github.com/authelia/authelia/v4/internal/model"
|
|
"github.com/authelia/authelia/v4/internal/oidc"
|
|
)
|
|
|
|
// OpenIDConnectAuthorizationGET handles GET requests to the OpenID Connect 1.0 Authorization endpoint.
|
|
//
|
|
// https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
|
|
func OpenIDConnectAuthorizationGET(ctx *middlewares.AutheliaCtx, rw http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
requester fosite.AuthorizeRequester
|
|
responder fosite.AuthorizeResponder
|
|
client *oidc.Client
|
|
authTime time.Time
|
|
issuer string
|
|
err error
|
|
)
|
|
|
|
if requester, err = ctx.Providers.OpenIDConnect.Fosite.NewAuthorizeRequest(ctx, r); err != nil {
|
|
rfc := fosite.ErrorToRFC6749Error(err)
|
|
|
|
ctx.Logger.Errorf("Authorization Request failed with error: %s", rfc.GetDescription())
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, err)
|
|
|
|
return
|
|
}
|
|
|
|
clientID := requester.GetClient().GetID()
|
|
|
|
ctx.Logger.Debugf("Authorization Request with id '%s' on client with id '%s' is being processed", requester.GetID(), clientID)
|
|
|
|
if client, err = ctx.Providers.OpenIDConnect.Store.GetFullClient(clientID); err != nil {
|
|
if errors.Is(err, fosite.ErrNotFound) {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: client was not found", requester.GetID(), clientID)
|
|
} else {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: failed to find client: %+v", requester.GetID(), clientID, err)
|
|
}
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, err)
|
|
|
|
return
|
|
}
|
|
|
|
if issuer, err = ctx.ExternalRootURL(); err != nil {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: error occurred determining issuer: %+v", requester.GetID(), clientID, err)
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, fosite.ErrServerError.WithHint("Could not determine issuer."))
|
|
|
|
return
|
|
}
|
|
|
|
userSession := ctx.GetSession()
|
|
|
|
var subject uuid.UUID
|
|
|
|
if subject, err = ctx.Providers.OpenIDConnect.Store.GetSubject(ctx, client.GetSectorIdentifier(), userSession.Username); err != nil {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: error occurred retrieving subject for user '%s': %+v", requester.GetID(), client.GetID(), userSession.Username, err)
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, fosite.ErrServerError.WithHint("Could not retrieve the subject."))
|
|
|
|
return
|
|
}
|
|
|
|
var (
|
|
consent *model.OAuth2ConsentSession
|
|
handled bool
|
|
)
|
|
|
|
if consent, handled = handleOIDCAuthorizationConsent(ctx, issuer, client, userSession, subject, rw, r, requester); handled {
|
|
return
|
|
}
|
|
|
|
extraClaims := oidcGrantRequests(requester, consent, &userSession)
|
|
|
|
if authTime, err = userSession.AuthenticatedTime(client.Policy); err != nil {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: error occurred checking authentication time: %+v", requester.GetID(), client.GetID(), err)
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, fosite.ErrServerError.WithHint("Could not obtain the authentication time."))
|
|
|
|
return
|
|
}
|
|
|
|
ctx.Logger.Debugf("Authorization Request with id '%s' on client with id '%s' was successfully processed, proceeding to build Authorization Response", requester.GetID(), clientID)
|
|
|
|
oidcSession := oidc.NewSessionWithAuthorizeRequest(issuer, ctx.Providers.OpenIDConnect.KeyManager.GetActiveKeyID(),
|
|
userSession.Username, userSession.AuthenticationMethodRefs.MarshalRFC8176(), extraClaims, authTime, consent, requester)
|
|
|
|
ctx.Logger.Tracef("Authorization Request with id '%s' on client with id '%s' creating session for Authorization Response for subject '%s' with username '%s' with claims: %+v",
|
|
requester.GetID(), oidcSession.ClientID, oidcSession.Subject, oidcSession.Username, oidcSession.Claims)
|
|
ctx.Logger.Tracef("Authorization Request with id '%s' on client with id '%s' creating session for Authorization Response for subject '%s' with username '%s' with headers: %+v",
|
|
requester.GetID(), oidcSession.ClientID, oidcSession.Subject, oidcSession.Username, oidcSession.Headers)
|
|
|
|
if responder, err = ctx.Providers.OpenIDConnect.Fosite.NewAuthorizeResponse(ctx, requester, oidcSession); err != nil {
|
|
rfc := fosite.ErrorToRFC6749Error(err)
|
|
|
|
ctx.Logger.Errorf("Authorization Response for Request with id '%s' on client with id '%s' could not be created: %s", requester.GetID(), clientID, rfc.GetDescription())
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, err)
|
|
|
|
return
|
|
}
|
|
|
|
if err = ctx.Providers.StorageProvider.SaveOAuth2ConsentSessionGranted(ctx, consent.ID); err != nil {
|
|
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' could not be processed: error occurred saving consent session: %+v", requester.GetID(), client.GetID(), err)
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, fosite.ErrServerError.WithHint("Could not save the session."))
|
|
|
|
return
|
|
}
|
|
|
|
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeResponse(rw, requester, responder)
|
|
}
|