Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use spec names for methods #51

Merged
merged 2 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions authorize_request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ func (f *Fosite) authorizeRequestParametersFromOpenIDConnectRequest(ctx context.
// if not signed with this algorithm. Request Objects are described in Section 6.1 of OpenID Connect Core 1.0 [OpenID.Core]. This algorithm MUST
// be used both when the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter).
// Servers SHOULD support RS256. The value none MAY be used. The default, if omitted, is that any algorithm supported by the OP and the RP MAY be used.
if oidcClient.GetRequestObjectSigningAlgorithm() != "" && oidcClient.GetRequestObjectSigningAlgorithm() != fmt.Sprintf("%s", t.Header[consts.JSONWebTokenHeaderAlgorithm]) {
return nil, errorsx.WithStack(ErrInvalidRequestObject.WithHintf("The request object uses signing algorithm '%s', but the requested OAuth 2.0 Client enforces signing algorithm '%s'.", t.Header[consts.JSONWebTokenHeaderAlgorithm], oidcClient.GetRequestObjectSigningAlgorithm()))
if oidcClient.GetRequestObjectSigningAlg() != "" && oidcClient.GetRequestObjectSigningAlg() != fmt.Sprintf("%s", t.Header[consts.JSONWebTokenHeaderAlgorithm]) {
return nil, errorsx.WithStack(ErrInvalidRequestObject.WithHintf("The request object uses signing algorithm '%s', but the requested OAuth 2.0 Client enforces signing algorithm '%s'.", t.Header[consts.JSONWebTokenHeaderAlgorithm], oidcClient.GetRequestObjectSigningAlg()))
}

if t.Method == jwt.SigningMethodNone {
Expand Down
18 changes: 9 additions & 9 deletions authorize_request_handler_oidc_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,63 +121,63 @@ func TestAuthorizeRequestParametersFromOpenIDConnectRequest(t *testing.T) {
{
d: "should fail because token invalid an no key set",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequestURI: {"foo"}},
client: &DefaultOpenIDConnectClient{RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{RequestObjectSigningAlg: "RS256"},
expectErr: ErrInvalidRequest,
expectForm: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}},
},
{
d: "should fail because token invalid",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequest: {"foo"}},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlg: "RS256"},
expectErr: ErrInvalidRequestObject,
expectForm: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}},
},
{
d: "should fail because kid does not exist",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequest: {mustGenerateAssertion(t, jwt.MapClaims{}, key, "does-not-exists")}},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlg: "RS256"},
expectErr: ErrInvalidRequestObject,
expectErrReason: "Unable to retrieve RSA signing key from OAuth 2.0 Client. The JSON Web Token uses signing key with kid 'does-not-exists', which could not be found.",
expectForm: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}},
},
{
d: "should fail because not RS256 token",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequest: {mustGenerateHSAssertion(t, jwt.MapClaims{})}},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlg: "RS256"},
expectErr: ErrInvalidRequestObject,
expectErrReason: "The request object uses signing algorithm 'HS256', but the requested OAuth 2.0 Client enforces signing algorithm 'RS256'.",
expectForm: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}},
},
{
d: "should pass and set request parameters properly",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterResponseType: {consts.ResponseTypeAuthorizationCodeFlow}, consts.FormParameterResponseMode: {consts.ResponseModeNone}, consts.FormParameterRequest: {validRequestObject}},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlg: "RS256"},
// The values from form are overwritten by the request object.
expectForm: url.Values{consts.FormParameterResponseType: {consts.ResponseTypeImplicitFlowToken}, consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequest: {validRequestObject}, "foo": {"bar"}, "baz": {"baz"}},
},
{
d: "should pass even if kid is unset",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequest: {validRequestObjectWithoutKid}},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlg: "RS256"},
expectForm: url.Values{consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequest: {validRequestObjectWithoutKid}, "foo": {"bar"}, "baz": {"baz"}},
},
{
d: "should fail because request uri is not whitelisted",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequestURI: {reqTS.URL}},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlgorithm: "RS256"},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlg: "RS256"},
expectForm: url.Values{consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequestURI: {reqTS.URL}, "foo": {"bar"}, "baz": {"baz"}},
expectErr: ErrInvalidRequestURI,
},
{
d: "should pass and set request_uri parameters properly and also fetch jwk from remote",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequestURI: {reqTS.URL}},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlgorithm: "RS256", RequestURIs: []string{reqTS.URL}},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlg: "RS256", RequestURIs: []string{reqTS.URL}},
expectForm: url.Values{consts.FormParameterResponseType: {"token"}, consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequestURI: {reqTS.URL}, "foo": {"bar"}, "baz": {"baz"}},
},
{
d: "should pass when request object uses algorithm none",
form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequest: {validNoneRequestObject}},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlgorithm: "none"},
client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlg: "none"},
expectForm: url.Values{consts.FormParameterState: {"some-state"}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequest: {validNoneRequestObject}, "foo": {"bar"}, "baz": {"baz"}},
},
{
Expand Down
38 changes: 19 additions & 19 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,18 @@ type OpenIDConnectClient interface {
// public key used by the client to authenticate.
GetJSONWebKeysURI() (uri string)

// GetRequestObjectSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing Request
// GetRequestObjectSigningAlg 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.
GetRequestObjectSigningAlgorithm() (alg string)
GetRequestObjectSigningAlg() (alg string)

// GetTokenEndpointAuthMethod 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.
GetTokenEndpointAuthMethod() (method string)

// GetTokenEndpointAuthSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing the
// GetTokenEndpointAuthSigningAlg 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.
GetTokenEndpointAuthSigningAlgorithm() (alg string)
GetTokenEndpointAuthSigningAlg() (alg string)

Client
}
Expand Down Expand Up @@ -124,7 +124,7 @@ type ResponseModeClient interface {

// ClientCredentialsFlowPolicyClient is a client which can allow implicit scopes in the client credentials flow.
type ClientCredentialsFlowPolicyClient interface {
GetClientCredentialsFlowAllowImplicitScope() bool
GetClientCredentialsFlowAllowImplicitScope() (allow bool)

Client
}
Expand All @@ -137,16 +137,16 @@ type JWTProfileClient interface {
GetAccessTokenSignedResponseKeyID() (kid string)

// GetEnableJWTProfileOAuthAccessTokens indicates this client should or should not issue JWT Profile Access Tokens.
GetEnableJWTProfileOAuthAccessTokens() (enable bool)
GetEnableJWTProfileOAuthAccessTokens() (enforce bool)

Client
}

// DefaultClient is a simple default implementation of the Client interface.
type DefaultClient struct {
ID string `json:"id"`
ClientSecret ClientSecret `json:"client_secret,omitempty"`
RotatedClientSecrets []ClientSecret `json:"rotated_client_secrets,omitempty"`
ClientSecret ClientSecret `json:"-"`
RotatedClientSecrets []ClientSecret `json:"-"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
ResponseTypes []string `json:"response_types"`
Expand All @@ -157,12 +157,12 @@ type DefaultClient struct {

type DefaultOpenIDConnectClient struct {
*DefaultClient
JSONWebKeysURI string `json:"jwks_uri"`
JSONWebKeys *jose.JSONWebKeySet `json:"jwks"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
RequestURIs []string `json:"request_uris"`
RequestObjectSigningAlgorithm string `json:"request_object_signing_alg"`
TokenEndpointAuthSigningAlgorithm string `json:"token_endpoint_auth_signing_alg"`
JSONWebKeysURI string `json:"jwks_uri"`
JSONWebKeys *jose.JSONWebKeySet `json:"jwks"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
RequestURIs []string `json:"request_uris"`
RequestObjectSigningAlg string `json:"request_object_signing_alg"`
TokenEndpointAuthSigningAlg string `json:"token_endpoint_auth_signing_alg"`
}

type DefaultResponseModeClient struct {
Expand Down Expand Up @@ -232,16 +232,16 @@ func (c *DefaultOpenIDConnectClient) GetJSONWebKeys() *jose.JSONWebKeySet {
return c.JSONWebKeys
}

func (c *DefaultOpenIDConnectClient) GetTokenEndpointAuthSigningAlgorithm() string {
if c.TokenEndpointAuthSigningAlgorithm == "" {
func (c *DefaultOpenIDConnectClient) GetTokenEndpointAuthSigningAlg() string {
if c.TokenEndpointAuthSigningAlg == "" {
return "RS256"
} else {
return c.TokenEndpointAuthSigningAlgorithm
return c.TokenEndpointAuthSigningAlg
}
}

func (c *DefaultOpenIDConnectClient) GetRequestObjectSigningAlgorithm() string {
return c.RequestObjectSigningAlgorithm
func (c *DefaultOpenIDConnectClient) GetRequestObjectSigningAlg() string {
return c.RequestObjectSigningAlg
}

func (c *DefaultOpenIDConnectClient) GetTokenEndpointAuthMethod() string {
Expand Down
2 changes: 1 addition & 1 deletion client_authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (s *DefaultClientAuthenticationStrategy) doAuthenticateAssertionParseAssert

kid, alg = getJWTHeaderKIDAlg(header)

if client.GetTokenEndpointAuthSigningAlgorithm() != alg {
if client.GetTokenEndpointAuthSigningAlg() != alg {
return nil, errorsx.WithStack(ErrInvalidClient.WithHintf("The requested OAuth 2.0 client does not support the token endpoint signing algorithm '%s'.", alg))
}

Expand Down
16 changes: 8 additions & 8 deletions client_authentication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldPassWithProperECDSAAssertionWhenJWKsAreSetWithinTheClientAndClientIdIsNotSetInTheRequest",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand All @@ -354,7 +354,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseRSAAssertionIsUsedButECDSAAssertionIsRequired",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand All @@ -369,7 +369,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseMalformedAssertionUsed",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": []string{"bad.assertion"}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}},
r: new(http.Request),
expectErr: ErrInvalidClient,
Expand All @@ -378,7 +378,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseExpired",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(-time.Hour).Unix(),
Expand All @@ -393,7 +393,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseNotBefore",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand All @@ -409,7 +409,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseIssuedInFuture",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand All @@ -425,7 +425,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseNoKeys",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: nil, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: nil, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand All @@ -440,7 +440,7 @@ func TestAuthenticateClient(t *testing.T) {
{
name: "ShouldFailBecauseNotBefore",
client: func(ts *httptest.Server) Client {
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}
return &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", ClientSecret: testClientSecretBar}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlg: "ES256"}
}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{
consts.ClaimSubject: "bar",
consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(),
Expand Down
12 changes: 6 additions & 6 deletions token/hmac/hmacsha.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ var b64 = base64.URLEncoding.WithPadding(base64.NoPadding)
// Generate generates a token and a matching signature or returns an error.
// This method implements rfc6819 Section 5.1.4.2.2: Use High Entropy for Secrets.
func (c *HMACStrategy) Generate(ctx context.Context) (string, string, error) {
c.Lock()
defer c.Unlock()
//c.Lock()
//defer c.Unlock()

secrets, err := c.Config.GetGlobalSecret(ctx)
secret, err := c.Config.GetGlobalSecret(ctx)
if err != nil {
return "", "", err
}

if len(secrets) < minimumSecretLength {
return "", "", errors.Errorf("secret for signing HMAC-SHA512/256 is expected to be 32 byte long, got %d byte", len(secrets))
if len(secret) < minimumSecretLength {
return "", "", errors.Errorf("secret for signing HMAC-SHA512/256 is expected to be 32 byte long, got %d byte", len(secret))
}

var signingKey [32]byte
copy(signingKey[:], secrets)
copy(signingKey[:], secret)

entropy := c.Config.GetTokenEntropy(ctx)
if entropy < minimumEntropy {
Expand Down
Loading