aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web/auth
diff options
context:
space:
mode:
authorM Hickford <mirth.hickford@gmail.com>2022-10-07 03:53:49 +0100
committerGitHub <noreply@github.com>2022-10-07 10:53:49 +0800
commit34f509eb7a48e698114261de323834482553a98c (patch)
treef3ab567fa99c97b0aafa3833e5c964f7e6679b6b /routers/web/auth
parentf09f73d784eb3a51da3d108f8be5116441cbd73d (diff)
downloadgitea-34f509eb7a48e698114261de323834482553a98c.tar.gz
gitea-34f509eb7a48e698114261de323834482553a98c.zip
Parse OAuth Authorization header when request omits client secret (#21351)
This fixes error "unauthorized_client: invalid client secret" when client includes secret in Authorization header rather than request body. OAuth spec permits both. Sanity validation that client id and client secret in request are consistent with Authorization header. Improve error descriptions. Error codes remain the same. Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: zeripath <art27@cantab.net>
Diffstat (limited to 'routers/web/auth')
-rw-r--r--routers/web/auth/oauth.go23
1 files changed, 21 insertions, 2 deletions
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index d145150535..e6112b4276 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -588,7 +588,8 @@ func OIDCKeys(ctx *context.Context) {
// AccessTokenOAuth manages all access token requests by the client
func AccessTokenOAuth(ctx *context.Context) {
form := *web.GetForm(ctx).(*forms.AccessTokenForm)
- if form.ClientID == "" {
+ // if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
+ if form.ClientID == "" || form.ClientSecret == "" {
authHeader := ctx.Req.Header.Get("Authorization")
authContent := strings.SplitN(authHeader, " ", 2)
if len(authContent) == 2 && authContent[0] == "Basic" {
@@ -608,7 +609,21 @@ func AccessTokenOAuth(ctx *context.Context) {
})
return
}
+ if form.ClientID != "" && form.ClientID != pair[0] {
+ handleAccessTokenError(ctx, AccessTokenError{
+ ErrorCode: AccessTokenErrorCodeInvalidRequest,
+ ErrorDescription: "client_id in request body inconsistent with Authorization header",
+ })
+ return
+ }
form.ClientID = pair[0]
+ if form.ClientSecret != "" && form.ClientSecret != pair[1] {
+ handleAccessTokenError(ctx, AccessTokenError{
+ ErrorCode: AccessTokenErrorCodeInvalidRequest,
+ ErrorDescription: "client_secret in request body inconsistent with Authorization header",
+ })
+ return
+ }
form.ClientSecret = pair[1]
}
}
@@ -686,9 +701,13 @@ func handleAuthorizationCode(ctx *context.Context, form forms.AccessTokenForm, s
return
}
if !app.ValidateClientSecret([]byte(form.ClientSecret)) {
+ errorDescription := "invalid client secret"
+ if form.ClientSecret == "" {
+ errorDescription = "invalid empty client secret"
+ }
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeUnauthorizedClient,
- ErrorDescription: "invalid client secret",
+ ErrorDescription: errorDescription,
})
return
}