diff options
author | M Hickford <mirth.hickford@gmail.com> | 2022-10-23 07:28:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-23 13:28:46 +0800 |
commit | afebbf29a92b895cd41038a06a68e6f4013df357 (patch) | |
tree | 3ffc1cadcc32be85ec59aede1fb7e01cb6eaeeb6 /routers/web | |
parent | f982a71997e057bce009574d04503177788e5a4e (diff) | |
download | gitea-afebbf29a92b895cd41038a06a68e6f4013df357.tar.gz gitea-afebbf29a92b895cd41038a06a68e6f4013df357.zip |
Require authentication for OAuth token refresh (#21421)
According to the OAuth spec
https://datatracker.ietf.org/doc/html/rfc6749#section-6 when "Refreshing
an Access Token"
> The authorization server MUST ... require client authentication for
confidential clients
Fixes #21418
Co-authored-by: Gusted <williamzijl7@hotmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'routers/web')
-rw-r--r-- | routers/web/auth/oauth.go | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index e0e3c6e59f..c98385c8f6 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -48,6 +48,7 @@ const ( // TODO move error and responses to SDK or models // AuthorizeErrorCode represents an error code specified in RFC 6749 +// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2.1 type AuthorizeErrorCode string const ( @@ -68,6 +69,7 @@ const ( ) // AuthorizeError represents an error type specified in RFC 6749 +// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2.1 type AuthorizeError struct { ErrorCode AuthorizeErrorCode `json:"error" form:"error"` ErrorDescription string @@ -80,6 +82,7 @@ func (err AuthorizeError) Error() string { } // AccessTokenErrorCode represents an error code specified in RFC 6749 +// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 type AccessTokenErrorCode string const ( @@ -98,6 +101,7 @@ const ( ) // AccessTokenError represents an error response specified in RFC 6749 +// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 type AccessTokenError struct { ErrorCode AccessTokenErrorCode `json:"error" form:"error"` ErrorDescription string `json:"error_description"` @@ -129,6 +133,7 @@ const ( ) // AccessTokenResponse represents a successful access token response +// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2 type AccessTokenResponse struct { AccessToken string `json:"access_token"` TokenType TokenType `json:"token_type"` @@ -663,6 +668,30 @@ func AccessTokenOAuth(ctx *context.Context) { } func handleRefreshToken(ctx *context.Context, form forms.AccessTokenForm, serverKey, clientKey oauth2.JWTSigningKey) { + app, err := auth.GetOAuth2ApplicationByClientID(ctx, form.ClientID) + if err != nil { + handleAccessTokenError(ctx, AccessTokenError{ + ErrorCode: AccessTokenErrorCodeInvalidClient, + ErrorDescription: fmt.Sprintf("cannot load client with client id: %q", form.ClientID), + }) + return + } + // "The authorization server MUST ... require client authentication for confidential clients" + // https://datatracker.ietf.org/doc/html/rfc6749#section-6 + if !app.ValidateClientSecret([]byte(form.ClientSecret)) { + errorDescription := "invalid client secret" + if form.ClientSecret == "" { + errorDescription = "invalid empty client secret" + } + // "invalid_client ... Client authentication failed" + // https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 + handleAccessTokenError(ctx, AccessTokenError{ + ErrorCode: AccessTokenErrorCodeInvalidClient, + ErrorDescription: errorDescription, + }) + return + } + token, err := oauth2.ParseToken(form.RefreshToken, serverKey) if err != nil { handleAccessTokenError(ctx, AccessTokenError{ |