Merge pull request #2433 from flant/implicit_flow_discovery

fix: Implicit Grant discovery
This commit is contained in:
Márk Sági-Kazár 2022-04-06 12:42:43 +02:00 committed by GitHub
commit 50dc2f5518
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 2 deletions

View File

@ -128,6 +128,7 @@ const (
const ( const (
grantTypeAuthorizationCode = "authorization_code" grantTypeAuthorizationCode = "authorization_code"
grantTypeRefreshToken = "refresh_token" grantTypeRefreshToken = "refresh_token"
grantTypeImplicit = "implicit"
grantTypePassword = "password" grantTypePassword = "password"
grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code" grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code"
) )

View File

@ -213,20 +213,27 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
c.SupportedResponseTypes = []string{responseTypeCode} c.SupportedResponseTypes = []string{responseTypeCode}
} }
supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default
supportedRes := make(map[string]bool) supportedRes := make(map[string]bool)
for _, respType := range c.SupportedResponseTypes { for _, respType := range c.SupportedResponseTypes {
switch respType { switch respType {
case responseTypeCode, responseTypeIDToken, responseTypeToken: case responseTypeCode, responseTypeIDToken:
// continue
case responseTypeToken:
// response_type=token is an implicit flow, let's add it to the discovery info
// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1
supportedGrant = append(supportedGrant, grantTypeImplicit)
default: default:
return nil, fmt.Errorf("unsupported response_type %q", respType) return nil, fmt.Errorf("unsupported response_type %q", respType)
} }
supportedRes[respType] = true supportedRes[respType] = true
} }
supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default
if c.PasswordConnector != "" { if c.PasswordConnector != "" {
supportedGrant = append(supportedGrant, grantTypePassword) supportedGrant = append(supportedGrant, grantTypePassword)
} }
sort.Strings(supportedGrant) sort.Strings(supportedGrant)
webFS := web.FS() webFS := web.FS()

View File

@ -1735,3 +1735,42 @@ func TestOAuth2DeviceFlow(t *testing.T) {
} }
} }
} }
func TestServerSupportedGrants(t *testing.T) {
tests := []struct {
name string
config func(c *Config)
resGrants []string
}{
{
name: "Simple",
config: func(c *Config) {},
resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode},
},
{
name: "With password connector",
config: func(c *Config) { c.PasswordConnector = "local" },
resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode},
},
{
name: "With token response",
config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) },
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode},
},
{
name: "All",
config: func(c *Config) {
c.PasswordConnector = "local"
c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken)
},
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
_, srv := newTestServer(context.TODO(), t, tc.config)
require.Equal(t, srv.supportedGrantTypes, tc.resGrants)
})
}
}