Skip to content

Commit 34f509e

Browse files
hickfordwxiaoguangzeripath
authored
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 <[email protected]> Co-authored-by: zeripath <[email protected]>
1 parent f09f73d commit 34f509e

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

routers/web/auth/oauth.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,8 @@ func OIDCKeys(ctx *context.Context) {
588588
// AccessTokenOAuth manages all access token requests by the client
589589
func AccessTokenOAuth(ctx *context.Context) {
590590
form := *web.GetForm(ctx).(*forms.AccessTokenForm)
591-
if form.ClientID == "" {
591+
// 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
592+
if form.ClientID == "" || form.ClientSecret == "" {
592593
authHeader := ctx.Req.Header.Get("Authorization")
593594
authContent := strings.SplitN(authHeader, " ", 2)
594595
if len(authContent) == 2 && authContent[0] == "Basic" {
@@ -608,7 +609,21 @@ func AccessTokenOAuth(ctx *context.Context) {
608609
})
609610
return
610611
}
612+
if form.ClientID != "" && form.ClientID != pair[0] {
613+
handleAccessTokenError(ctx, AccessTokenError{
614+
ErrorCode: AccessTokenErrorCodeInvalidRequest,
615+
ErrorDescription: "client_id in request body inconsistent with Authorization header",
616+
})
617+
return
618+
}
611619
form.ClientID = pair[0]
620+
if form.ClientSecret != "" && form.ClientSecret != pair[1] {
621+
handleAccessTokenError(ctx, AccessTokenError{
622+
ErrorCode: AccessTokenErrorCodeInvalidRequest,
623+
ErrorDescription: "client_secret in request body inconsistent with Authorization header",
624+
})
625+
return
626+
}
612627
form.ClientSecret = pair[1]
613628
}
614629
}
@@ -686,9 +701,13 @@ func handleAuthorizationCode(ctx *context.Context, form forms.AccessTokenForm, s
686701
return
687702
}
688703
if !app.ValidateClientSecret([]byte(form.ClientSecret)) {
704+
errorDescription := "invalid client secret"
705+
if form.ClientSecret == "" {
706+
errorDescription = "invalid empty client secret"
707+
}
689708
handleAccessTokenError(ctx, AccessTokenError{
690709
ErrorCode: AccessTokenErrorCodeUnauthorizedClient,
691-
ErrorDescription: "invalid client secret",
710+
ErrorDescription: errorDescription,
692711
})
693712
return
694713
}

0 commit comments

Comments
 (0)