mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 20:47:22 +00:00
fix: refresh token activation (#1795)
* fix: oidc grant type check * docs: add offline_access scope * docs: update refresh token status in supported grant types * fix: update oidc pkg
This commit is contained in:
parent
1f41cc5ca8
commit
f8ab1f5b7b
@ -139,6 +139,46 @@ curl --request POST \
|
|||||||
--data client_assertion=eyJhbGciOiJSUzI1Ni...
|
--data client_assertion=eyJhbGciOiJSUzI1Ni...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Refresh Token Grant
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Required request Parameters
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
| ------------- | ----------------------------------------------------------------------------------- |
|
||||||
|
| grant_type | Must be `refresh_token` |
|
||||||
|
| refresh_token | The refresh_token previously issued in the last auth code or refresh token request. |
|
||||||
|
| scope | [Scopes](Scopes) you would like to request from ZITADEL for the new access_token. Must be a subset of the scope originally requested by the corresponding auth request. When omitted, the scopes requested by the original auth request will be reused. Scopes are space delimited, e.g. `openid email profile` |
|
||||||
|
|
||||||
|
Depending on your authorization method you will have to provide additional parameters or headers:
|
||||||
|
|
||||||
|
When using `client_secret_basic`
|
||||||
|
|
||||||
|
Send your `client_id` and `client_secret` as Basic Auth Header. Check [Client Secret Basic Auth Method](authn-methods#client-secret-basic) on how to build it correctly.
|
||||||
|
|
||||||
|
When using `client_secret_post`
|
||||||
|
|
||||||
|
Send your `client_id` and `client_secret` as parameters in the body:
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
| ------------- | -------------------------------- |
|
||||||
|
| client_id | client_id of the application |
|
||||||
|
| client_secret | client_secret of the application |
|
||||||
|
|
||||||
|
When using `none` (PKCE)
|
||||||
|
|
||||||
|
Send your `client_id` as parameter in the body. No authentication is required.
|
||||||
|
|
||||||
|
When using `private_key_jwt`
|
||||||
|
|
||||||
|
Send a client assertion as JWT for us to validate the signature against the registered public key.
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
| --------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| client_assertion | JWT built and signed according to [Using JWTs for Client Authentication](authn-methods#jwt-with-private-key) |
|
||||||
|
| client_assertion_type | Must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` |
|
||||||
|
|
||||||
## introspection_endpoint
|
## introspection_endpoint
|
||||||
|
|
||||||
[https://api.zitadel.ch/oauth/v2/introspect](https://api.zitadel.ch/oauth/v2/introspect)
|
[https://api.zitadel.ch/oauth/v2/introspect](https://api.zitadel.ch/oauth/v2/introspect)
|
||||||
|
@ -12,7 +12,7 @@ For a list of supported or unsupported `Grant Types` please have a look at the t
|
|||||||
| Device Authorization | under consideration |
|
| Device Authorization | under consideration |
|
||||||
| Implicit | yes |
|
| Implicit | yes |
|
||||||
| JSON Web Token (JWT) Profile | yes |
|
| JSON Web Token (JWT) Profile | yes |
|
||||||
| Refresh Token | work in progress |
|
| Refresh Token | yes |
|
||||||
| Resource Owner Password Credentials | no |
|
| Resource Owner Password Credentials | no |
|
||||||
| Security Assertion Markup Language (SAML) 2.0 Profile | no |
|
| Security Assertion Markup Language (SAML) 2.0 Profile | no |
|
||||||
| Token Exchange | work in progress |
|
| Token Exchange | work in progress |
|
||||||
|
@ -6,12 +6,13 @@ ZITADEL supports the usage of scopes as way of requesting information from the I
|
|||||||
|
|
||||||
## Standard Scopes
|
## Standard Scopes
|
||||||
|
|
||||||
| Scopes | Example | Description |
|
| Scopes | Example | Description |
|
||||||
|:--------|:----------|------------------------------------------------------|
|
|:---------------|:-----------------|--------------------------------------------------------------------------------|
|
||||||
| openid | `openid` | When using openid connect this is a mandatory scope |
|
| openid | `openid` | When using openid connect this is a mandatory scope |
|
||||||
| profile | `profile` | Optional scope to request the profile of the subject |
|
| profile | `profile` | Optional scope to request the profile of the subject |
|
||||||
| email | `email` | Optional scope to request the email of the subject |
|
| email | `email` | Optional scope to request the email of the subject |
|
||||||
| address | `address` | Optional scope to request the address of the subject |
|
| address | `address` | Optional scope to request the address of the subject |
|
||||||
|
| offline_access | `offline_access` | Optional scope to request a refresh_token (only possible when using code flow) |
|
||||||
|
|
||||||
## Custom Scopes
|
## Custom Scopes
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -16,7 +16,7 @@ require (
|
|||||||
github.com/allegro/bigcache v1.2.1
|
github.com/allegro/bigcache v1.2.1
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
|
||||||
github.com/caos/logging v0.0.2
|
github.com/caos/logging v0.0.2
|
||||||
github.com/caos/oidc v0.15.0
|
github.com/caos/oidc v0.15.1
|
||||||
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980
|
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980
|
||||||
github.com/cockroachdb/cockroach-go/v2 v2.1.0
|
github.com/cockroachdb/cockroach-go/v2 v2.1.0
|
||||||
github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43
|
github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43
|
||||||
|
4
go.sum
4
go.sum
@ -137,8 +137,8 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBW
|
|||||||
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
|
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
|
||||||
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
|
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
|
||||||
github.com/caos/oidc v0.14.4/go.mod h1:H5Y2zw3YIrWqQOoy0wcmZva2a66bumDyU2iOhXiM9uA=
|
github.com/caos/oidc v0.14.4/go.mod h1:H5Y2zw3YIrWqQOoy0wcmZva2a66bumDyU2iOhXiM9uA=
|
||||||
github.com/caos/oidc v0.15.0 h1:lSykVX6yfUbWpJPAZ9/ZCuowo95h7AgfgPaC15lzf4Y=
|
github.com/caos/oidc v0.15.1 h1:dzMelbk9uYkNTfEy9+273o0fwZTgMSj9eqvS7UtKUpo=
|
||||||
github.com/caos/oidc v0.15.0/go.mod h1:JiK5RXSOgag66wiSOMEkS+yS4R46Baz6dGwfr60VfvI=
|
github.com/caos/oidc v0.15.1/go.mod h1:JiK5RXSOgag66wiSOMEkS+yS4R46Baz6dGwfr60VfvI=
|
||||||
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980 h1:Fz0aYUwGMA2tsu5w7SryqFGjqGClJVHbyhBMT5SXtPU=
|
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980 h1:Fz0aYUwGMA2tsu5w7SryqFGjqGClJVHbyhBMT5SXtPU=
|
||||||
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980/go.mod h1:2I8oiZb5SMRm/qTLvwpSmdV0M6ex8J/UKyxUGfKaqJo=
|
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980/go.mod h1:2I8oiZb5SMRm/qTLvwpSmdV0M6ex8J/UKyxUGfKaqJo=
|
||||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
|
@ -61,6 +61,10 @@ func (c *Client) ResponseTypes() []oidc.ResponseType {
|
|||||||
return responseTypesToOIDC(c.OIDCResponseTypes)
|
return responseTypesToOIDC(c.OIDCResponseTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) GrantTypes() []oidc.GrantType {
|
||||||
|
return grantTypesToOIDC(c.OIDCGrantTypes)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) DevMode() bool {
|
func (c *Client) DevMode() bool {
|
||||||
return c.ApplicationView.DevMode
|
return c.ApplicationView.DevMode
|
||||||
}
|
}
|
||||||
@ -165,6 +169,27 @@ func responseTypeToOIDC(responseType model.OIDCResponseType) oidc.ResponseType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func grantTypesToOIDC(grantTypes []model.OIDCGrantType) []oidc.GrantType {
|
||||||
|
oidcTypes := make([]oidc.GrantType, len(grantTypes))
|
||||||
|
for i, t := range grantTypes {
|
||||||
|
oidcTypes[i] = grantTypeToOIDC(t)
|
||||||
|
}
|
||||||
|
return oidcTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func grantTypeToOIDC(grantType model.OIDCGrantType) oidc.GrantType {
|
||||||
|
switch grantType {
|
||||||
|
case model.OIDCGrantTypeAuthorizationCode:
|
||||||
|
return oidc.GrantTypeCode
|
||||||
|
case model.OIDCGrantTypeImplicit:
|
||||||
|
return oidc.GrantTypeImplicit
|
||||||
|
case model.OIDCGrantTypeRefreshToken:
|
||||||
|
return oidc.GrantTypeRefreshToken
|
||||||
|
default:
|
||||||
|
return oidc.GrantTypeCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func removeScopeWithPrefix(scopes []string, scopePrefix ...string) []string {
|
func removeScopeWithPrefix(scopes []string, scopePrefix ...string) []string {
|
||||||
newScopeList := make([]string, 0)
|
newScopeList := make([]string, 0)
|
||||||
for _, scope := range scopes {
|
for _, scope := range scopes {
|
||||||
|
@ -73,6 +73,7 @@ func NewProvider(ctx context.Context, config OPHandlerConfig, command *command.C
|
|||||||
}
|
}
|
||||||
copy(config.OPConfig.CryptoKey[:], cryptoKey)
|
copy(config.OPConfig.CryptoKey[:], cryptoKey)
|
||||||
config.OPConfig.CodeMethodS256 = true
|
config.OPConfig.CodeMethodS256 = true
|
||||||
|
config.OPConfig.GrantTypeRefreshToken = true
|
||||||
metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount}
|
metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount}
|
||||||
provider, err := op.NewOpenIDProvider(
|
provider, err := op.NewOpenIDProvider(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -190,6 +190,7 @@ func GetOIDCV1Compliance(appType OIDCApplicationType, grantTypes []OIDCGrantType
|
|||||||
compliance.NoneCompliant = true
|
compliance.NoneCompliant = true
|
||||||
compliance.Problems = append([]string{"Application.OIDC.V1.NoRedirectUris"}, compliance.Problems...)
|
compliance.Problems = append([]string{"Application.OIDC.V1.NoRedirectUris"}, compliance.Problems...)
|
||||||
}
|
}
|
||||||
|
CheckGrantTypes(compliance, grantTypes)
|
||||||
if containsOIDCGrantType(grantTypes, OIDCGrantTypeImplicit) && containsOIDCGrantType(grantTypes, OIDCGrantTypeAuthorizationCode) {
|
if containsOIDCGrantType(grantTypes, OIDCGrantTypeImplicit) && containsOIDCGrantType(grantTypes, OIDCGrantTypeAuthorizationCode) {
|
||||||
CheckRedirectUrisImplicitAndCode(compliance, appType, redirectUris)
|
CheckRedirectUrisImplicitAndCode(compliance, appType, redirectUris)
|
||||||
} else {
|
} else {
|
||||||
@ -213,6 +214,13 @@ func GetOIDCV1Compliance(appType OIDCApplicationType, grantTypes []OIDCGrantType
|
|||||||
return compliance
|
return compliance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckGrantTypes(compliance *Compliance, grantTypes []OIDCGrantType) {
|
||||||
|
if containsOIDCGrantType(grantTypes, OIDCGrantTypeRefreshToken) && !containsOIDCGrantType(grantTypes, OIDCGrantTypeAuthorizationCode) {
|
||||||
|
compliance.NoneCompliant = true
|
||||||
|
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.GrantType.Refresh.NoAuthCode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetOIDCV1NativeApplicationCompliance(compliance *Compliance, authMethod OIDCAuthMethodType) {
|
func GetOIDCV1NativeApplicationCompliance(compliance *Compliance, authMethod OIDCAuthMethodType) {
|
||||||
if authMethod != OIDCAuthMethodTypeNone {
|
if authMethod != OIDCAuthMethodTypeNone {
|
||||||
compliance.NoneCompliant = true
|
compliance.NoneCompliant = true
|
||||||
@ -238,7 +246,7 @@ func CheckRedirectUrisCode(compliance *Compliance, appType OIDCApplicationType,
|
|||||||
}
|
}
|
||||||
if appType == OIDCApplicationTypeNative && !onlyLocalhostIsHttp(redirectUris) {
|
if appType == OIDCApplicationTypeNative && !onlyLocalhostIsHttp(redirectUris) {
|
||||||
compliance.NoneCompliant = true
|
compliance.NoneCompliant = true
|
||||||
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Code.RedirectUris.NativeShouldBeHttpLocalhost")
|
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Native.RedirectUris.MustBeHttpLocalhost")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if containsCustom(redirectUris) && appType != OIDCApplicationTypeNative {
|
if containsCustom(redirectUris) && appType != OIDCApplicationTypeNative {
|
||||||
@ -259,7 +267,7 @@ func CheckRedirectUrisImplicit(compliance *Compliance, appType OIDCApplicationTy
|
|||||||
if appType == OIDCApplicationTypeNative {
|
if appType == OIDCApplicationTypeNative {
|
||||||
if !onlyLocalhostIsHttp(redirectUris) {
|
if !onlyLocalhostIsHttp(redirectUris) {
|
||||||
compliance.NoneCompliant = true
|
compliance.NoneCompliant = true
|
||||||
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.NativeShouldBeHttpLocalhost")
|
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Native.RedirectUris.MustBeHttpLocalhost")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -283,7 +291,7 @@ func CheckRedirectUrisImplicitAndCode(compliance *Compliance, appType OIDCApplic
|
|||||||
}
|
}
|
||||||
if !onlyLocalhostIsHttp(redirectUris) && appType == OIDCApplicationTypeNative {
|
if !onlyLocalhostIsHttp(redirectUris) && appType == OIDCApplicationTypeNative {
|
||||||
compliance.NoneCompliant = true
|
compliance.NoneCompliant = true
|
||||||
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.NativeShouldBeHttpLocalhost")
|
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Native.RedirectUris.MustBeHttpLocalhost")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !compliance.NoneCompliant {
|
if !compliance.NoneCompliant {
|
||||||
|
@ -695,11 +695,15 @@ Application:
|
|||||||
RedirectUris:
|
RedirectUris:
|
||||||
CustomNotAllowed: Grant Type Implicit erlaubt keine custom Redirect Uris.
|
CustomNotAllowed: Grant Type Implicit erlaubt keine custom Redirect Uris.
|
||||||
HttpNotAllowed: Grant Type Implicit erlaubt keine http Redirect Uris.
|
HttpNotAllowed: Grant Type Implicit erlaubt keine http Redirect Uris.
|
||||||
NativeShouldBeHttpLocalhost: Grant Type Implicit erlaubt beim Apptype Native http nur mit localhost (http://localhost)
|
|
||||||
HttpLocalhostOnlyForNative: Http://localhost Redirect Uri ist nur für Native Applikationen erlaubt.
|
HttpLocalhostOnlyForNative: Http://localhost Redirect Uri ist nur für Native Applikationen erlaubt.
|
||||||
Native:
|
Native:
|
||||||
AuthMethodType:
|
AuthMethodType:
|
||||||
NotNone: Bei Native Applikationen sollte der AuthMethodType none sein.
|
NotNone: Bei Native Applikationen sollte der AuthMethodType none sein.
|
||||||
|
RedirectUris:
|
||||||
|
MustBeHttpLocalhost: Die Weiterleitung muss mit einem eigenen Protokoll, http://127.0.0.1, http://[::1] oder http://localhost beginnen.
|
||||||
UserAgent:
|
UserAgent:
|
||||||
AuthMethodType:
|
AuthMethodType:
|
||||||
NotNone: Bei einem User Agent sollte der AuthMethodType none sein.
|
NotNone: Bei einem User Agent sollte der AuthMethodType none sein.
|
||||||
|
GrantType:
|
||||||
|
Refresh:
|
||||||
|
NoAuthCode: Refresh Token nur in Kombination mit Authorization Code erlaubt.
|
||||||
|
@ -696,11 +696,15 @@ Application:
|
|||||||
RedirectUris:
|
RedirectUris:
|
||||||
CustomNotAllowed: Grant type implicit doesn't allow custom redirect uris
|
CustomNotAllowed: Grant type implicit doesn't allow custom redirect uris
|
||||||
HttpNotAllowed: Grant tpye implicit doesn't allow http redirect uris
|
HttpNotAllowed: Grant tpye implicit doesn't allow http redirect uris
|
||||||
NativeShouldBeHttpLocalhost: Grant tpye implicit only allowed http://localhost for native apptype
|
|
||||||
HttpLocalhostOnlyForNative: Http://localhost redirect uri is only allowed for native applications.
|
HttpLocalhostOnlyForNative: Http://localhost redirect uri is only allowed for native applications.
|
||||||
Native:
|
Native:
|
||||||
AuthMethodType:
|
AuthMethodType:
|
||||||
NotNone: Native applications should have authmethodtype none.
|
NotNone: Native applications should have authmethodtype none.
|
||||||
|
RedirectUris:
|
||||||
|
MustBeHttpLocalhost: Redirect URIs must begin with your own protocol, http://127.0.0.1, http://[::1] or http://localhost.
|
||||||
UserAgent:
|
UserAgent:
|
||||||
AuthMethodType:
|
AuthMethodType:
|
||||||
NotNone: User agent app should have authmethodtype none.
|
NotNone: User agent app should have authmethodtype none.
|
||||||
|
GrantType:
|
||||||
|
Refresh:
|
||||||
|
NoAuthCode: Refresh Token only allowed in combination with Authorization Code.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user