Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Commit

Permalink
validate retrieved token with configured JWKS (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergicastro authored Feb 19, 2024
1 parent b2bfa99 commit f281f16
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 42 deletions.
54 changes: 31 additions & 23 deletions internal/authz/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
"github.com/lestrrat-go/jwx/jws"
"github.com/tetratelabs/telemetry"
"google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -375,37 +376,44 @@ func (o *oidcHandler) retrieveTokens(ctx context.Context, log telemetry.Logger,
return
}

if oidcNonce, ok := idToken.Get("nonce"); ok {
if oidcNonce.(string) != stateFromStore.Nonce {
log.Info("id token nonce does not match", "nonce-from-id-token", oidcNonce, "nonce-from-store", stateFromStore.Nonce)
setDenyResponse(resp, newDenyResponse(), codes.InvalidArgument)
return
}
oidcNonce, ok := idToken.Get("nonce")
if !ok {
log.Info("id token does not have nonce claim")
setDenyResponse(resp, newDenyResponse(), codes.InvalidArgument)
return
}
var (
audMatches bool
oidcAud interface{}
ok bool
)
if oidcAud, ok = idToken.Get("aud"); ok {
switch aud := oidcAud.(type) {
case string:
audMatches = aud == o.config.GetClientId()
case []string:
for _, a := range aud {
if a == o.config.GetClientId() {
audMatches = true
break
}
}
if oidcNonce.(string) != stateFromStore.Nonce {
log.Info("id token nonce does not match", "nonce-from-id-token", oidcNonce, "nonce-from-store", stateFromStore.Nonce)
setDenyResponse(resp, newDenyResponse(), codes.InvalidArgument)
return
}

var audMatches bool
for _, a := range idToken.Audience() {
if a == o.config.GetClientId() {
audMatches = true
break
}
}
if !audMatches {
log.Info("id token audience does not match", "aud-from-id-token", oidcAud, "aud-from-config", o.config.GetClientId())
log.Info("id token audience does not match", "aud-from-id-token", idToken.Audience(), "aud-from-config", o.config.GetClientId())
setDenyResponse(resp, newDenyResponse(), codes.InvalidArgument)
return
}

jwtSet, err := o.jwks.Get(ctx, o.config)
if err != nil {
log.Error("error fetching jwks", err)
setDenyResponse(resp, newDenyResponse(), codes.Internal)
return
}

if _, err := jws.VerifySet([]byte(bodyTokens.IDToken), jwtSet); err != nil {
log.Error("error verifying id token with fetched jwks", err)
setDenyResponse(resp, newDenyResponse(), codes.Internal)
return
}

// https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
// token_type must be Bearer
if bodyTokens.TokenType != "Bearer" {
Expand Down
Loading

0 comments on commit f281f16

Please sign in to comment.