summaryrefslogtreecommitdiff
path: root/internal/handlers/handler_oauth_authorization_claims.go
blob: 7b8ab22fe7343d76610b202455920c5e47538631 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package handlers

import (
	"net/http"
	"net/url"

	oauthelia2 "authelia.com/provider/oauth2"

	"github.com/authelia/authelia/v4/internal/authentication"
	"github.com/authelia/authelia/v4/internal/middlewares"
	"github.com/authelia/authelia/v4/internal/model"
	"github.com/authelia/authelia/v4/internal/oidc"
	"github.com/authelia/authelia/v4/internal/session"
)

func handleOAuth2AuthorizationClaims(ctx *middlewares.AutheliaCtx, rw http.ResponseWriter, _ *http.Request, flow string, userSession session.UserSession, details *authentication.UserDetailsExtended, client oidc.Client, requester oauthelia2.Requester, issuer *url.URL, consent *model.OAuth2ConsentSession, extra map[string]any) (requests *oidc.ClaimsRequests, handled bool) {
	var err error

	if requester.GetRequestedScopes().Has(oidc.ScopeOpenID) {
		if requests, err = oidc.NewClaimRequests(requester.GetRequestForm()); err != nil {
			ctx.Logger.WithError(err).Errorf("%s Request with id '%s' on client with id '%s' could not be processed: error occurred parsing the claims parameter", flow, requester.GetID(), client.GetID())

			ctx.Providers.OpenIDConnect.WriteDynamicAuthorizeError(ctx, rw, requester, err)

			return nil, true
		}

		claimsStrategy := client.GetClaimsStrategy()
		scopeStrategy := ctx.Providers.OpenIDConnect.GetScopeStrategy(ctx)

		if err = claimsStrategy.ValidateClaimsRequests(ctx, scopeStrategy, client, requests); err != nil {
			ctx.Logger.WithError(oauthelia2.ErrorToDebugRFC6749Error(err)).Errorf("%s Request with id '%s' on client with id '%s' could not be processed: the client requested claims were not permitted.", flow, requester.GetID(), client.GetID())

			ctx.Providers.OpenIDConnect.WriteDynamicAuthorizeError(ctx, rw, requester, oauthelia2.ErrAccessDenied.WithHint("The requested subject was not the same subject that attempted to authorize the request."))

			return nil, true
		}

		if requested, ok := requests.MatchesIssuer(issuer); !ok {
			ctx.Logger.Errorf("%s Request with id '%s' on client with id '%s' could not be processed: the client requested issuer '%s' but the issuer for the token will be '%s' instead", flow, requester.GetID(), client.GetID(), requested, issuer.String())

			ctx.Providers.OpenIDConnect.WriteDynamicAuthorizeError(ctx, rw, requester, oauthelia2.ErrAccessDenied.WithHint("The requested issuer was not the same issuer that attempted to authorize the request."))

			return nil, true
		}

		if requested, ok := requests.MatchesSubject(consent.Subject.UUID.String()); !ok {
			ctx.Logger.Errorf("%s Request with id '%s' on client with id '%s' could not be processed: the client requested subject '%s' but the subject value for '%s' is '%s' for the '%s' sector identifier", flow, requester.GetID(), client.GetID(), requested, userSession.Username, consent.Subject.UUID, client.GetSectorIdentifierURI())

			ctx.Providers.OpenIDConnect.WriteDynamicAuthorizeError(ctx, rw, requester, oauthelia2.ErrAccessDenied.WithHint("The requested subject was not the same subject that attempted to authorize the request."))

			return nil, true
		}

		oidc.GrantScopeAudienceConsent(requester, consent)

		if err = claimsStrategy.PopulateIDTokenClaims(ctx, scopeStrategy, client, requester.GetGrantedScopes(), oauthelia2.Arguments(consent.GrantedClaims), requests.GetIDTokenRequests(), details, ctx.Clock.Now(), nil, extra); err != nil {
			ctx.Logger.Errorf("%s Response for Request with id '%s' on client with id '%s' could not be created: %s", flow, requester.GetID(), client.GetID(), oauthelia2.ErrorToDebugRFC6749Error(err))

			ctx.Providers.OpenIDConnect.WriteDynamicAuthorizeError(ctx, rw, requester, err)

			return nil, true
		}
	} else {
		oidc.GrantScopeAudienceConsent(requester, consent)
	}

	return requests, false
}