Skip to content

Commit

Permalink
add ClientAuthenticationStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
narg95 committed Feb 18, 2021
1 parent c1a6ce3 commit 93aaebd
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 13 deletions.
14 changes: 14 additions & 0 deletions client_authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ import (
jose "gopkg.in/square/go-jose.v2"
)

// ClientAuthenticationStrategy provides a method signature for authenticating a client request
type ClientAuthenticationStrategy func(context.Context, *http.Request, url.Values) (Client, error)

const clientAssertionJWTBearerType = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"

func (f *Fosite) findClientPublicJWK(oidcClient OpenIDConnectClient, t *jwt.Token, expectsRSAKey bool) (interface{}, error) {
Expand Down Expand Up @@ -66,7 +69,18 @@ func (f *Fosite) findClientPublicJWK(oidcClient OpenIDConnectClient, t *jwt.Toke
return nil, errorsx.WithStack(ErrInvalidClient.WithHint("The OAuth 2.0 Client has no JSON Web Keys set registered, but they are needed to complete the request."))
}

// AuthenticateClient authenticates client requests using the configured strategy
// `Fosite.ClientAuthenticationStrategy`, if nil it uses `Fosite.DefaultClientAuthenticationStrategy`
func (f *Fosite) AuthenticateClient(ctx context.Context, r *http.Request, form url.Values) (Client, error) {
if f.ClientAuthenticationStrategy == nil {
return f.DefaultClientAuthenticationStrategy(ctx, r, form)
}
return f.ClientAuthenticationStrategy(ctx, r, form)
}

// DefaultClientAuthenticationStrategy provides the fosite's default client authentication strategy,
// HTTP Basic Authentication and JWT Bearer
func (f *Fosite) DefaultClientAuthenticationStrategy(ctx context.Context, r *http.Request, form url.Values) (Client, error) {
if assertionType := form.Get("client_assertion_type"); assertionType == clientAssertionJWTBearerType {
assertion := form.Get("client_assertion")
if len(assertion) == 0 {
Expand Down
27 changes: 14 additions & 13 deletions compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,20 @@ func Compose(config *Config, storage interface{}, strategy interface{}, hasher f
}

f := &fosite.Fosite{
Store: storage.(fosite.Storage),
AuthorizeEndpointHandlers: fosite.AuthorizeEndpointHandlers{},
TokenEndpointHandlers: fosite.TokenEndpointHandlers{},
TokenIntrospectionHandlers: fosite.TokenIntrospectionHandlers{},
RevocationHandlers: fosite.RevocationHandlers{},
Hasher: hasher,
ScopeStrategy: config.GetScopeStrategy(),
AudienceMatchingStrategy: config.GetAudienceStrategy(),
SendDebugMessagesToClients: config.SendDebugMessagesToClients,
TokenURL: config.TokenURL,
JWKSFetcherStrategy: config.GetJWKSFetcherStrategy(),
MinParameterEntropy: config.GetMinParameterEntropy(),
UseLegacyErrorFormat: config.UseLegacyErrorFormat,
Store: storage.(fosite.Storage),
AuthorizeEndpointHandlers: fosite.AuthorizeEndpointHandlers{},
TokenEndpointHandlers: fosite.TokenEndpointHandlers{},
TokenIntrospectionHandlers: fosite.TokenIntrospectionHandlers{},
RevocationHandlers: fosite.RevocationHandlers{},
Hasher: hasher,
ScopeStrategy: config.GetScopeStrategy(),
AudienceMatchingStrategy: config.GetAudienceStrategy(),
SendDebugMessagesToClients: config.SendDebugMessagesToClients,
TokenURL: config.TokenURL,
JWKSFetcherStrategy: config.GetJWKSFetcherStrategy(),
MinParameterEntropy: config.GetMinParameterEntropy(),
UseLegacyErrorFormat: config.UseLegacyErrorFormat,
ClientAuthenticationStrategy: config.GetClientAuthenticationStrategy(),
}

for _, factory := range factories {
Expand Down
11 changes: 11 additions & 0 deletions compose/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ type Config struct {

// GrantTypeJWTBearerMaxDuration sets the maximum time after JWT issued date, during which the JWT is considered valid.
GrantTypeJWTBearerMaxDuration time.Duration

// ClientAuthenticationStrategy indicates the Strategy to authenticate client requests
ClientAuthenticationStrategy fosite.ClientAuthenticationStrategy
}

// GetScopeStrategy returns the scope strategy to be used. Defaults to glob scope strategy.
Expand Down Expand Up @@ -221,3 +224,11 @@ func (c *Config) GetJWTMaxDuration() time.Duration {
}
return c.GrantTypeJWTBearerMaxDuration
}

// GetClientAuthenticationStrategy returns the configured client authentication strategy.
// Defaults to nil.
// Note that on a nil strategy `fosite.Fosite` fallbacks to its default client authentication strategy
// `fosite.Fosite.DefaultClientAuthenticationStrategy`
func (c *Config) GetClientAuthenticationStrategy() fosite.ClientAuthenticationStrategy {
return c.ClientAuthenticationStrategy
}
3 changes: 3 additions & 0 deletions fosite.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ type Fosite struct {

// FormPostHTMLTemplate sets html template for rendering the authorization response when the request has response_mode=form_post. Defaults to fosite.FormPostDefaultTemplate
FormPostHTMLTemplate *template.Template

// ClientAuthenticationStrategy provides an extension point to plug a strategy to authenticate clients
ClientAuthenticationStrategy ClientAuthenticationStrategy
}

const MinParameterEntropy = 8
Expand Down

0 comments on commit 93aaebd

Please sign in to comment.