dex/storage/etcd/types.go

315 lines
9.4 KiB
Go
Raw Normal View History

package etcd
import (
"time"
jose "gopkg.in/square/go-jose.v2"
"github.com/dexidp/dex/storage"
)
// AuthCode is a mirrored struct from storage with JSON struct tags
type AuthCode struct {
ID string `json:"ID"`
ClientID string `json:"clientID"`
RedirectURI string `json:"redirectURI"`
Nonce string `json:"nonce,omitempty"`
Scopes []string `json:"scopes,omitempty"`
2019-04-18 19:47:31 +05:30
ConnectorID string `json:"connectorID,omitempty"`
ConnectorData []byte `json:"connectorData,omitempty"`
Claims Claims `json:"claims,omitempty"`
Expiry time.Time `json:"expiry"`
PKCE implementation (#1784) * Basic implementation of PKCE Signed-off-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> * @mfmarche on 24 Feb: when code_verifier is set, don't check client_secret In PKCE flow, no client_secret is used, so the check for a valid client_secret would always fail. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * @deric on 16 Jun: return invalid_grant when wrong code_verifier Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enforce PKCE flow on /token when PKCE flow was started on /auth Also dissallow PKCE on /token, when PKCE flow was not started on /auth Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * fixed error messages when mixed PKCE/no PKCE flow. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * server_test.go: Added PKCE error cases on /token endpoint * Added test for invalid_grant, when wrong code_verifier is sent * Added test for mixed PKCE / no PKCE auth flows. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * cleanup: extracted method checkErrorResponse and type TestDefinition * fixed connector being overwritten Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * /token endpoint: skip client_secret verification only for grand type authorization_code with PKCE extension Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow "Authorization" header in CORS handlers * Adds "Authorization" to the default CORS headers{"Accept", "Accept-Language", "Content-Language", "Origin"} Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Add "code_challenge_methods_supported" to discovery endpoint discovery endpoint /dex/.well-known/openid-configuration now has the following entry: "code_challenge_methods_supported": [ "S256", "plain" ] Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Updated tests (mixed-up comments), added a PKCE test * @asoorm added test that checks if downgrade to "plain" on /token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * remove redefinition of providedCodeVerifier, fixed spelling (#6) Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Signed-off-by: Bernd Eckstein <HEllRZA@users.noreply.github.com> * Rename struct CodeChallenge to PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * PKCE: Check clientSecret when available In authorization_code flow with PKCE, allow empty client_secret on /auth and /token endpoints. But check the client_secret when it is given. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enable PKCE with public: true dex configuration public on staticClients now enables the following behavior in PKCE: - Public: false, PKCE will always check client_secret. This means PKCE in it's natural form is disabled. - Public: true, PKCE is enabled. It will only check client_secret if the client has sent one. But it allows the code flow if the client didn't sent one. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Redirect error on unsupported code_challenge_method - Check for unsupported code_challenge_method after redirect uri is validated, and use newErr() to return the error. - Add PKCE tests to oauth2_test.go Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Reverted go.mod and go.sum to the state of master Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Don't omit client secret check for PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow public clients (e.g. with PKCE) to have redirect URIs configured Signed-off-by: Martin Heide <martin.heide@faro.com> * Remove "Authorization" as Accepted Headers on CORS, small fixes Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Revert "Allow public clients (e.g. with PKCE) to have redirect URIs configured" This reverts commit b6e297b78537dc44cd3e1374f0b4d34bf89404ac. Signed-off-by: Martin Heide <martin.heide@faro.com> * PKCE on client_secret client error message * When connecting to the token endpoint with PKCE without client_secret, but the client is configured with a client_secret, generate a special error message. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Output info message when PKCE without client_secret used on confidential client * removes the special error message Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * General missing/invalid client_secret message on token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Co-authored-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> Co-authored-by: Martin Heide <martin.heide@faro.com> Co-authored-by: M. Heide <66078329+heidemn-faro@users.noreply.github.com>
2020-10-26 16:03:40 +05:30
CodeChallenge string `json:"code_challenge,omitempty"`
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
}
func toStorageAuthCode(a AuthCode) storage.AuthCode {
return storage.AuthCode{
ID: a.ID,
ClientID: a.ClientID,
RedirectURI: a.RedirectURI,
ConnectorID: a.ConnectorID,
ConnectorData: a.ConnectorData,
Nonce: a.Nonce,
Scopes: a.Scopes,
Claims: toStorageClaims(a.Claims),
Expiry: a.Expiry,
PKCE: storage.PKCE{
CodeChallenge: a.CodeChallenge,
CodeChallengeMethod: a.CodeChallengeMethod,
},
}
}
func fromStorageAuthCode(a storage.AuthCode) AuthCode {
return AuthCode{
PKCE implementation (#1784) * Basic implementation of PKCE Signed-off-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> * @mfmarche on 24 Feb: when code_verifier is set, don't check client_secret In PKCE flow, no client_secret is used, so the check for a valid client_secret would always fail. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * @deric on 16 Jun: return invalid_grant when wrong code_verifier Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enforce PKCE flow on /token when PKCE flow was started on /auth Also dissallow PKCE on /token, when PKCE flow was not started on /auth Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * fixed error messages when mixed PKCE/no PKCE flow. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * server_test.go: Added PKCE error cases on /token endpoint * Added test for invalid_grant, when wrong code_verifier is sent * Added test for mixed PKCE / no PKCE auth flows. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * cleanup: extracted method checkErrorResponse and type TestDefinition * fixed connector being overwritten Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * /token endpoint: skip client_secret verification only for grand type authorization_code with PKCE extension Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow "Authorization" header in CORS handlers * Adds "Authorization" to the default CORS headers{"Accept", "Accept-Language", "Content-Language", "Origin"} Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Add "code_challenge_methods_supported" to discovery endpoint discovery endpoint /dex/.well-known/openid-configuration now has the following entry: "code_challenge_methods_supported": [ "S256", "plain" ] Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Updated tests (mixed-up comments), added a PKCE test * @asoorm added test that checks if downgrade to "plain" on /token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * remove redefinition of providedCodeVerifier, fixed spelling (#6) Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Signed-off-by: Bernd Eckstein <HEllRZA@users.noreply.github.com> * Rename struct CodeChallenge to PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * PKCE: Check clientSecret when available In authorization_code flow with PKCE, allow empty client_secret on /auth and /token endpoints. But check the client_secret when it is given. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enable PKCE with public: true dex configuration public on staticClients now enables the following behavior in PKCE: - Public: false, PKCE will always check client_secret. This means PKCE in it's natural form is disabled. - Public: true, PKCE is enabled. It will only check client_secret if the client has sent one. But it allows the code flow if the client didn't sent one. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Redirect error on unsupported code_challenge_method - Check for unsupported code_challenge_method after redirect uri is validated, and use newErr() to return the error. - Add PKCE tests to oauth2_test.go Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Reverted go.mod and go.sum to the state of master Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Don't omit client secret check for PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow public clients (e.g. with PKCE) to have redirect URIs configured Signed-off-by: Martin Heide <martin.heide@faro.com> * Remove "Authorization" as Accepted Headers on CORS, small fixes Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Revert "Allow public clients (e.g. with PKCE) to have redirect URIs configured" This reverts commit b6e297b78537dc44cd3e1374f0b4d34bf89404ac. Signed-off-by: Martin Heide <martin.heide@faro.com> * PKCE on client_secret client error message * When connecting to the token endpoint with PKCE without client_secret, but the client is configured with a client_secret, generate a special error message. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Output info message when PKCE without client_secret used on confidential client * removes the special error message Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * General missing/invalid client_secret message on token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Co-authored-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> Co-authored-by: Martin Heide <martin.heide@faro.com> Co-authored-by: M. Heide <66078329+heidemn-faro@users.noreply.github.com>
2020-10-26 16:03:40 +05:30
ID: a.ID,
ClientID: a.ClientID,
RedirectURI: a.RedirectURI,
ConnectorID: a.ConnectorID,
ConnectorData: a.ConnectorData,
Nonce: a.Nonce,
Scopes: a.Scopes,
Claims: fromStorageClaims(a.Claims),
Expiry: a.Expiry,
CodeChallenge: a.PKCE.CodeChallenge,
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
}
}
// AuthRequest is a mirrored struct from storage with JSON struct tags
type AuthRequest struct {
ID string `json:"id"`
ClientID string `json:"client_id"`
ResponseTypes []string `json:"response_types"`
Scopes []string `json:"scopes"`
RedirectURI string `json:"redirect_uri"`
Nonce string `json:"nonce"`
State string `json:"state"`
ForceApprovalPrompt bool `json:"force_approval_prompt"`
Expiry time.Time `json:"expiry"`
LoggedIn bool `json:"logged_in"`
Claims Claims `json:"claims"`
ConnectorID string `json:"connector_id"`
ConnectorData []byte `json:"connector_data"`
PKCE implementation (#1784) * Basic implementation of PKCE Signed-off-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> * @mfmarche on 24 Feb: when code_verifier is set, don't check client_secret In PKCE flow, no client_secret is used, so the check for a valid client_secret would always fail. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * @deric on 16 Jun: return invalid_grant when wrong code_verifier Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enforce PKCE flow on /token when PKCE flow was started on /auth Also dissallow PKCE on /token, when PKCE flow was not started on /auth Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * fixed error messages when mixed PKCE/no PKCE flow. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * server_test.go: Added PKCE error cases on /token endpoint * Added test for invalid_grant, when wrong code_verifier is sent * Added test for mixed PKCE / no PKCE auth flows. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * cleanup: extracted method checkErrorResponse and type TestDefinition * fixed connector being overwritten Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * /token endpoint: skip client_secret verification only for grand type authorization_code with PKCE extension Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow "Authorization" header in CORS handlers * Adds "Authorization" to the default CORS headers{"Accept", "Accept-Language", "Content-Language", "Origin"} Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Add "code_challenge_methods_supported" to discovery endpoint discovery endpoint /dex/.well-known/openid-configuration now has the following entry: "code_challenge_methods_supported": [ "S256", "plain" ] Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Updated tests (mixed-up comments), added a PKCE test * @asoorm added test that checks if downgrade to "plain" on /token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * remove redefinition of providedCodeVerifier, fixed spelling (#6) Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Signed-off-by: Bernd Eckstein <HEllRZA@users.noreply.github.com> * Rename struct CodeChallenge to PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * PKCE: Check clientSecret when available In authorization_code flow with PKCE, allow empty client_secret on /auth and /token endpoints. But check the client_secret when it is given. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enable PKCE with public: true dex configuration public on staticClients now enables the following behavior in PKCE: - Public: false, PKCE will always check client_secret. This means PKCE in it's natural form is disabled. - Public: true, PKCE is enabled. It will only check client_secret if the client has sent one. But it allows the code flow if the client didn't sent one. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Redirect error on unsupported code_challenge_method - Check for unsupported code_challenge_method after redirect uri is validated, and use newErr() to return the error. - Add PKCE tests to oauth2_test.go Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Reverted go.mod and go.sum to the state of master Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Don't omit client secret check for PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow public clients (e.g. with PKCE) to have redirect URIs configured Signed-off-by: Martin Heide <martin.heide@faro.com> * Remove "Authorization" as Accepted Headers on CORS, small fixes Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Revert "Allow public clients (e.g. with PKCE) to have redirect URIs configured" This reverts commit b6e297b78537dc44cd3e1374f0b4d34bf89404ac. Signed-off-by: Martin Heide <martin.heide@faro.com> * PKCE on client_secret client error message * When connecting to the token endpoint with PKCE without client_secret, but the client is configured with a client_secret, generate a special error message. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Output info message when PKCE without client_secret used on confidential client * removes the special error message Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * General missing/invalid client_secret message on token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Co-authored-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> Co-authored-by: Martin Heide <martin.heide@faro.com> Co-authored-by: M. Heide <66078329+heidemn-faro@users.noreply.github.com>
2020-10-26 16:03:40 +05:30
CodeChallenge string `json:"code_challenge,omitempty"`
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
}
func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
return AuthRequest{
ID: a.ID,
ClientID: a.ClientID,
ResponseTypes: a.ResponseTypes,
Scopes: a.Scopes,
RedirectURI: a.RedirectURI,
Nonce: a.Nonce,
State: a.State,
ForceApprovalPrompt: a.ForceApprovalPrompt,
Expiry: a.Expiry,
LoggedIn: a.LoggedIn,
Claims: fromStorageClaims(a.Claims),
ConnectorID: a.ConnectorID,
2019-04-18 19:47:31 +05:30
ConnectorData: a.ConnectorData,
PKCE implementation (#1784) * Basic implementation of PKCE Signed-off-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> * @mfmarche on 24 Feb: when code_verifier is set, don't check client_secret In PKCE flow, no client_secret is used, so the check for a valid client_secret would always fail. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * @deric on 16 Jun: return invalid_grant when wrong code_verifier Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enforce PKCE flow on /token when PKCE flow was started on /auth Also dissallow PKCE on /token, when PKCE flow was not started on /auth Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * fixed error messages when mixed PKCE/no PKCE flow. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * server_test.go: Added PKCE error cases on /token endpoint * Added test for invalid_grant, when wrong code_verifier is sent * Added test for mixed PKCE / no PKCE auth flows. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * cleanup: extracted method checkErrorResponse and type TestDefinition * fixed connector being overwritten Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * /token endpoint: skip client_secret verification only for grand type authorization_code with PKCE extension Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow "Authorization" header in CORS handlers * Adds "Authorization" to the default CORS headers{"Accept", "Accept-Language", "Content-Language", "Origin"} Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Add "code_challenge_methods_supported" to discovery endpoint discovery endpoint /dex/.well-known/openid-configuration now has the following entry: "code_challenge_methods_supported": [ "S256", "plain" ] Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Updated tests (mixed-up comments), added a PKCE test * @asoorm added test that checks if downgrade to "plain" on /token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * remove redefinition of providedCodeVerifier, fixed spelling (#6) Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Signed-off-by: Bernd Eckstein <HEllRZA@users.noreply.github.com> * Rename struct CodeChallenge to PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * PKCE: Check clientSecret when available In authorization_code flow with PKCE, allow empty client_secret on /auth and /token endpoints. But check the client_secret when it is given. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enable PKCE with public: true dex configuration public on staticClients now enables the following behavior in PKCE: - Public: false, PKCE will always check client_secret. This means PKCE in it's natural form is disabled. - Public: true, PKCE is enabled. It will only check client_secret if the client has sent one. But it allows the code flow if the client didn't sent one. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Redirect error on unsupported code_challenge_method - Check for unsupported code_challenge_method after redirect uri is validated, and use newErr() to return the error. - Add PKCE tests to oauth2_test.go Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Reverted go.mod and go.sum to the state of master Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Don't omit client secret check for PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow public clients (e.g. with PKCE) to have redirect URIs configured Signed-off-by: Martin Heide <martin.heide@faro.com> * Remove "Authorization" as Accepted Headers on CORS, small fixes Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Revert "Allow public clients (e.g. with PKCE) to have redirect URIs configured" This reverts commit b6e297b78537dc44cd3e1374f0b4d34bf89404ac. Signed-off-by: Martin Heide <martin.heide@faro.com> * PKCE on client_secret client error message * When connecting to the token endpoint with PKCE without client_secret, but the client is configured with a client_secret, generate a special error message. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Output info message when PKCE without client_secret used on confidential client * removes the special error message Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * General missing/invalid client_secret message on token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Co-authored-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> Co-authored-by: Martin Heide <martin.heide@faro.com> Co-authored-by: M. Heide <66078329+heidemn-faro@users.noreply.github.com>
2020-10-26 16:03:40 +05:30
CodeChallenge: a.PKCE.CodeChallenge,
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
}
}
func toStorageAuthRequest(a AuthRequest) storage.AuthRequest {
return storage.AuthRequest{
ID: a.ID,
ClientID: a.ClientID,
ResponseTypes: a.ResponseTypes,
Scopes: a.Scopes,
RedirectURI: a.RedirectURI,
Nonce: a.Nonce,
State: a.State,
ForceApprovalPrompt: a.ForceApprovalPrompt,
LoggedIn: a.LoggedIn,
ConnectorID: a.ConnectorID,
2019-04-18 19:47:31 +05:30
ConnectorData: a.ConnectorData,
Expiry: a.Expiry,
Claims: toStorageClaims(a.Claims),
PKCE implementation (#1784) * Basic implementation of PKCE Signed-off-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> * @mfmarche on 24 Feb: when code_verifier is set, don't check client_secret In PKCE flow, no client_secret is used, so the check for a valid client_secret would always fail. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * @deric on 16 Jun: return invalid_grant when wrong code_verifier Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enforce PKCE flow on /token when PKCE flow was started on /auth Also dissallow PKCE on /token, when PKCE flow was not started on /auth Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * fixed error messages when mixed PKCE/no PKCE flow. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * server_test.go: Added PKCE error cases on /token endpoint * Added test for invalid_grant, when wrong code_verifier is sent * Added test for mixed PKCE / no PKCE auth flows. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * cleanup: extracted method checkErrorResponse and type TestDefinition * fixed connector being overwritten Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * /token endpoint: skip client_secret verification only for grand type authorization_code with PKCE extension Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow "Authorization" header in CORS handlers * Adds "Authorization" to the default CORS headers{"Accept", "Accept-Language", "Content-Language", "Origin"} Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Add "code_challenge_methods_supported" to discovery endpoint discovery endpoint /dex/.well-known/openid-configuration now has the following entry: "code_challenge_methods_supported": [ "S256", "plain" ] Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Updated tests (mixed-up comments), added a PKCE test * @asoorm added test that checks if downgrade to "plain" on /token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * remove redefinition of providedCodeVerifier, fixed spelling (#6) Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Signed-off-by: Bernd Eckstein <HEllRZA@users.noreply.github.com> * Rename struct CodeChallenge to PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * PKCE: Check clientSecret when available In authorization_code flow with PKCE, allow empty client_secret on /auth and /token endpoints. But check the client_secret when it is given. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Enable PKCE with public: true dex configuration public on staticClients now enables the following behavior in PKCE: - Public: false, PKCE will always check client_secret. This means PKCE in it's natural form is disabled. - Public: true, PKCE is enabled. It will only check client_secret if the client has sent one. But it allows the code flow if the client didn't sent one. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Redirect error on unsupported code_challenge_method - Check for unsupported code_challenge_method after redirect uri is validated, and use newErr() to return the error. - Add PKCE tests to oauth2_test.go Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Reverted go.mod and go.sum to the state of master Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Don't omit client secret check for PKCE Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Allow public clients (e.g. with PKCE) to have redirect URIs configured Signed-off-by: Martin Heide <martin.heide@faro.com> * Remove "Authorization" as Accepted Headers on CORS, small fixes Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Revert "Allow public clients (e.g. with PKCE) to have redirect URIs configured" This reverts commit b6e297b78537dc44cd3e1374f0b4d34bf89404ac. Signed-off-by: Martin Heide <martin.heide@faro.com> * PKCE on client_secret client error message * When connecting to the token endpoint with PKCE without client_secret, but the client is configured with a client_secret, generate a special error message. Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * Output info message when PKCE without client_secret used on confidential client * removes the special error message Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> * General missing/invalid client_secret message on token endpoint Signed-off-by: Bernd Eckstein <Bernd.Eckstein@faro.com> Co-authored-by: Tadeusz Magura-Witkowski <tadeuszmw@gmail.com> Co-authored-by: Martin Heide <martin.heide@faro.com> Co-authored-by: M. Heide <66078329+heidemn-faro@users.noreply.github.com>
2020-10-26 16:03:40 +05:30
PKCE: storage.PKCE{
CodeChallenge: a.CodeChallenge,
CodeChallengeMethod: a.CodeChallengeMethod,
},
}
}
// RefreshToken is a mirrored struct from storage with JSON struct tags
type RefreshToken struct {
ID string `json:"id"`
Token string `json:"token"`
ObsoleteToken string `json:"obsolete_token"`
CreatedAt time.Time `json:"created_at"`
LastUsed time.Time `json:"last_used"`
ClientID string `json:"client_id"`
ConnectorID string `json:"connector_id"`
ConnectorData []byte `json:"connector_data"`
Claims Claims `json:"claims"`
Scopes []string `json:"scopes"`
Nonce string `json:"nonce"`
}
func toStorageRefreshToken(r RefreshToken) storage.RefreshToken {
return storage.RefreshToken{
2019-04-18 19:47:31 +05:30
ID: r.ID,
Token: r.Token,
ObsoleteToken: r.ObsoleteToken,
2019-04-18 19:47:31 +05:30
CreatedAt: r.CreatedAt,
LastUsed: r.LastUsed,
ClientID: r.ClientID,
ConnectorID: r.ConnectorID,
ConnectorData: r.ConnectorData,
Scopes: r.Scopes,
Nonce: r.Nonce,
Claims: toStorageClaims(r.Claims),
}
}
func fromStorageRefreshToken(r storage.RefreshToken) RefreshToken {
return RefreshToken{
2019-04-18 19:47:31 +05:30
ID: r.ID,
Token: r.Token,
ObsoleteToken: r.ObsoleteToken,
2019-04-18 19:47:31 +05:30
CreatedAt: r.CreatedAt,
LastUsed: r.LastUsed,
ClientID: r.ClientID,
ConnectorID: r.ConnectorID,
ConnectorData: r.ConnectorData,
Scopes: r.Scopes,
Nonce: r.Nonce,
Claims: fromStorageClaims(r.Claims),
}
}
// Claims is a mirrored struct from storage with JSON struct tags.
type Claims struct {
UserID string `json:"userID"`
Username string `json:"username"`
PreferredUsername string `json:"preferredUsername"`
Email string `json:"email"`
EmailVerified bool `json:"emailVerified"`
Groups []string `json:"groups,omitempty"`
}
func fromStorageClaims(i storage.Claims) Claims {
return Claims{
UserID: i.UserID,
Username: i.Username,
PreferredUsername: i.PreferredUsername,
Email: i.Email,
EmailVerified: i.EmailVerified,
Groups: i.Groups,
}
}
func toStorageClaims(i Claims) storage.Claims {
return storage.Claims{
UserID: i.UserID,
Username: i.Username,
PreferredUsername: i.PreferredUsername,
Email: i.Email,
EmailVerified: i.EmailVerified,
Groups: i.Groups,
}
}
// Keys is a mirrored struct from storage with JSON struct tags
type Keys struct {
SigningKey *jose.JSONWebKey `json:"signing_key,omitempty"`
SigningKeyPub *jose.JSONWebKey `json:"signing_key_pub,omitempty"`
VerificationKeys []storage.VerificationKey `json:"verification_keys"`
NextRotation time.Time `json:"next_rotation"`
}
// OfflineSessions is a mirrored struct from storage with JSON struct tags
type OfflineSessions struct {
2018-01-30 02:41:59 +05:30
UserID string `json:"user_id,omitempty"`
ConnID string `json:"conn_id,omitempty"`
Refresh map[string]*storage.RefreshTokenRef `json:"refresh,omitempty"`
ConnectorData []byte `json:"connectorData,omitempty"`
}
func fromStorageOfflineSessions(o storage.OfflineSessions) OfflineSessions {
return OfflineSessions{
2018-01-30 02:41:59 +05:30
UserID: o.UserID,
ConnID: o.ConnID,
Refresh: o.Refresh,
ConnectorData: o.ConnectorData,
}
}
func toStorageOfflineSessions(o OfflineSessions) storage.OfflineSessions {
s := storage.OfflineSessions{
2018-01-30 02:41:59 +05:30
UserID: o.UserID,
ConnID: o.ConnID,
Refresh: o.Refresh,
ConnectorData: o.ConnectorData,
}
if s.Refresh == nil {
// Server code assumes this will be non-nil.
s.Refresh = make(map[string]*storage.RefreshTokenRef)
}
return s
}
// DeviceRequest is a mirrored struct from storage with JSON struct tags
type DeviceRequest struct {
UserCode string `json:"user_code"`
DeviceCode string `json:"device_code"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Scopes []string `json:"scopes"`
Expiry time.Time `json:"expiry"`
}
func fromStorageDeviceRequest(d storage.DeviceRequest) DeviceRequest {
return DeviceRequest{
UserCode: d.UserCode,
DeviceCode: d.DeviceCode,
ClientID: d.ClientID,
ClientSecret: d.ClientSecret,
Scopes: d.Scopes,
Expiry: d.Expiry,
}
}
// DeviceToken is a mirrored struct from storage with JSON struct tags
type DeviceToken struct {
DeviceCode string `json:"device_code"`
Status string `json:"status"`
Token string `json:"token"`
Expiry time.Time `json:"expiry"`
LastRequestTime time.Time `json:"last_request"`
PollIntervalSeconds int `json:"poll_interval"`
CodeChallenge string `json:"code_challenge,omitempty"`
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
}
func fromStorageDeviceToken(t storage.DeviceToken) DeviceToken {
return DeviceToken{
DeviceCode: t.DeviceCode,
Status: t.Status,
Token: t.Token,
Expiry: t.Expiry,
LastRequestTime: t.LastRequestTime,
PollIntervalSeconds: t.PollIntervalSeconds,
CodeChallenge: t.PKCE.CodeChallenge,
CodeChallengeMethod: t.PKCE.CodeChallengeMethod,
}
}
func toStorageDeviceToken(t DeviceToken) storage.DeviceToken {
return storage.DeviceToken{
DeviceCode: t.DeviceCode,
Status: t.Status,
Token: t.Token,
Expiry: t.Expiry,
LastRequestTime: t.LastRequestTime,
PollIntervalSeconds: t.PollIntervalSeconds,
PKCE: storage.PKCE{
CodeChallenge: t.CodeChallenge,
CodeChallengeMethod: t.CodeChallengeMethod,
},
}
}