Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions compose/compose_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type CommonStrategy struct {
type HMACSHAStrategyConfigurator interface {
fosite.AccessTokenLifespanProvider
fosite.RefreshTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.AuthorizeCodeLifespanProvider
fosite.TokenEntropyProvider
fosite.GlobalSecretProvider
Expand Down
6 changes: 6 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ type AccessTokenLifespanProvider interface {
GetAccessTokenLifespan(ctx context.Context) time.Duration
}

// TokenPrefixProvider returns the provider for configuring the token prefix.
type TokenPrefixProvider interface {
// GetAccessTokenLifespan returns the access token lifespan.
GetTokenPrefixProvider(ctx context.Context) string
}

// IDTokenLifespanProvider returns the provider for configuring the ID token lifespan.
type IDTokenLifespanProvider interface {
// GetIDTokenLifespan returns the ID token lifespan.
Expand Down
11 changes: 11 additions & 0 deletions config_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (
_ AuthorizeCodeLifespanProvider = (*Config)(nil)
_ RefreshTokenLifespanProvider = (*Config)(nil)
_ AccessTokenLifespanProvider = (*Config)(nil)
_ TokenPrefixProvider = (*Config)(nil)
_ ScopeStrategyProvider = (*Config)(nil)
_ AudienceStrategyProvider = (*Config)(nil)
_ RedirectSecureCheckerProvider = (*Config)(nil)
Expand Down Expand Up @@ -72,6 +73,9 @@ type Config struct {
// refresh tokens that never expire.
RefreshTokenLifespan time.Duration

// TokenPrefix sets the prefix for hmac tokens to help identify tokens. Defaults to "ory"
TokenPrefix string

// AuthorizeCodeLifespan sets how long an authorize code is going to be valid. Defaults to fifteen minutes.
AuthorizeCodeLifespan time.Duration

Expand Down Expand Up @@ -328,6 +332,13 @@ func (c *Config) GetAccessTokenIssuer(ctx context.Context) string {
return c.AccessTokenIssuer
}

func (c *Config) GetTokenPrefixProvider(_ context.Context) string {
if c.TokenPrefix == "" {
c.TokenPrefix = "ory"
}
return c.TokenPrefix
}

func (c *Config) GetJWTScopeField(ctx context.Context) jwt.JWTScopeFieldEnum {
return c.JWTScopeClaimKey
}
Expand Down
1 change: 1 addition & 0 deletions fosite.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type Configurator interface {
RefreshTokenScopesProvider
AccessTokenLifespanProvider
RefreshTokenLifespanProvider
TokenPrefixProvider
AuthorizeCodeLifespanProvider
TokenEntropyProvider
RotatedGlobalSecretsProvider
Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/flow_authorize_code_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type AuthorizeExplicitGrantHandler struct {
fosite.AuthorizeCodeLifespanProvider
fosite.AccessTokenLifespanProvider
fosite.RefreshTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.ScopeStrategyProvider
fosite.AudienceStrategyProvider
fosite.RedirectSecureCheckerProvider
Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/flow_authorize_implicit.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type AuthorizeImplicitGrantTypeHandler struct {

Config interface {
fosite.AccessTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.ScopeStrategyProvider
fosite.AudienceStrategyProvider
}
Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/flow_client_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ClientCredentialsGrantHandler struct {
fosite.ScopeStrategyProvider
fosite.AudienceStrategyProvider
fosite.AccessTokenLifespanProvider
fosite.TokenPrefixProvider
}
}

Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/flow_refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type RefreshTokenGrantHandler struct {
Config interface {
fosite.AccessTokenLifespanProvider
fosite.RefreshTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.ScopeStrategyProvider
fosite.AudienceStrategyProvider
fosite.RefreshTokenScopesProvider
Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/flow_resource_owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type ResourceOwnerPasswordCredentialsGrantHandler struct {
fosite.RefreshTokenScopesProvider
fosite.RefreshTokenLifespanProvider
fosite.AccessTokenLifespanProvider
fosite.TokenPrefixProvider
}
}

Expand Down
1 change: 1 addition & 0 deletions handler/oauth2/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
type HandleHelperConfigProvider interface {
fosite.AccessTokenLifespanProvider
fosite.RefreshTokenLifespanProvider
fosite.TokenPrefixProvider
}

type HandleHelper struct {
Expand Down
32 changes: 19 additions & 13 deletions handler/oauth2/strategy_hmacsha.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type HMACSHAStrategy struct {
Config interface {
fosite.AccessTokenLifespanProvider
fosite.RefreshTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.AuthorizeCodeLifespanProvider
}
prefix *string
Expand All @@ -35,9 +36,9 @@ func (h *HMACSHAStrategy) AuthorizeCodeSignature(ctx context.Context, token stri
return h.Enigma.Signature(token)
}

func (h *HMACSHAStrategy) getPrefix(part string) string {
func (h *HMACSHAStrategy) getPrefix(ctx context.Context, part string) string {
if h.prefix == nil {
prefix := "ory_%s_"
prefix := h.Config.GetTokenPrefixProvider(ctx) + "_%s_"
h.prefix = &prefix
} else if len(*h.prefix) == 0 {
return ""
Expand All @@ -46,12 +47,17 @@ func (h *HMACSHAStrategy) getPrefix(part string) string {
return fmt.Sprintf(*h.prefix, part)
}

func (h *HMACSHAStrategy) trimPrefix(token, part string) string {
return strings.TrimPrefix(token, h.getPrefix(part))
func (h *HMACSHAStrategy) trimPrefix(ctx context.Context, token, part string) string {
// Support natural migration from ory prefix to custom prefix
legacyPrefix := fmt.Sprintf("ory_%s_", part)
return strings.TrimPrefix(
strings.TrimPrefix(token, legacyPrefix),
h.getPrefix(ctx, part),
)
}

func (h *HMACSHAStrategy) setPrefix(token, part string) string {
return h.getPrefix(part) + token
func (h *HMACSHAStrategy) setPrefix(ctx context.Context, token, part string) string {
return h.getPrefix(ctx, part) + token
}

func (h *HMACSHAStrategy) GenerateAccessToken(ctx context.Context, _ fosite.Requester) (token string, signature string, err error) {
Expand All @@ -60,7 +66,7 @@ func (h *HMACSHAStrategy) GenerateAccessToken(ctx context.Context, _ fosite.Requ
return "", "", err
}

return h.setPrefix(token, "at"), sig, nil
return h.setPrefix(ctx, token, "at"), sig, nil
}

func (h *HMACSHAStrategy) ValidateAccessToken(ctx context.Context, r fosite.Requester, token string) (err error) {
Expand All @@ -73,7 +79,7 @@ func (h *HMACSHAStrategy) ValidateAccessToken(ctx context.Context, r fosite.Requ
return errorsx.WithStack(fosite.ErrTokenExpired.WithHintf("Access token expired at '%s'.", exp))
}

return h.Enigma.Validate(ctx, h.trimPrefix(token, "at"))
return h.Enigma.Validate(ctx, h.trimPrefix(ctx, token, "at"))
}

func (h *HMACSHAStrategy) GenerateRefreshToken(ctx context.Context, _ fosite.Requester) (token string, signature string, err error) {
Expand All @@ -82,21 +88,21 @@ func (h *HMACSHAStrategy) GenerateRefreshToken(ctx context.Context, _ fosite.Req
return "", "", err
}

return h.setPrefix(token, "rt"), sig, nil
return h.setPrefix(ctx, token, "rt"), sig, nil
}

func (h *HMACSHAStrategy) ValidateRefreshToken(ctx context.Context, r fosite.Requester, token string) (err error) {
var exp = r.GetSession().GetExpiresAt(fosite.RefreshToken)
if exp.IsZero() {
// Unlimited lifetime
return h.Enigma.Validate(ctx, h.trimPrefix(token, "rt"))
return h.Enigma.Validate(ctx, h.trimPrefix(ctx, token, "rt"))
}

if !exp.IsZero() && exp.Before(time.Now().UTC()) {
return errorsx.WithStack(fosite.ErrTokenExpired.WithHintf("Refresh token expired at '%s'.", exp))
}

return h.Enigma.Validate(ctx, h.trimPrefix(token, "rt"))
return h.Enigma.Validate(ctx, h.trimPrefix(ctx, token, "rt"))
}

func (h *HMACSHAStrategy) GenerateAuthorizeCode(ctx context.Context, _ fosite.Requester) (token string, signature string, err error) {
Expand All @@ -105,7 +111,7 @@ func (h *HMACSHAStrategy) GenerateAuthorizeCode(ctx context.Context, _ fosite.Re
return "", "", err
}

return h.setPrefix(token, "ac"), sig, nil
return h.setPrefix(ctx, token, "ac"), sig, nil
}

func (h *HMACSHAStrategy) ValidateAuthorizeCode(ctx context.Context, r fosite.Requester, token string) (err error) {
Expand All @@ -118,5 +124,5 @@ func (h *HMACSHAStrategy) ValidateAuthorizeCode(ctx context.Context, r fosite.Re
return errorsx.WithStack(fosite.ErrTokenExpired.WithHintf("Authorize code expired at '%s'.", exp))
}

return h.Enigma.Validate(ctx, h.trimPrefix(token, "ac"))
return h.Enigma.Validate(ctx, h.trimPrefix(ctx, token, "ac"))
}
17 changes: 17 additions & 0 deletions handler/oauth2/strategy_hmacsha_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,20 @@ func TestHMACAuthorizeCode(t *testing.T) {
})
}
}

func TestHMACTokenPrefix(t *testing.T) {
t.Run("PrefixToken", func(t *testing.T) {
hmacshaStrategy = HMACSHAStrategy{
Enigma: &hmac.HMACStrategy{Config: &fosite.Config{GlobalSecret: []byte("foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar")}},
Config: &fosite.Config{
AccessTokenLifespan: time.Hour * 24,
AuthorizeCodeLifespan: time.Hour * 24,
TokenPrefix: "abc",
},
}
token, signature, err := hmacshaStrategy.GenerateAccessToken(nil, &hmacValidCase)
assert.NoError(t, err)
assert.Equal(t, strings.Split(token, ".")[1], signature)
assert.Contains(t, token, "abc_at_")
})
}
1 change: 1 addition & 0 deletions handler/openid/flow_hybrid.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type OpenIDConnectHybridHandler struct {
fosite.IDTokenLifespanProvider
fosite.MinParameterEntropyProvider
fosite.ScopeStrategyProvider
fosite.TokenPrefixProvider
}
}

Expand Down
1 change: 1 addition & 0 deletions handler/openid/flow_hybrid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var hmacStrategy = &oauth2.HMACSHAStrategy{
GlobalSecret: []byte("some-super-cool-secret-that-nobody-knows-nobody-knows"),
},
},
Config: &fosite.Config{},
}

type defaultSession struct {
Expand Down
1 change: 1 addition & 0 deletions handler/rfc7523/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Handler struct {

Config interface {
fosite.AccessTokenLifespanProvider
fosite.TokenPrefixProvider
fosite.TokenURLProvider
fosite.GrantTypeJWTBearerCanSkipClientAuthProvider
fosite.GrantTypeJWTBearerIDOptionalProvider
Expand Down