372 lines
16 KiB
Go
372 lines
16 KiB
Go
package oidc
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
|
)
|
|
|
|
func TestOpenIDConnectProvider_NewOpenIDConnectProvider_NotConfigured(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(nil, nil, nil)
|
|
|
|
assert.Nil(t, provider)
|
|
}
|
|
|
|
func TestNewOpenIDConnectProvider_ShouldEnableOptionalDiscoveryValues(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
EnablePKCEPlainChallenge: true,
|
|
HMACSecret: badhmac,
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: myclient,
|
|
Secret: MustDecodeSecret(badsecret),
|
|
SectorIdentifier: url.URL{Host: examplecomsid},
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
examplecom,
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
require.NotNil(t, provider)
|
|
|
|
disco := provider.GetOpenIDConnectWellKnownConfiguration(examplecom)
|
|
|
|
assert.Len(t, disco.SubjectTypesSupported, 2)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePublic)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePairwise)
|
|
|
|
assert.Len(t, disco.CodeChallengeMethodsSupported, 2)
|
|
assert.Contains(t, disco.CodeChallengeMethodsSupported, PKCEChallengeMethodSHA256)
|
|
assert.Contains(t, disco.CodeChallengeMethodsSupported, PKCEChallengeMethodSHA256)
|
|
}
|
|
|
|
func TestOpenIDConnectProvider_NewOpenIDConnectProvider_GoodConfiguration(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
HMACSecret: badhmac,
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: "a-client",
|
|
Secret: MustDecodeSecret("$plaintext$a-client-secret"),
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
},
|
|
{
|
|
ID: "b-client",
|
|
Description: "Normal Description",
|
|
Secret: MustDecodeSecret("$plaintext$b-client-secret"),
|
|
Policy: twofactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
Scopes: []string{
|
|
ScopeGroups,
|
|
},
|
|
GrantTypes: []string{
|
|
GrantTypeRefreshToken,
|
|
},
|
|
ResponseTypes: []string{
|
|
"token",
|
|
"code",
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
assert.NotNil(t, provider)
|
|
}
|
|
|
|
func TestOpenIDConnectProvider_NewOpenIDConnectProvider_GetOpenIDConnectWellKnownConfiguration(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
HMACSecret: "asbdhaaskmdlkamdklasmdlkams",
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: "a-client",
|
|
Secret: MustDecodeSecret("$plaintext$a-client-secret"),
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
require.NotNil(t, provider)
|
|
|
|
disco := provider.GetOpenIDConnectWellKnownConfiguration(examplecom)
|
|
|
|
assert.Equal(t, examplecom, disco.Issuer)
|
|
assert.Equal(t, "https://example.com/jwks.json", disco.JWKSURI)
|
|
assert.Equal(t, "https://example.com/api/oidc/authorization", disco.AuthorizationEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/token", disco.TokenEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/userinfo", disco.UserinfoEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/introspection", disco.IntrospectionEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/revocation", disco.RevocationEndpoint)
|
|
assert.Equal(t, "", disco.RegistrationEndpoint)
|
|
|
|
assert.Len(t, disco.CodeChallengeMethodsSupported, 1)
|
|
assert.Contains(t, disco.CodeChallengeMethodsSupported, PKCEChallengeMethodSHA256)
|
|
|
|
assert.Len(t, disco.ScopesSupported, 5)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeOpenID)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeOfflineAccess)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeProfile)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeGroups)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeEmail)
|
|
|
|
assert.Len(t, disco.ResponseModesSupported, 3)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeFormPost)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeQuery)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeFragment)
|
|
|
|
assert.Len(t, disco.SubjectTypesSupported, 2)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePublic)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePairwise)
|
|
|
|
assert.Len(t, disco.ResponseTypesSupported, 7)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeAuthorizationCodeFlow)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowIDToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowBoth)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowIDToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowBoth)
|
|
|
|
assert.Len(t, disco.TokenEndpointAuthMethodsSupported, 4)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretBasic)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretPost)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretJWT)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodNone)
|
|
|
|
assert.Len(t, disco.RevocationEndpointAuthMethodsSupported, 4)
|
|
assert.Contains(t, disco.RevocationEndpointAuthMethodsSupported, ClientAuthMethodClientSecretBasic)
|
|
assert.Contains(t, disco.RevocationEndpointAuthMethodsSupported, ClientAuthMethodClientSecretPost)
|
|
assert.Contains(t, disco.RevocationEndpointAuthMethodsSupported, ClientAuthMethodClientSecretJWT)
|
|
assert.Contains(t, disco.RevocationEndpointAuthMethodsSupported, ClientAuthMethodNone)
|
|
|
|
assert.Len(t, disco.IntrospectionEndpointAuthMethodsSupported, 2)
|
|
assert.Contains(t, disco.IntrospectionEndpointAuthMethodsSupported, ClientAuthMethodClientSecretBasic)
|
|
assert.Contains(t, disco.IntrospectionEndpointAuthMethodsSupported, ClientAuthMethodNone)
|
|
|
|
assert.Len(t, disco.GrantTypesSupported, 3)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeAuthorizationCode)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeRefreshToken)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeImplicit)
|
|
|
|
assert.Len(t, disco.RevocationEndpointAuthSigningAlgValuesSupported, 3)
|
|
assert.Equal(t, disco.RevocationEndpointAuthSigningAlgValuesSupported[0], SigningAlgHMACUsingSHA256)
|
|
assert.Equal(t, disco.RevocationEndpointAuthSigningAlgValuesSupported[1], SigningAlgHMACUsingSHA384)
|
|
assert.Equal(t, disco.RevocationEndpointAuthSigningAlgValuesSupported[2], SigningAlgHMACUsingSHA512)
|
|
|
|
assert.Len(t, disco.TokenEndpointAuthSigningAlgValuesSupported, 3)
|
|
assert.Equal(t, disco.TokenEndpointAuthSigningAlgValuesSupported[0], SigningAlgHMACUsingSHA256)
|
|
assert.Equal(t, disco.TokenEndpointAuthSigningAlgValuesSupported[1], SigningAlgHMACUsingSHA384)
|
|
assert.Equal(t, disco.TokenEndpointAuthSigningAlgValuesSupported[2], SigningAlgHMACUsingSHA512)
|
|
|
|
assert.Len(t, disco.IDTokenSigningAlgValuesSupported, 1)
|
|
assert.Contains(t, disco.IDTokenSigningAlgValuesSupported, SigningAlgRSAUsingSHA256)
|
|
|
|
assert.Len(t, disco.UserinfoSigningAlgValuesSupported, 2)
|
|
assert.Equal(t, disco.UserinfoSigningAlgValuesSupported[0], SigningAlgRSAUsingSHA256)
|
|
assert.Equal(t, disco.UserinfoSigningAlgValuesSupported[1], SigningAlgNone)
|
|
|
|
require.Len(t, disco.RequestObjectSigningAlgValuesSupported, 2)
|
|
assert.Equal(t, SigningAlgRSAUsingSHA256, disco.RequestObjectSigningAlgValuesSupported[0])
|
|
assert.Equal(t, SigningAlgNone, disco.RequestObjectSigningAlgValuesSupported[1])
|
|
|
|
assert.Len(t, disco.ClaimsSupported, 18)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthenticationMethodsReference)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAudience)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthorizedParty)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimClientIdentifier)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimExpirationTime)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimIssuedAt)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimIssuer)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimJWTID)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimRequestedAt)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimSubject)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthenticationTime)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimNonce)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimPreferredEmail)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimEmailVerified)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimEmailAlts)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimGroups)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimPreferredUsername)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimFullName)
|
|
|
|
assert.Len(t, disco.PromptValuesSupported, 2)
|
|
assert.Contains(t, disco.PromptValuesSupported, PromptConsent)
|
|
assert.Contains(t, disco.PromptValuesSupported, PromptNone)
|
|
}
|
|
|
|
func TestOpenIDConnectProvider_NewOpenIDConnectProvider_GetOAuth2WellKnownConfiguration(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
HMACSecret: "asbdhaaskmdlkamdklasmdlkams",
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: "a-client",
|
|
Secret: MustDecodeSecret("$plaintext$a-client-secret"),
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
require.NotNil(t, provider)
|
|
|
|
disco := provider.GetOAuth2WellKnownConfiguration(examplecom)
|
|
|
|
assert.Equal(t, examplecom, disco.Issuer)
|
|
assert.Equal(t, "https://example.com/jwks.json", disco.JWKSURI)
|
|
assert.Equal(t, "https://example.com/api/oidc/authorization", disco.AuthorizationEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/token", disco.TokenEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/introspection", disco.IntrospectionEndpoint)
|
|
assert.Equal(t, "https://example.com/api/oidc/revocation", disco.RevocationEndpoint)
|
|
assert.Equal(t, "", disco.RegistrationEndpoint)
|
|
|
|
require.Len(t, disco.CodeChallengeMethodsSupported, 1)
|
|
assert.Equal(t, "S256", disco.CodeChallengeMethodsSupported[0])
|
|
|
|
assert.Len(t, disco.ScopesSupported, 5)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeOpenID)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeOfflineAccess)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeProfile)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeGroups)
|
|
assert.Contains(t, disco.ScopesSupported, ScopeEmail)
|
|
|
|
assert.Len(t, disco.ResponseModesSupported, 3)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeFormPost)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeQuery)
|
|
assert.Contains(t, disco.ResponseModesSupported, ResponseModeFragment)
|
|
|
|
assert.Len(t, disco.SubjectTypesSupported, 2)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePublic)
|
|
assert.Contains(t, disco.SubjectTypesSupported, SubjectTypePairwise)
|
|
|
|
assert.Len(t, disco.ResponseTypesSupported, 7)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeAuthorizationCodeFlow)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowIDToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeImplicitFlowBoth)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowIDToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowToken)
|
|
assert.Contains(t, disco.ResponseTypesSupported, ResponseTypeHybridFlowBoth)
|
|
|
|
assert.Len(t, disco.TokenEndpointAuthMethodsSupported, 4)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretBasic)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretPost)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodClientSecretJWT)
|
|
assert.Contains(t, disco.TokenEndpointAuthMethodsSupported, ClientAuthMethodNone)
|
|
|
|
assert.Len(t, disco.GrantTypesSupported, 3)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeAuthorizationCode)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeRefreshToken)
|
|
assert.Contains(t, disco.GrantTypesSupported, GrantTypeImplicit)
|
|
|
|
assert.Len(t, disco.ClaimsSupported, 18)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthenticationMethodsReference)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAudience)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthorizedParty)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimClientIdentifier)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimExpirationTime)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimIssuedAt)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimIssuer)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimJWTID)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimRequestedAt)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimSubject)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimAuthenticationTime)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimNonce)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimPreferredEmail)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimEmailVerified)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimEmailAlts)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimGroups)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimPreferredUsername)
|
|
assert.Contains(t, disco.ClaimsSupported, ClaimFullName)
|
|
}
|
|
|
|
func TestOpenIDConnectProvider_NewOpenIDConnectProvider_GetOpenIDConnectWellKnownConfigurationWithPlainPKCE(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
HMACSecret: "asbdhaaskmdlkamdklasmdlkams",
|
|
EnablePKCEPlainChallenge: true,
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: "a-client",
|
|
Secret: MustDecodeSecret("$plaintext$a-client-secret"),
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
require.NotNil(t, provider)
|
|
|
|
disco := provider.GetOpenIDConnectWellKnownConfiguration(examplecom)
|
|
|
|
require.Len(t, disco.CodeChallengeMethodsSupported, 2)
|
|
assert.Equal(t, PKCEChallengeMethodSHA256, disco.CodeChallengeMethodsSupported[0])
|
|
assert.Equal(t, PKCEChallengeMethodPlain, disco.CodeChallengeMethodsSupported[1])
|
|
}
|
|
|
|
func TestNewOpenIDConnectProviderDiscovery(t *testing.T) {
|
|
provider := NewOpenIDConnectProvider(&schema.OpenIDConnectConfiguration{
|
|
IssuerCertificateChain: schema.X509CertificateChain{},
|
|
IssuerPrivateKey: keyRSA2048,
|
|
HMACSecret: "asbdhaaskmdlkamdklasmdlkams",
|
|
EnablePKCEPlainChallenge: true,
|
|
Clients: []schema.OpenIDConnectClientConfiguration{
|
|
{
|
|
ID: "a-client",
|
|
Secret: MustDecodeSecret("$plaintext$a-client-secret"),
|
|
Policy: onefactor,
|
|
RedirectURIs: []string{
|
|
"https://google.com",
|
|
},
|
|
},
|
|
},
|
|
}, nil, nil)
|
|
|
|
a := provider.GetOpenIDConnectWellKnownConfiguration("https://auth.example.com")
|
|
|
|
data, err := json.Marshal(&a)
|
|
assert.NoError(t, err)
|
|
|
|
b := OpenIDConnectWellKnownConfiguration{}
|
|
|
|
assert.NoError(t, json.Unmarshal(data, &b))
|
|
|
|
assert.Equal(t, a, b)
|
|
|
|
y := provider.GetOAuth2WellKnownConfiguration("https://auth.example.com")
|
|
|
|
data, err = json.Marshal(&y)
|
|
assert.NoError(t, err)
|
|
|
|
z := OAuth2WellKnownConfiguration{}
|
|
|
|
assert.NoError(t, json.Unmarshal(data, &z))
|
|
|
|
assert.Equal(t, y, z)
|
|
}
|