func()

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
}