func (a KubeJWTAuthenticator) Authenticate(ctx context.Context) (Caller, error) { targetJWT, err := extractBearerToken(ctx) if err != nil { return nil, fmt.Errorf("target JWT extraction error: %v", err) } clusterID := extractClusterID(ctx) var id []string
kubeClient := a.GetKubeClient(clusterID)
if kubeClient == nil {
return nil, fmt.Errorf("could not get cluster %s's kube client", clusterID)
}
var aud []string
if !util.IsK8SUnbound(targetJWT) || security.Require3PToken.Get() {
aud = security.TokenAudiences
// TODO: check the audience from token, no need to call
// apiserver if audience is not matching. This may also
// handle older apiservers that don't check audience.
} else {
// No audience will be passed to the check if the token
// is unbound and the setting to require bound tokens is off
aud = nil
}
// 通过tokenreview接口验证客户端token的有效性
id, err = tokenreview.ValidateK8sJwt(kubeClient, targetJWT, aud)
if err != nil {
return nil, fmt.Errorf("failed to validate the JWT from cluster %s: %v", clusterID, err)
}
if len(id) != 2 {
return nil, fmt.Errorf("failed to parse the JWT. Validation result length is not 2, but %d", len(id))
}
callerNamespace := id[0]
callerServiceAccount := id[1]
return &Caller{
AuthSource: AuthSourceIDToken,
Identities: []string{fmt.Sprintf(identityTemplate, a.trustDomain, callerNamespace, callerServiceAccount)},
}, nil
}
ClientCertAuthenticator
func (cca ClientCertAuthenticator) Authenticate(ctx context.Context) (Caller, error) { peer, ok := peer.FromContext(ctx) if !ok || peer.AuthInfo == nil { return nil, fmt.Errorf("no client certificate is presented") }