summaryrefslogtreecommitdiff
path: root/internal/oidc/flow_client_credentials.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/oidc/flow_client_credentials.go')
-rw-r--r--internal/oidc/flow_client_credentials.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/internal/oidc/flow_client_credentials.go b/internal/oidc/flow_client_credentials.go
index deb57a487..118f9496e 100644
--- a/internal/oidc/flow_client_credentials.go
+++ b/internal/oidc/flow_client_credentials.go
@@ -2,6 +2,7 @@ package oidc
import (
"context"
+ "net/url"
"time"
"github.com/ory/fosite"
@@ -92,3 +93,78 @@ func (c *ClientCredentialsGrantHandler) CanHandleTokenEndpointRequest(ctx contex
var (
_ fosite.TokenEndpointHandler = (*ClientCredentialsGrantHandler)(nil)
)
+
+// PopulateClientCredentialsFlowSessionWithAccessRequest is used to configure a session when performing a client credentials grant.
+func PopulateClientCredentialsFlowSessionWithAccessRequest(ctx Context, client fosite.Client, session *Session) (err error) {
+ var (
+ issuer *url.URL
+ )
+
+ if issuer, err = ctx.IssuerURL(); err != nil {
+ return fosite.ErrServerError.WithWrap(err).WithDebugf("Failed to determine the issuer with error: %s.", err.Error())
+ }
+
+ if client == nil {
+ return fosite.ErrServerError.WithDebug("Failed to get the client for the request.")
+ }
+
+ session.Subject = ""
+ session.Claims.Subject = client.GetID()
+ session.ClientID = client.GetID()
+ session.DefaultSession.Claims.Issuer = issuer.String()
+ session.DefaultSession.Claims.IssuedAt = ctx.GetClock().Now().UTC()
+ session.DefaultSession.Claims.RequestedAt = ctx.GetClock().Now().UTC()
+ session.ClientCredentials = true
+
+ return nil
+}
+
+// PopulateClientCredentialsFlowRequester is used to grant the authorized scopes and audiences when performing a client
+// credentials grant.
+func PopulateClientCredentialsFlowRequester(ctx Context, config fosite.Configurator, client fosite.Client, requester fosite.Requester) (err error) {
+ if client == nil || config == nil || requester == nil {
+ return fosite.ErrServerError.WithDebug("Failed to get the client, configuration, or requester for the request.")
+ }
+
+ scopes := requester.GetRequestedScopes()
+ audience := requester.GetRequestedAudience()
+
+ var authz, nauthz bool
+
+ strategy := config.GetScopeStrategy(ctx)
+
+ for _, scope := range scopes {
+ switch scope {
+ case ScopeOffline, ScopeOfflineAccess:
+ break
+ case ScopeAutheliaBearerAuthz:
+ authz = true
+ default:
+ nauthz = true
+ }
+
+ if strategy(client.GetScopes(), scope) {
+ requester.GrantScope(scope)
+ } else {
+ return fosite.ErrInvalidScope.WithDebugf("The scope '%s' is not authorized on client with id '%s'.", scope, client.GetID())
+ }
+ }
+
+ if authz && nauthz {
+ return fosite.ErrInvalidScope.WithDebugf("The scope '%s' must only be requested by itself or with the '%s' scope, no other scopes are permitted.", ScopeAutheliaBearerAuthz, ScopeOfflineAccess)
+ }
+
+ if authz && len(audience) == 0 {
+ return fosite.ErrInvalidRequest.WithDebugf("The scope '%s' requires the request also include an audience.", ScopeAutheliaBearerAuthz)
+ }
+
+ if err = config.GetAudienceStrategy(ctx)(client.GetAudience(), audience); err != nil {
+ return err
+ }
+
+ for _, aud := range audience {
+ requester.GrantAudience(aud)
+ }
+
+ return nil
+}