Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,9 @@ ENABLED = true
;; Alternative location to specify OAuth2 authentication secret. You cannot specify both this and JWT_SECRET, and must pick one
;JWT_SECRET_URI = file:/etc/gitea/oauth2_jwt_secret
;;
;; The "issuer" claim identifies the principal that issued the JWT. Default to ROOT_URL without the last slash.
;JWT_CLAIM_ISSUER =
;;
;; Lifetime of an OAuth2 access token in seconds
;ACCESS_TOKEN_EXPIRATION_TIME = 3600
;;
Expand Down
1 change: 1 addition & 0 deletions modules/setting/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ var OAuth2 = struct {
InvalidateRefreshTokens bool
JWTSigningAlgorithm string `ini:"JWT_SIGNING_ALGORITHM"`
JWTSigningPrivateKeyFile string `ini:"JWT_SIGNING_PRIVATE_KEY_FILE"`
JWTClaimIssuer string `ini:"JWT_CLAIM_ISSUER"`
MaxTokenLength int
DefaultApplications []string
}{
Expand Down
6 changes: 5 additions & 1 deletion services/oauth2_provider/access_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,12 @@ func NewJwtRegisteredClaimsFromUser(clientID string, grantUserID int64, exp *jwt
// to retrieve the configuration information. This MUST also be identical to the "iss" Claim value in ID Tokens issued from this Issuer.
// * https://accounts.google.com/.well-known/openid-configuration
// * https://github.com/login/oauth/.well-known/openid-configuration
issuer := setting.OAuth2.JWTClaimIssuer
if issuer == "" {
issuer = strings.TrimSuffix(setting.AppURL, "/")
}
return jwt.RegisteredClaims{
Issuer: strings.TrimSuffix(setting.AppURL, "/"),
Issuer: issuer,
Audience: []string{clientID},
Subject: strconv.FormatInt(grantUserID, 10),
ExpiresAt: exp,
Expand Down
36 changes: 24 additions & 12 deletions tests/integration/oauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -919,20 +919,32 @@ func TestOAuth_GrantScopesClaimAllGroups(t *testing.T) {
}

func testOAuth2WellKnown(t *testing.T) {
defer test.MockVariableValue(&setting.AppURL, "https://try.gitea.io/")()
urlOpenidConfiguration := "/.well-known/openid-configuration"

defer test.MockVariableValue(&setting.AppURL, "https://try.gitea.io/")()
req := NewRequest(t, "GET", urlOpenidConfiguration)
resp := MakeRequest(t, req, http.StatusOK)
var respMap map[string]any
DecodeJSON(t, resp, &respMap)
assert.Equal(t, "https://try.gitea.io", respMap["issuer"])
assert.Equal(t, "https://try.gitea.io/login/oauth/authorize", respMap["authorization_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/access_token", respMap["token_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/keys", respMap["jwks_uri"])
assert.Equal(t, "https://try.gitea.io/login/oauth/userinfo", respMap["userinfo_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/introspect", respMap["introspection_endpoint"])
assert.Equal(t, []any{"RS256"}, respMap["id_token_signing_alg_values_supported"])
t.Run("WellKnown", func(t *testing.T) {
req := NewRequest(t, "GET", urlOpenidConfiguration)
resp := MakeRequest(t, req, http.StatusOK)
var respMap map[string]any
DecodeJSON(t, resp, &respMap)
assert.Equal(t, "https://try.gitea.io", respMap["issuer"])
assert.Equal(t, "https://try.gitea.io/login/oauth/authorize", respMap["authorization_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/access_token", respMap["token_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/keys", respMap["jwks_uri"])
assert.Equal(t, "https://try.gitea.io/login/oauth/userinfo", respMap["userinfo_endpoint"])
assert.Equal(t, "https://try.gitea.io/login/oauth/introspect", respMap["introspection_endpoint"])
assert.Equal(t, []any{"RS256"}, respMap["id_token_signing_alg_values_supported"])
})

t.Run("WellKnownWithIssuer", func(t *testing.T) {
defer test.MockVariableValue(&setting.OAuth2.JWTClaimIssuer, "https://try.gitea.io/")()
req := NewRequest(t, "GET", urlOpenidConfiguration)
resp := MakeRequest(t, req, http.StatusOK)
var respMap map[string]any
DecodeJSON(t, resp, &respMap)
assert.Equal(t, "https://try.gitea.io/", respMap["issuer"]) // has trailing by JWTClaimIssuer
assert.Equal(t, "https://try.gitea.io/login/oauth/authorize", respMap["authorization_endpoint"])
})

defer test.MockVariableValue(&setting.OAuth2.Enabled, false)()
MakeRequest(t, NewRequest(t, "GET", urlOpenidConfiguration), http.StatusNotFound)
Expand Down
Loading