in src/go/configgenerator/filtergen/jwt_authn.go [129:221]
func (g *JwtAuthnGenerator) GenFilterConfig() (proto.Message, error) {
providers := make(map[string]*jwtpb.JwtProvider)
for _, provider := range g.AuthConfig.GetProviders() {
addr, err := util.ExtractAddressFromURI(provider.GetJwksUri())
if err != nil {
return nil, fmt.Errorf("for provider (%v), failed to parse JWKS URI: %v", provider.Id, err)
}
clusterName := util.JwtProviderClusterName(addr)
fromHeaders, fromParams, err := processJwtLocations(provider)
if err != nil {
return nil, err
}
jwks := &jwtpb.RemoteJwks{
HttpUri: &corepb.HttpUri{
Uri: provider.GetJwksUri(),
HttpUpstreamType: &corepb.HttpUri_Cluster{
Cluster: clusterName,
},
Timeout: durationpb.New(g.HttpRequestTimeout),
},
CacheDuration: &durationpb.Duration{
Seconds: int64(g.JwksCacheDurationInS),
},
}
if !g.DisableJwksAsyncFetch {
jwks.AsyncFetch = &jwtpb.JwksAsyncFetch{
FastListener: g.JwksAsyncFetchFastListener,
}
}
if g.JwksFetchNumRetries > 0 {
// only create a retry policy, evenutally with a backoff if it is required.
rp := &corepb.RetryPolicy{
NumRetries: &wrapperspb.UInt32Value{
Value: uint32(g.JwksFetchNumRetries),
},
RetryBackOff: &corepb.BackoffStrategy{
BaseInterval: durationpb.New(g.JwksFetchRetryBackOffBaseInterval),
MaxInterval: durationpb.New(g.JwksFetchRetryBackOffMaxInterval),
},
}
jwks.RetryPolicy = rp
}
jp := &jwtpb.JwtProvider{
Issuer: provider.GetIssuer(),
JwksSourceSpecifier: &jwtpb.JwtProvider_RemoteJwks{
RemoteJwks: jwks,
},
FromHeaders: fromHeaders,
FromParams: fromParams,
ForwardPayloadHeader: g.GeneratedHeaderPrefix + util.JwtAuthnForwardPayloadHeaderSuffix,
Forward: true,
PadForwardPayloadHeader: g.JwtPadForwardPayloadHeader,
}
if len(provider.GetAudiences()) != 0 {
for _, a := range strings.Split(provider.GetAudiences(), ",") {
jp.Audiences = append(jp.Audiences, strings.TrimSpace(a))
}
} else if !g.DisableJwtAudienceServiceNameCheck {
// No providers specified by user.
// For backwards-compatibility with ESPv1, auto-generate audiences.
// See b/147834348 for more information on this default behavior.
defaultAudience := fmt.Sprintf("https://%v", g.ServiceName)
jp.Audiences = append(jp.Audiences, defaultAudience)
}
if g.JwtCacheSize > 0 {
jp.JwtCacheConfig = &jwtpb.JwtCacheConfig{
JwtCacheSize: uint32(g.JwtCacheSize),
}
}
// TODO(taoxuy): add unit test
// the JWT Payload will be send to metadata by envoy and it will be used by service control filter
// for logging and setting credential_id
jp.PayloadInMetadata = util.JwtPayloadMetadataName
providers[provider.GetId()] = jp
}
requirements := make(map[string]*jwtpb.JwtRequirement)
for _, rule := range g.AuthConfig.GetRules() {
if len(rule.GetRequirements()) > 0 {
requirements[rule.GetSelector()] = makeJwtRequirement(rule.GetRequirements(), rule.GetAllowWithoutCredential())
}
}
return &jwtpb.JwtAuthentication{
Providers: providers,
RequirementMap: requirements,
}, nil
}