角色认证 authenticators

authenticators

在istiod中对节点身份进行验证,分为两种

  • KubeJWTAuthenticator

  • jwt认证

    authenticators := []authenticate.Authenticator{
        &authenticate.ClientCertAuthenticator{},
        authenticate.NewKubeJWTAuthenticator(s.kubeClient, s.clusterID, s.multicluster.GetRemoteKubeClient, spiffe.GetTrustDomain(), features.JwtPolicy.Get()),
    }

KubeJWTAuthenticator

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") }

if authType := peer.AuthInfo.AuthType(); authType != "tls" {
    return nil, fmt.Errorf("unsupported auth type: %q", authType)
}

tlsInfo := peer.AuthInfo.(credentials.TLSInfo)
chains := tlsInfo.State.VerifiedChains
if len(chains) == 0 || len(chains[0]) == 0 {
    return nil, fmt.Errorf("no verified chain is found")
}

ids, err := util.ExtractIDs(chains[0][0].Extensions)
if err != nil {
    return nil, err
}

return &Caller{
    AuthSource: AuthSourceClientCertificate,
    Identities: ids,
}, nil

}

Last updated