Skip to content

Commit

Permalink
Merge pull request #128751 from cockroachdb/blathers/backport-release…
Browse files Browse the repository at this point in the history
…-23.1.25-rc-128669

release-23.1.25-rc: jwtauthccl: add mapper for issuer url to jwks URI
  • Loading branch information
souravcrl authored Aug 12, 2024
2 parents 23983a8 + 3469436 commit e2f43c5
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 90 deletions.
1 change: 1 addition & 0 deletions pkg/ccl/jwtauthccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ go_library(
"@com_github_cockroachdb_errors//:errors",
"@com_github_lestrrat_go_jwx//jwk",
"@com_github_lestrrat_go_jwx//jwt",
"@org_golang_x_exp//maps",
],
)

Expand Down
51 changes: 26 additions & 25 deletions pkg/ccl/jwtauthccl/authentication_jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type jwtAuthenticator struct {
type jwtAuthenticatorConf struct {
audience []string
enabled bool
issuers []string
issuersConf issuerURLConf
jwks jwk.Set
claim string
jwksAutoFetchEnabled bool
Expand All @@ -87,7 +87,7 @@ func (authenticator *jwtAuthenticator) reloadConfigLocked(
conf := jwtAuthenticatorConf{
audience: mustParseValueOrArray(JWTAuthAudience.Get(&st.SV)),
enabled: JWTAuthEnabled.Get(&st.SV),
issuers: mustParseValueOrArray(JWTAuthIssuers.Get(&st.SV)),
issuersConf: mustParseJWTIssuersConf(JWTAuthIssuersConfig.Get(&st.SV)),
jwks: mustParseJWKS(JWTAuthJWKS.Get(&st.SV)),
claim: JWTAuthClaim.Get(&st.SV),
jwksAutoFetchEnabled: JWKSAutoFetchEnabled.Get(&st.SV),
Expand Down Expand Up @@ -157,25 +157,15 @@ func (authenticator *jwtAuthenticator) ValidateJWTLogin(
}

// Check for issuer match against configured issuers.
issuerUrl := ""
issuerMatch := false
for _, issuer := range authenticator.mu.conf.issuers {
if issuer == unverifiedToken.Issuer() {
issuerMatch = true
issuerUrl = issuer
break
}
}
if !issuerMatch {
return "", errors.WithDetailf(
errors.Newf("JWT authentication: invalid issuer"),
"token issued by %s", unverifiedToken.Issuer())
tokenIssuer := unverifiedToken.Issuer()
if err = authenticator.mu.conf.issuersConf.checkIssuerConfigured(tokenIssuer); err != nil {
return "", errors.WithDetailf(err, "token issued by %s", tokenIssuer)
}

var jwkSet jwk.Set
// If auto-fetch is enabled, fetch the JWKS remotely from the issuer's well known jwks url.
// If auto-fetch is enabled, fetch the JWKS remotely from the issuer's well known jwks URI.
if authenticator.mu.conf.jwksAutoFetchEnabled {
jwkSet, err = authenticator.remoteFetchJWKS(ctx, issuerUrl)
jwkSet, err = authenticator.remoteFetchJWKS(ctx, tokenIssuer)
if err != nil {
return fmt.Sprintf("unable to fetch jwks: %v", err),
errors.Newf("JWT authentication: unable to validate token")
Expand Down Expand Up @@ -278,16 +268,27 @@ func (authenticator *jwtAuthenticator) ValidateJWTLogin(
return "", nil
}

// remoteFetchJWKS fetches the JWKS from the provided URI.
// remoteFetchJWKS fetches the JWKS URI from the provided issuer URL.
func (authenticator *jwtAuthenticator) remoteFetchJWKS(
ctx context.Context, issuerUrl string,
ctx context.Context, issuerURL string,
) (jwk.Set, error) {
jwksUrl, err := authenticator.getJWKSUrl(ctx, issuerUrl)
var jwksURI string
// if JWKS URI is configured in JWTAuthIssuersConfig use that instead of URL
// from issuer's well-known endpoint
err := authenticator.mu.conf.issuersConf.checkJWKSConfigured()
if err != nil {
return nil, err
jwksURI, err = authenticator.getJWKSURI(ctx, issuerURL)
if err != nil {
return nil, err
}
} else {
jwksURI, err = authenticator.mu.conf.issuersConf.getJWKSURI(issuerURL)
if err != nil {
return nil, err
}
}

body, err := getHttpResponse(ctx, jwksUrl, authenticator)
body, err := getHttpResponse(ctx, jwksURI, authenticator)
if err != nil {
return nil, err
}
Expand All @@ -298,8 +299,8 @@ func (authenticator *jwtAuthenticator) remoteFetchJWKS(
return jwkSet, nil
}

// getJWKSUrl returns the JWKS URI from the OpenID configuration endpoint.
func (authenticator *jwtAuthenticator) getJWKSUrl(
// getJWKSURI returns the JWKS URI from the OpenID configuration endpoint.
func (authenticator *jwtAuthenticator) getJWKSURI(
ctx context.Context, issuerUrl string,
) (string, error) {
type OIDCConfigResponse struct {
Expand Down Expand Up @@ -361,7 +362,7 @@ var ConfigureJWTAuth = func(
JWTAuthEnabled.SetOnChange(&st.SV, func(ctx context.Context) {
authenticator.reloadConfig(ambientCtx.AnnotateCtx(ctx), st)
})
JWTAuthIssuers.SetOnChange(&st.SV, func(ctx context.Context) {
JWTAuthIssuersConfig.SetOnChange(&st.SV, func(ctx context.Context) {
authenticator.reloadConfig(ambientCtx.AnnotateCtx(ctx), st)
})
JWTAuthJWKS.SetOnChange(&st.SV, func(ctx context.Context) {
Expand Down
Loading

0 comments on commit e2f43c5

Please sign in to comment.