Update fosite error usage.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
Matt Moyer 2020-12-17 14:09:19 -06:00
parent 421c17c421
commit 3a81fbd1b4
No known key found for this signature in database
GPG Key ID: EAE88AD172C5AE2D
11 changed files with 38 additions and 91 deletions

View File

@ -86,7 +86,7 @@ func (a *accessTokenStorage) getSession(ctx context.Context, signature string) (
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithCause(err).WithDebug(err.Error())
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
if err != nil {

View File

@ -110,7 +110,7 @@ func (a *authorizeCodeStorage) getSession(ctx context.Context, signature string)
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithCause(err).WithDebug(err.Error())
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
if err != nil {

View File

@ -88,7 +88,7 @@ func (a *openIDConnectRequestStorage) getSession(ctx context.Context, signature
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithCause(err).WithDebug(err.Error())
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
if err != nil {

View File

@ -72,7 +72,7 @@ func (a *pkceStorage) getSession(ctx context.Context, signature string) (*sessio
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithCause(err).WithDebug(err.Error())
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
if err != nil {

View File

@ -86,7 +86,7 @@ func (a *refreshTokenStorage) getSession(ctx context.Context, signature string)
rv, err := a.storage.Get(ctx, signature, session)
if errors.IsNotFound(err) {
return nil, "", fosite.ErrNotFound.WithCause(err).WithDebug(err.Error())
return nil, "", fosite.ErrNotFound.WithWrap(err).WithDebug(err.Error())
}
if err != nil {

View File

@ -41,76 +41,62 @@ func TestAuthorizationEndpoint(t *testing.T) {
fositeInvalidClientErrorBody = here.Doc(`
{
"error": "invalid_client",
"error_verbose": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)",
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)\n\nThe requested OAuth 2.0 Client does not exist.",
"error_hint": "The requested OAuth 2.0 Client does not exist.",
"status_code": 401
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The requested OAuth 2.0 Client does not exist."
}
`)
fositeInvalidRedirectURIErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nThe \"redirect_uri\" parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls.",
"error_hint": "The \"redirect_uri\" parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls.",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."
}
`)
fositePromptHasNoneAndOtherValueErrorQuery = map[string]string{
"error": "invalid_request",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nParameter \"prompt\" was set to \"none\", but contains other values as well which is not allowed.",
"error_hint": "Parameter \"prompt\" was set to \"none\", but contains other values as well which is not allowed.",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Parameter 'prompt' was set to 'none', but contains other values as well which is not allowed.",
"state": happyState,
}
fositeMissingCodeChallengeErrorQuery = map[string]string{
"error": "invalid_request",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nClients must include a code_challenge when performing the authorize code flow, but it is missing.",
"error_hint": "Clients must include a code_challenge when performing the authorize code flow, but it is missing.",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Clients must include a code_challenge when performing the authorize code flow, but it is missing.",
"state": happyState,
}
fositeMissingCodeChallengeMethodErrorQuery = map[string]string{
"error": "invalid_request",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nClients must use code_challenge_method=S256, plain is not allowed.",
"error_hint": "Clients must use code_challenge_method=S256, plain is not allowed.",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Clients must use code_challenge_method=S256, plain is not allowed.",
"state": happyState,
}
fositeInvalidCodeChallengeErrorQuery = map[string]string{
"error": "invalid_request",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nThe code_challenge_method is not supported, use S256 instead.",
"error_hint": "The code_challenge_method is not supported, use S256 instead.",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The code_challenge_method is not supported, use S256 instead.",
"state": happyState,
}
fositeUnsupportedResponseTypeErrorQuery = map[string]string{
"error": "unsupported_response_type",
"error_description": "The authorization server does not support obtaining a token using this method\n\nThe client is not allowed to request response_type \"unsupported\".",
"error_hint": `The client is not allowed to request response_type "unsupported".`,
"error_description": "The authorization server does not support obtaining a token using this method. The client is not allowed to request response_type 'unsupported'.",
"state": happyState,
}
fositeInvalidScopeErrorQuery = map[string]string{
"error": "invalid_scope",
"error_description": "The requested scope is invalid, unknown, or malformed\n\nThe OAuth 2.0 Client is not allowed to request scope \"tuna\".",
"error_hint": `The OAuth 2.0 Client is not allowed to request scope "tuna".`,
"error_description": "The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope 'tuna'.",
"state": happyState,
}
fositeInvalidStateErrorQuery = map[string]string{
"error": "invalid_state",
"error_description": "The state is missing or does not have enough characters and is therefore considered too weak\n\nRequest parameter \"state\" must be at least be 8 characters long to ensure sufficient entropy.",
"error_hint": `Request parameter "state" must be at least be 8 characters long to ensure sufficient entropy.`,
"error_description": "The state is missing or does not have enough characters and is therefore considered too weak. Request parameter 'state' must be at least be 8 characters long to ensure sufficient entropy.",
"state": "short",
}
fositeMissingResponseTypeErrorQuery = map[string]string{
"error": "unsupported_response_type",
"error_description": "The authorization server does not support obtaining a token using this method\n\nThe request is missing the \"response_type\"\" parameter.",
"error_hint": `The request is missing the "response_type"" parameter.`,
"error_description": "The authorization server does not support obtaining a token using this method. `The request is missing the 'response_type' parameter.",
"state": happyState,
}
)

View File

@ -356,7 +356,7 @@ func TestCallbackEndpoint(t *testing.T) {
).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusFound,
wantRedirectLocationRegexp: downstreamRedirectURI + `\?code=([^&]+)&scope=openid%20offline_access&state=` + happyDownstreamState,
wantRedirectLocationRegexp: downstreamRedirectURI + `\?code=([^&]+)&scope=openid\+offline_access&state=` + happyDownstreamState,
wantDownstreamIDTokenUsername: upstreamUsername,
wantDownstreamIDTokenSubject: upstreamIssuer + "?sub=" + upstreamSubject,
wantDownstreamRequestedScopes: []string{"openid", "offline_access"},

View File

@ -50,7 +50,7 @@ func (s *dynamicOpenIDConnectECDSAStrategy) GenerateIDToken(
_, activeJwk := s.jwksProvider.GetJWKS(s.fositeConfig.IDTokenIssuer)
if activeJwk == nil {
plog.Debug("no JWK found for issuer", "issuer", s.fositeConfig.IDTokenIssuer)
return "", fosite.ErrTemporarilyUnavailable.WithCause(constable.Error("no JWK found for issuer"))
return "", fosite.ErrTemporarilyUnavailable.WithWrap(constable.Error("no JWK found for issuer"))
}
key, ok := activeJwk.Key.(*ecdsa.PrivateKey)
if !ok {
@ -65,7 +65,7 @@ func (s *dynamicOpenIDConnectECDSAStrategy) GenerateIDToken(
"actualType",
actualType,
)
return "", fosite.ErrServerError.WithCause(constable.Error("JWK must be of type ecdsa"))
return "", fosite.ErrServerError.WithWrap(constable.Error("JWK must be of type ecdsa"))
}
return compose.NewOpenIDConnectECDSAStrategy(s.fositeConfig, key).GenerateIDToken(ctx, requester)

View File

@ -266,11 +266,11 @@ func FositeErrorForLog(err error) []interface{} {
rfc6749Error := fosite.ErrorToRFC6749Error(err)
keysAndValues := make([]interface{}, 0)
keysAndValues = append(keysAndValues, "name")
keysAndValues = append(keysAndValues, rfc6749Error.Name)
keysAndValues = append(keysAndValues, rfc6749Error.ErrorField)
keysAndValues = append(keysAndValues, "status")
keysAndValues = append(keysAndValues, rfc6749Error.Status())
keysAndValues = append(keysAndValues, "description")
keysAndValues = append(keysAndValues, rfc6749Error.Description)
keysAndValues = append(keysAndValues, rfc6749Error.DescriptionField)
return keysAndValues
}

View File

@ -78,138 +78,99 @@ var (
return here.Docf(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nHTTP method is \"%s\", expected \"POST\".",
"error_hint": "HTTP method is \"%s\", expected \"POST\".",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. HTTP method is '%s', expected 'POST'."
}
`, actual, actual)
`, actual)
}
fositeMissingGrantTypeErrorBody = here.Docf(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nRequest parameter \"grant_type\"\" is missing",
"error_hint": "Request parameter \"grant_type\"\" is missing",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Request parameter 'grant_type' is missing"
}
`)
fositeEmptyPayloadErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nThe POST body can not be empty.",
"error_hint": "The POST body can not be empty.",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The POST body can not be empty."
}
`)
fositeInvalidPayloadErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nUnable to parse HTTP body, make sure to send a properly formatted form request body.",
"error_hint": "Unable to parse HTTP body, make sure to send a properly formatted form request body.",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Unable to parse HTTP body, make sure to send a properly formatted form request body."
}
`)
fositeInvalidRequestErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nMake sure that the various parameters are correct, be aware of case sensitivity and trim your parameters. Make sure that the client you are using has exactly whitelisted the redirect_uri you specified.",
"error_hint": "Make sure that the various parameters are correct, be aware of case sensitivity and trim your parameters. Make sure that the client you are using has exactly whitelisted the redirect_uri you specified.",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Make sure that the various parameters are correct, be aware of case sensitivity and trim your parameters. Make sure that the client you are using has exactly whitelisted the redirect_uri you specified."
}
`)
fositeInvalidRequestMissingGrantTypeErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nRequest parameter \"grant_type\"\" is missing",
"error_hint": "Request parameter \"grant_type\"\" is missing",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Request parameter 'grant_type' is missing"
}
`)
fositeMissingClientErrorBody = here.Doc(`
{
"error": "invalid_request",
"error_verbose": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed\n\nClient credentials missing or malformed in both HTTP Authorization header and HTTP POST body.",
"error_hint": "Client credentials missing or malformed in both HTTP Authorization header and HTTP POST body.",
"status_code": 400
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Client credentials missing or malformed in both HTTP Authorization header and HTTP POST body."
}
`)
fositeInvalidClientErrorBody = here.Doc(`
{
"error": "invalid_client",
"error_verbose": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)",
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)",
"status_code": 401
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)."
}
`)
fositeInvalidAuthCodeErrorBody = here.Doc(`
{
"error": "invalid_grant",
"error_verbose": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"status_code": 400
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}
`)
fositeReusedAuthCodeErrorBody = here.Doc(`
{
"error": "invalid_grant",
"error_verbose": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client\n\nThe authorization code has already been used.",
"error_hint": "The authorization code has already been used.",
"status_code": 400
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used."
}
`)
fositeInvalidRedirectURIErrorBody = here.Doc(`
{
"error": "invalid_grant",
"error_verbose": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client\n\nThe \"redirect_uri\" from this request does not match the one from the authorize request.",
"error_hint": "The \"redirect_uri\" from this request does not match the one from the authorize request.",
"status_code": 400
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The 'redirect_uri' from this request does not match the one from the authorize request."
}
`)
fositeMissingPKCEVerifierErrorBody = here.Doc(`
{
"error": "invalid_grant",
"error_verbose": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client\n\nThe PKCE code verifier must be at least 43 characters.",
"error_hint": "The PKCE code verifier must be at least 43 characters.",
"status_code": 400
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The PKCE code verifier must be at least 43 characters."
}
`)
fositeWrongPKCEVerifierErrorBody = here.Doc(`
{
"error": "invalid_grant",
"error_verbose": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client\n\nThe PKCE code challenge did not match the code verifier.",
"error_hint": "The PKCE code challenge did not match the code verifier.",
"status_code": 400
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The PKCE code challenge did not match the code verifier."
}
`)
fositeTemporarilyUnavailableErrorBody = here.Doc(`
{
"error": "temporarily_unavailable",
"error_description": "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server",
"error_verbose": "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server",
"status_code": 503
"error_description": "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server."
}
`)
@ -749,7 +710,7 @@ func TestTokenExchange(t *testing.T) {
},
requestedAudience: "some-workload-cluster",
wantStatus: http.StatusForbidden,
wantResponseBodyContains: `missing the \"pinniped:request-audience\" scope`,
wantResponseBodyContains: `missing the 'pinniped:request-audience' scope`,
},
{
name: "access token missing openid scope",
@ -766,7 +727,7 @@ func TestTokenExchange(t *testing.T) {
},
requestedAudience: "some-workload-cluster",
wantStatus: http.StatusForbidden,
wantResponseBodyContains: `missing the \"openid\" scope`,
wantResponseBodyContains: `missing the 'openid' scope`,
},
{
name: "token minting failure",

View File

@ -135,7 +135,7 @@ func (t *TokenExchangeHandler) validateAccessToken(ctx context.Context, requeste
signature := t.accessTokenStrategy.AccessTokenSignature(accessToken)
originalRequester, err := t.accessTokenStorage.GetAccessTokenSession(ctx, signature, requester.GetSession())
if err != nil {
return nil, fosite.ErrRequestUnauthorized.WithCause(err).WithHint("invalid subject_token")
return nil, fosite.ErrRequestUnauthorized.WithWrap(err).WithHint("invalid subject_token")
}
return originalRequester, nil
}