summaryrefslogtreecommitdiff
path: root/internal/oidc/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/oidc/client.go')
-rw-r--r--internal/oidc/client.go272
1 files changed, 193 insertions, 79 deletions
diff --git a/internal/oidc/client.go b/internal/oidc/client.go
index 41d302d03..71b43d867 100644
--- a/internal/oidc/client.go
+++ b/internal/oidc/client.go
@@ -1,8 +1,10 @@
package oidc
import (
+ "github.com/go-crypt/crypt/algorithm"
"github.com/ory/fosite"
"github.com/ory/x/errorsx"
+ "gopkg.in/square/go-jose.v2"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/authorization"
@@ -11,8 +13,8 @@ import (
)
// NewClient creates a new Client.
-func NewClient(config schema.OpenIDConnectClientConfiguration) (client *Client) {
- client = &Client{
+func NewClient(config schema.OpenIDConnectClientConfiguration) (client Client) {
+ base := &BaseClient{
ID: config.ID,
Description: config.Description,
Secret: config.Secret,
@@ -40,14 +42,165 @@ func NewClient(config schema.OpenIDConnectClientConfiguration) (client *Client)
}
for _, mode := range config.ResponseModes {
- client.ResponseModes = append(client.ResponseModes, fosite.ResponseModeType(mode))
+ base.ResponseModes = append(base.ResponseModes, fosite.ResponseModeType(mode))
+ }
+
+ if config.TokenEndpointAuthMethod != "" && config.TokenEndpointAuthMethod != "auto" {
+ client = &FullClient{
+ BaseClient: base,
+ TokenEndpointAuthMethod: config.TokenEndpointAuthMethod,
+ }
+ } else {
+ client = base
}
return client
}
+// GetID returns the ID.
+func (c *BaseClient) GetID() string {
+ return c.ID
+}
+
+// GetDescription returns the Description.
+func (c *BaseClient) GetDescription() string {
+ if c.Description == "" {
+ c.Description = c.GetID()
+ }
+
+ return c.Description
+}
+
+// GetSecret returns the Secret.
+func (c *BaseClient) GetSecret() algorithm.Digest {
+ return c.Secret
+}
+
+// GetSectorIdentifier returns the SectorIdentifier for this client.
+func (c *BaseClient) GetSectorIdentifier() string {
+ return c.SectorIdentifier
+}
+
+// GetHashedSecret returns the Secret.
+func (c *BaseClient) GetHashedSecret() (secret []byte) {
+ if c.Secret == nil {
+ return []byte(nil)
+ }
+
+ return []byte(c.Secret.Encode())
+}
+
+// GetRedirectURIs returns the RedirectURIs.
+func (c *BaseClient) GetRedirectURIs() (redirectURIs []string) {
+ return c.RedirectURIs
+}
+
+// GetGrantTypes returns the GrantTypes.
+func (c *BaseClient) GetGrantTypes() fosite.Arguments {
+ if len(c.GrantTypes) == 0 {
+ return fosite.Arguments{"authorization_code"}
+ }
+
+ return c.GrantTypes
+}
+
+// GetResponseTypes returns the ResponseTypes.
+func (c *BaseClient) GetResponseTypes() fosite.Arguments {
+ if len(c.ResponseTypes) == 0 {
+ return fosite.Arguments{"code"}
+ }
+
+ return c.ResponseTypes
+}
+
+// GetScopes returns the Scopes.
+func (c *BaseClient) GetScopes() fosite.Arguments {
+ return c.Scopes
+}
+
+// GetAudience returns the Audience.
+func (c *BaseClient) GetAudience() fosite.Arguments {
+ return c.Audience
+}
+
+// GetResponseModes returns the valid response modes for this client.
+//
+// Implements the fosite.ResponseModeClient.
+func (c *BaseClient) GetResponseModes() []fosite.ResponseModeType {
+ return c.ResponseModes
+}
+
+// GetUserinfoSigningAlgorithm returns the UserinfoSigningAlgorithm.
+func (c *BaseClient) GetUserinfoSigningAlgorithm() string {
+ if c.UserinfoSigningAlgorithm == "" {
+ c.UserinfoSigningAlgorithm = SigningAlgorithmNone
+ }
+
+ return c.UserinfoSigningAlgorithm
+}
+
+// GetPAREnforcement returns EnforcePAR.
+func (c *BaseClient) GetPAREnforcement() bool {
+ return c.EnforcePAR
+}
+
+// GetPKCEEnforcement returns EnforcePKCE.
+func (c *BaseClient) GetPKCEEnforcement() bool {
+ return c.EnforcePKCE
+}
+
+// GetPKCEChallengeMethodEnforcement returns EnforcePKCEChallengeMethod.
+func (c *BaseClient) GetPKCEChallengeMethodEnforcement() bool {
+ return c.EnforcePKCEChallengeMethod
+}
+
+// GetPKCEChallengeMethod returns PKCEChallengeMethod.
+func (c *BaseClient) GetPKCEChallengeMethod() string {
+ return c.PKCEChallengeMethod
+}
+
+// GetAuthorizationPolicy returns Policy.
+func (c *BaseClient) GetAuthorizationPolicy() authorization.Level {
+ return c.Policy
+}
+
+// GetConsentPolicy returns Consent.
+func (c *BaseClient) GetConsentPolicy() ClientConsent {
+ return c.Consent
+}
+
+// GetConsentResponseBody returns the proper consent response body for this session.OIDCWorkflowSession.
+func (c *BaseClient) GetConsentResponseBody(consent *model.OAuth2ConsentSession) ConsentGetResponseBody {
+ body := ConsentGetResponseBody{
+ ClientID: c.ID,
+ ClientDescription: c.Description,
+ PreConfiguration: c.Consent.Mode == ClientConsentModePreConfigured,
+ }
+
+ if consent != nil {
+ body.Scopes = consent.RequestedScopes
+ body.Audience = consent.RequestedAudience
+ }
+
+ return body
+}
+
+// IsPublic returns the value of the Public property.
+func (c *BaseClient) IsPublic() bool {
+ return c.Public
+}
+
+// IsAuthenticationLevelSufficient returns if the provided authentication.Level is sufficient for the client of the AutheliaClient.
+func (c *BaseClient) IsAuthenticationLevelSufficient(level authentication.Level) bool {
+ if level == authentication.NotAuthenticated {
+ return false
+ }
+
+ return authorization.IsAuthLevelSufficient(level, c.Policy)
+}
+
// ValidatePKCEPolicy is a helper function to validate PKCE policy constraints on a per-client basis.
-func (c *Client) ValidatePKCEPolicy(r fosite.Requester) (err error) {
+func (c *BaseClient) ValidatePKCEPolicy(r fosite.Requester) (err error) {
form := r.GetRequestForm()
if c.EnforcePKCE {
@@ -70,7 +223,7 @@ func (c *Client) ValidatePKCEPolicy(r fosite.Requester) (err error) {
}
// ValidatePARPolicy is a helper function to validate additional policy constraints on a per-client basis.
-func (c *Client) ValidatePARPolicy(r fosite.Requester, prefix string) (err error) {
+func (c *BaseClient) ValidatePARPolicy(r fosite.Requester, prefix string) (err error) {
if c.EnforcePAR {
if !IsPushedAuthorizedRequest(r, prefix) {
switch requestURI := r.GetRequestForm().Get(FormParameterRequestURI); requestURI {
@@ -87,7 +240,7 @@ func (c *Client) ValidatePARPolicy(r fosite.Requester, prefix string) (err error
// ValidateResponseModePolicy is an additional check to the response mode parameter to ensure if it's omitted that the
// default response mode for the fosite.AuthorizeRequester is permitted.
-func (c *Client) ValidateResponseModePolicy(r fosite.AuthorizeRequester) (err error) {
+func (c *BaseClient) ValidateResponseModePolicy(r fosite.AuthorizeRequester) (err error) {
if r.GetResponseMode() != fosite.ResponseModeDefault {
return nil
}
@@ -109,91 +262,52 @@ func (c *Client) ValidateResponseModePolicy(r fosite.AuthorizeRequester) (err er
return errorsx.WithStack(fosite.ErrUnsupportedResponseMode.WithHintf(`The request omitted the response_mode making the default response_mode "%s" based on the other authorization request parameters but registered OAuth 2.0 client doesn't support this response_mode`, m))
}
-// IsAuthenticationLevelSufficient returns if the provided authentication.Level is sufficient for the client of the AutheliaClient.
-func (c *Client) IsAuthenticationLevelSufficient(level authentication.Level) bool {
- if level == authentication.NotAuthenticated {
- return false
- }
-
- return authorization.IsAuthLevelSufficient(level, c.Policy)
-}
-
-// GetSectorIdentifier returns the SectorIdentifier for this client.
-func (c *Client) GetSectorIdentifier() string {
- return c.SectorIdentifier
-}
-
-// GetConsentResponseBody returns the proper consent response body for this session.OIDCWorkflowSession.
-func (c *Client) GetConsentResponseBody(consent *model.OAuth2ConsentSession) ConsentGetResponseBody {
- body := ConsentGetResponseBody{
- ClientID: c.ID,
- ClientDescription: c.Description,
- PreConfiguration: c.Consent.Mode == ClientConsentModePreConfigured,
- }
-
- if consent != nil {
- body.Scopes = consent.RequestedScopes
- body.Audience = consent.RequestedAudience
- }
-
- return body
+// GetRequestURIs is an array of request_uri values that are pre-registered by the RP for use at the OP. Servers MAY
+// cache the contents of the files referenced by these URIs and not retrieve them at the time they are used in a request.
+// OPs can require that request_uri values used be pre-registered with the require_request_uri_registration
+// discovery parameter.
+func (c *FullClient) GetRequestURIs() []string {
+ return c.RequestURIs
}
-// GetID returns the ID.
-func (c *Client) GetID() string {
- return c.ID
+// GetJSONWebKeys returns the JSON Web Key Set containing the public key used by the client to authenticate.
+func (c *FullClient) GetJSONWebKeys() *jose.JSONWebKeySet {
+ return c.JSONWebKeys
}
-// GetHashedSecret returns the Secret.
-func (c *Client) GetHashedSecret() (secret []byte) {
- if c.Secret == nil {
- return []byte(nil)
- }
-
- return []byte(c.Secret.Encode())
+// GetJSONWebKeysURI returns the URL for lookup of JSON Web Key Set containing the
+// public key used by the client to authenticate.
+func (c *FullClient) GetJSONWebKeysURI() string {
+ return c.JSONWebKeysURI
}
-// GetRedirectURIs returns the RedirectURIs.
-func (c *Client) GetRedirectURIs() (redirectURIs []string) {
- return c.RedirectURIs
+// GetRequestObjectSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing Request
+// Objects sent to the OP. All Request Objects from this Client MUST be rejected, if not signed with this algorithm.
+func (c *FullClient) GetRequestObjectSigningAlgorithm() string {
+ return c.RequestObjectSigningAlgorithm
}
-// GetGrantTypes returns the GrantTypes.
-func (c *Client) GetGrantTypes() fosite.Arguments {
- if len(c.GrantTypes) == 0 {
- return fosite.Arguments{"authorization_code"}
+// GetTokenEndpointAuthMethod returns the requested Client Authentication Method for the Token Endpoint. The options are
+// client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none.
+func (c *FullClient) GetTokenEndpointAuthMethod() string {
+ if c.TokenEndpointAuthMethod == "" {
+ if c.Public {
+ c.TokenEndpointAuthMethod = ClientAuthMethodNone
+ } else {
+ c.TokenEndpointAuthMethod = ClientAuthMethodClientSecretPost
+ }
}
- return c.GrantTypes
+ return c.TokenEndpointAuthMethod
}
-// GetResponseTypes returns the ResponseTypes.
-func (c *Client) GetResponseTypes() fosite.Arguments {
- if len(c.ResponseTypes) == 0 {
- return fosite.Arguments{"code"}
+// GetTokenEndpointAuthSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing the JWT
+// [JWT] used to authenticate the Client at the Token Endpoint for the private_key_jwt and client_secret_jwt
+// authentication methods.
+func (c *FullClient) GetTokenEndpointAuthSigningAlgorithm() string {
+ if c.TokenEndpointAuthSigningAlgorithm == "" {
+ c.TokenEndpointAuthSigningAlgorithm = SigningAlgorithmRSAWithSHA256
}
- return c.ResponseTypes
-}
-
-// GetScopes returns the Scopes.
-func (c *Client) GetScopes() fosite.Arguments {
- return c.Scopes
-}
-
-// IsPublic returns the value of the Public property.
-func (c *Client) IsPublic() bool {
- return c.Public
-}
-
-// GetAudience returns the Audience.
-func (c *Client) GetAudience() fosite.Arguments {
- return c.Audience
-}
-
-// GetResponseModes returns the valid response modes for this client.
-//
-// Implements the fosite.ResponseModeClient.
-func (c *Client) GetResponseModes() []fosite.ResponseModeType {
- return c.ResponseModes
+ return c.TokenEndpointAuthSigningAlgorithm
}