Skip to content

Commit e0bd8f6

Browse files
committed
change(handler): token exchange related stategy should not be inside the handler package
1 parent 17fb0ff commit e0bd8f6

File tree

7 files changed

+84
-140
lines changed

7 files changed

+84
-140
lines changed

client_authentication.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import (
2121
"github.com/ory/fosite/token/jwt"
2222
)
2323

24+
// CanSkipClientAuthenticationStrategy provides a method signature for checking if client authentication can be skipped.
25+
type CanSkipClientAuthenticationStrategy func(context.Context, AccessRequester) bool
26+
2427
// ClientAuthenticationStrategy provides a method signature for authenticating a client request
2528
type ClientAuthenticationStrategy func(context.Context, *http.Request, url.Values) (Client, error)
2629

config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ type GrantTypeJWTBearerCanSkipClientAuthProvider interface {
150150
GetGrantTypeJWTBearerCanSkipClientAuth(ctx context.Context) bool
151151
}
152152

153+
// GrantTypeTokenExchangeCanSkipClientAuthProvider returns the provider for configuring the grant type Token Exchange can skip client auth.
154+
type GrantTypeTokenExchangeCanSkipClientAuthProvider interface {
155+
// GetGrantTypeTokenExchangeCanSkipClientAuth returns the grant type Token Exchange can skip client auth.
156+
GetGrantTypeTokenExchangeCanSkipClientAuth(ctx context.Context) CanSkipClientAuthenticationStrategy
157+
}
158+
153159
// GrantTypeJWTBearerIDOptionalProvider returns the provider for configuring the grant type JWT bearer ID optional.
154160
type GrantTypeJWTBearerIDOptionalProvider interface {
155161
// GetGrantTypeJWTBearerIDOptional returns the grant type JWT bearer ID optional.

config_default.go

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,45 +23,46 @@ const (
2323
)
2424

2525
var (
26-
_ AuthorizeCodeLifespanProvider = (*Config)(nil)
27-
_ RefreshTokenLifespanProvider = (*Config)(nil)
28-
_ AccessTokenLifespanProvider = (*Config)(nil)
29-
_ ScopeStrategyProvider = (*Config)(nil)
30-
_ AudienceStrategyProvider = (*Config)(nil)
31-
_ RedirectSecureCheckerProvider = (*Config)(nil)
32-
_ RefreshTokenScopesProvider = (*Config)(nil)
33-
_ DisableRefreshTokenValidationProvider = (*Config)(nil)
34-
_ AccessTokenIssuerProvider = (*Config)(nil)
35-
_ JWTScopeFieldProvider = (*Config)(nil)
36-
_ AllowedPromptsProvider = (*Config)(nil)
37-
_ OmitRedirectScopeParamProvider = (*Config)(nil)
38-
_ MinParameterEntropyProvider = (*Config)(nil)
39-
_ SanitationAllowedProvider = (*Config)(nil)
40-
_ EnforcePKCEForPublicClientsProvider = (*Config)(nil)
41-
_ EnablePKCEPlainChallengeMethodProvider = (*Config)(nil)
42-
_ EnforcePKCEProvider = (*Config)(nil)
43-
_ GrantTypeJWTBearerCanSkipClientAuthProvider = (*Config)(nil)
44-
_ GrantTypeJWTBearerIDOptionalProvider = (*Config)(nil)
45-
_ GrantTypeJWTBearerIssuedDateOptionalProvider = (*Config)(nil)
46-
_ GetJWTMaxDurationProvider = (*Config)(nil)
47-
_ IDTokenLifespanProvider = (*Config)(nil)
48-
_ IDTokenIssuerProvider = (*Config)(nil)
49-
_ JWKSFetcherStrategyProvider = (*Config)(nil)
50-
_ ClientAuthenticationStrategyProvider = (*Config)(nil)
51-
_ SendDebugMessagesToClientsProvider = (*Config)(nil)
52-
_ ResponseModeHandlerExtensionProvider = (*Config)(nil)
53-
_ MessageCatalogProvider = (*Config)(nil)
54-
_ FormPostHTMLTemplateProvider = (*Config)(nil)
55-
_ TokenURLProvider = (*Config)(nil)
56-
_ GetSecretsHashingProvider = (*Config)(nil)
57-
_ HTTPClientProvider = (*Config)(nil)
58-
_ HMACHashingProvider = (*Config)(nil)
59-
_ AuthorizeEndpointHandlersProvider = (*Config)(nil)
60-
_ TokenEndpointHandlersProvider = (*Config)(nil)
61-
_ TokenIntrospectionHandlersProvider = (*Config)(nil)
62-
_ RevocationHandlersProvider = (*Config)(nil)
63-
_ PushedAuthorizeRequestHandlersProvider = (*Config)(nil)
64-
_ PushedAuthorizeRequestConfigProvider = (*Config)(nil)
26+
_ AuthorizeCodeLifespanProvider = (*Config)(nil)
27+
_ RefreshTokenLifespanProvider = (*Config)(nil)
28+
_ AccessTokenLifespanProvider = (*Config)(nil)
29+
_ ScopeStrategyProvider = (*Config)(nil)
30+
_ AudienceStrategyProvider = (*Config)(nil)
31+
_ RedirectSecureCheckerProvider = (*Config)(nil)
32+
_ RefreshTokenScopesProvider = (*Config)(nil)
33+
_ DisableRefreshTokenValidationProvider = (*Config)(nil)
34+
_ AccessTokenIssuerProvider = (*Config)(nil)
35+
_ JWTScopeFieldProvider = (*Config)(nil)
36+
_ AllowedPromptsProvider = (*Config)(nil)
37+
_ OmitRedirectScopeParamProvider = (*Config)(nil)
38+
_ MinParameterEntropyProvider = (*Config)(nil)
39+
_ SanitationAllowedProvider = (*Config)(nil)
40+
_ EnforcePKCEForPublicClientsProvider = (*Config)(nil)
41+
_ EnablePKCEPlainChallengeMethodProvider = (*Config)(nil)
42+
_ EnforcePKCEProvider = (*Config)(nil)
43+
_ GrantTypeTokenExchangeCanSkipClientAuthProvider = (*Config)(nil)
44+
_ GrantTypeJWTBearerCanSkipClientAuthProvider = (*Config)(nil)
45+
_ GrantTypeJWTBearerIDOptionalProvider = (*Config)(nil)
46+
_ GrantTypeJWTBearerIssuedDateOptionalProvider = (*Config)(nil)
47+
_ GetJWTMaxDurationProvider = (*Config)(nil)
48+
_ IDTokenLifespanProvider = (*Config)(nil)
49+
_ IDTokenIssuerProvider = (*Config)(nil)
50+
_ JWKSFetcherStrategyProvider = (*Config)(nil)
51+
_ ClientAuthenticationStrategyProvider = (*Config)(nil)
52+
_ SendDebugMessagesToClientsProvider = (*Config)(nil)
53+
_ ResponseModeHandlerExtensionProvider = (*Config)(nil)
54+
_ MessageCatalogProvider = (*Config)(nil)
55+
_ FormPostHTMLTemplateProvider = (*Config)(nil)
56+
_ TokenURLProvider = (*Config)(nil)
57+
_ GetSecretsHashingProvider = (*Config)(nil)
58+
_ HTTPClientProvider = (*Config)(nil)
59+
_ HMACHashingProvider = (*Config)(nil)
60+
_ AuthorizeEndpointHandlersProvider = (*Config)(nil)
61+
_ TokenEndpointHandlersProvider = (*Config)(nil)
62+
_ TokenIntrospectionHandlersProvider = (*Config)(nil)
63+
_ RevocationHandlersProvider = (*Config)(nil)
64+
_ PushedAuthorizeRequestHandlersProvider = (*Config)(nil)
65+
_ PushedAuthorizeRequestConfigProvider = (*Config)(nil)
6566
)
6667

6768
type Config struct {
@@ -148,6 +149,9 @@ type Config struct {
148149
// GrantTypeJWTBearerMaxDuration sets the maximum time after JWT issued date, during which the JWT is considered valid.
149150
GrantTypeJWTBearerMaxDuration time.Duration
150151

152+
// GrantTypeTokenExchangeCanSkipClientAuth indicates the stretegy to check if client authentication can be skipped.
153+
GrantTypeTokenExchangeCanSkipClientAuth CanSkipClientAuthenticationStrategy
154+
151155
// ClientAuthenticationStrategy indicates the Strategy to authenticate client requests
152156
ClientAuthenticationStrategy ClientAuthenticationStrategy
153157

@@ -299,6 +303,12 @@ func (c *Config) GetGrantTypeJWTBearerCanSkipClientAuth(ctx context.Context) boo
299303
return c.GrantTypeJWTBearerCanSkipClientAuth
300304
}
301305

306+
// GetGrantTypeTokenExchangeCanSkipClientAuth returns the GrantTypeTokenExchangeCanSkipClientAuth field.
307+
// Defaults to nil, in which case TokenExchange follows the default behavior.
308+
func (c *Config) GetGrantTypeTokenExchangeCanSkipClientAuth(ctx context.Context) CanSkipClientAuthenticationStrategy {
309+
return c.GrantTypeTokenExchangeCanSkipClientAuth
310+
}
311+
302312
// GetEnforcePKCE If set to true, public clients must use PKCE.
303313
func (c *Config) GetEnforcePKCE(ctx context.Context) bool {
304314
return c.EnforcePKCE

handler/rfc8693/handler.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"time"
1111

1212
"github.com/ory/fosite"
13-
"github.com/ory/fosite/compose"
1413
"github.com/ory/fosite/handler/oauth2"
1514
"github.com/ory/fosite/token/jwt"
1615
"github.com/ory/x/errorsx"
@@ -22,18 +21,17 @@ const (
2221
tokenTypeAT = "urn:ietf:params:oauth:token-type:access_token"
2322
)
2423

25-
func TokenExchangeGrantFactory(config *compose.CommonStrategy, storage, strategy interface{}) interface{} {
26-
return nil
27-
}
28-
2924
type Handler struct {
30-
Storage RFC8693Storage
31-
Strategy ClientAuthenticationStrategy
32-
ScopeStrategy fosite.ScopeStrategy
33-
AudienceMatchingStrategy fosite.AudienceMatchingStrategy
34-
RefreshTokenStrategy oauth2.RefreshTokenStrategy
35-
RefreshTokenStorage oauth2.RefreshTokenStorage
36-
fosite.RefreshTokenScopesProvider
25+
Storage RFC8693Storage
26+
RefreshTokenStorage oauth2.RefreshTokenStorage
27+
RefreshTokenStrategy oauth2.RefreshTokenStrategy
28+
29+
Config interface {
30+
fosite.GrantTypeTokenExchangeCanSkipClientAuthProvider
31+
fosite.ScopeStrategyProvider
32+
fosite.AudienceStrategyProvider
33+
fosite.RefreshTokenScopesProvider
34+
}
3735

3836
*oauth2.HandleHelper
3937
}
@@ -136,14 +134,14 @@ func (c *Handler) HandleTokenEndpointRequest(ctx context.Context, requester fosi
136134

137135
// Check and grant scope.
138136
for _, scope := range requester.GetRequestedScopes() {
139-
if !c.ScopeStrategy(client.GetScopes(), scope) {
137+
if !c.Config.GetScopeStrategy(ctx)(client.GetScopes(), scope) {
140138
return errorsx.WithStack(fosite.ErrInvalidScope.WithHintf("The OAuth 2.0 Client is not allowed to request scope '%s'.", scope))
141139
}
142140
requester.GrantScope(scope)
143141
}
144142

145143
// Check and grant audience.
146-
if err := c.AudienceMatchingStrategy(client.GetAudience(), requester.GetRequestedAudience()); err != nil {
144+
if err := c.Config.GetAudienceStrategy(ctx)(client.GetAudience(), requester.GetRequestedAudience()); err != nil {
147145
return errorsx.WithStack(fosite.ErrInvalidRequest.WithHintf("audience not match: %v", err))
148146
}
149147
for _, audience := range requester.GetRequestedAudience() {
@@ -164,7 +162,7 @@ func (c *Handler) HandleTokenEndpointRequest(ctx context.Context, requester fosi
164162
requester.SetSession(&fosite.DefaultSession{
165163
Subject: subject,
166164
})
167-
requester.GetSession().SetExpiresAt(fosite.AccessToken, time.Now().UTC().Add(c.Config.GetAccessTokenLifespan(ctx)))
165+
requester.GetSession().SetExpiresAt(fosite.AccessToken, time.Now().UTC().Add(c.HandleHelper.Config.GetAccessTokenLifespan(ctx)))
168166
return nil
169167
case tokenTypeAT:
170168
or, err := c.verifyAccessTokenAsSubjectToken(ctx, client.GetID(), params)
@@ -189,14 +187,13 @@ func (c *Handler) PopulateTokenEndpointResponse(ctx context.Context, requester f
189187
return errorsx.WithStack(fosite.ErrUnauthorizedClient.WithHintf("The OAuth 2.0 Client is not allowed to use authorization grant '%s'.", fosite.GrantTypeTokenExchange))
190188
}
191189

192-
atLifespan := fosite.GetEffectiveLifespan(requester.GetClient(), fosite.GrantTypeTokenExchange, fosite.AccessToken, c.Config.GetAccessTokenLifespan(ctx))
190+
atLifespan := fosite.GetEffectiveLifespan(requester.GetClient(), fosite.GrantTypeTokenExchange, fosite.AccessToken, c.HandleHelper.Config.GetAccessTokenLifespan(ctx))
193191

194192
if err := c.IssueAccessToken(ctx, atLifespan, requester, responder); err != nil {
195193
return err
196194
}
197195

198196
if canIssueRefreshToken(ctx, c, requester) {
199-
fmt.Println(requester)
200197
refresh, refreshSignature, err := c.RefreshTokenStrategy.GenerateRefreshToken(ctx, requester)
201198
if err != nil {
202199
return errorsx.WithStack(fosite.ErrServerError.WithWrap(err).WithDebug(err.Error()))
@@ -211,7 +208,7 @@ func (c *Handler) PopulateTokenEndpointResponse(ctx context.Context, requester f
211208
}
212209

213210
func canIssueRefreshToken(ctx context.Context, c *Handler, requester fosite.Requester) bool {
214-
scope := c.GetRefreshTokenScopes(ctx)
211+
scope := c.Config.GetRefreshTokenScopes(ctx)
215212
// Require one of the refresh token scopes, if set.
216213
if len(scope) > 0 && !requester.GetGrantedScopes().HasOneOf(scope...) {
217214
return false
@@ -223,8 +220,12 @@ func canIssueRefreshToken(ctx context.Context, c *Handler, requester fosite.Requ
223220
return true
224221
}
225222

226-
func (c *Handler) CanSkipClientAuth(requester fosite.AccessRequester) bool {
227-
return c.Strategy.CanSkipClientAuth(requester)
223+
func (c *Handler) CanSkipClientAuth(ctx context.Context, requester fosite.AccessRequester) bool {
224+
if s := c.Config.GetGrantTypeTokenExchangeCanSkipClientAuth(ctx); s != nil {
225+
return s(ctx, requester)
226+
}
227+
228+
return false
228229
}
229230

230231
func (c *Handler) keyFunc(ctx context.Context) jwt.Keyfunc {

handler/rfc8693/handler_test.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ func TestTokenExchange_HandleTokenEndpointRequest(t *testing.T) {
3030

3131
h := Handler{
3232
Storage: teStore,
33+
Config: &fosite.Config{},
3334
HandleHelper: &fositeOAuth2.HandleHelper{
3435
AccessTokenStorage: atStore,
3536
AccessTokenStrategy: chgen,
3637
Config: &fosite.Config{
3738
AccessTokenLifespan: time.Hour,
3839
},
3940
},
40-
ScopeStrategy: fosite.HierarchicScopeStrategy,
41-
AudienceMatchingStrategy: fosite.DefaultAudienceMatchingStrategy,
42-
RefreshTokenStorage: rtStore,
41+
RefreshTokenStorage: rtStore,
4342
}
4443

4544
for _, c := range []struct {
@@ -286,13 +285,9 @@ func TestTokenExchange_PopulateTokenEndpointResponse(t *testing.T) {
286285
AccessTokenLifespan: time.Hour,
287286
},
288287
},
289-
ScopeStrategy: fosite.HierarchicScopeStrategy,
290-
AudienceMatchingStrategy: fosite.DefaultAudienceMatchingStrategy,
291-
RefreshTokenStrategy: rtStrategy,
292-
RefreshTokenStorage: rtStore,
293-
RefreshTokenScopesProvider: &fosite.Config{
294-
RefreshTokenScopes: []string{"offline", "offline_access"},
295-
},
288+
Config: &fosite.Config{},
289+
RefreshTokenStrategy: rtStrategy,
290+
RefreshTokenStorage: rtStore,
296291
}
297292
for _, c := range []struct {
298293
name string

handler/rfc8693/strategy.go

Lines changed: 0 additions & 19 deletions
This file was deleted.

internal/oauth2_token_exchange_strategy.go

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)