in pkg/authority/k8s/client.go [217:298]
func (c *ClientImpl) VerifyServiceAccount(token string, authorizationType string) (*rule.Endpoint, bool) {
var tokenReview *k8sauth.TokenReview
if authorizationType == "dubbo-ca-token" {
tokenReview = &k8sauth.TokenReview{
Spec: k8sauth.TokenReviewSpec{
Token: token,
Audiences: []string{"dubbo-ca"},
},
}
} else {
tokenReview = &k8sauth.TokenReview{
Spec: k8sauth.TokenReviewSpec{
Token: token,
},
}
}
reviewRes, err := c.kubeClient.AuthenticationV1().TokenReviews().Create(
context.TODO(), tokenReview, metav1.CreateOptions{})
if err != nil {
logger.Sugar().Warnf("Failed to validate token. " + err.Error())
return nil, false
}
if reviewRes.Status.Error != "" {
logger.Sugar().Warnf("Failed to validate token. " + reviewRes.Status.Error)
return nil, false
}
names := strings.Split(reviewRes.Status.User.Username, ":")
if len(names) != 4 {
logger.Sugar().Warnf("Token is not a pod service account. " + reviewRes.Status.User.Username)
return nil, false
}
namespace := names[2]
podName := reviewRes.Status.User.Extra["authentication.kubernetes.io/pod-name"]
podUid := reviewRes.Status.User.Extra["authentication.kubernetes.io/pod-uid"]
if len(podName) != 1 || len(podUid) != 1 {
logger.Sugar().Warnf("Token is not a pod service account. " + reviewRes.Status.User.Username)
return nil, false
}
pod, err := c.kubeClient.CoreV1().Pods(namespace).Get(context.TODO(), podName[0], metav1.GetOptions{})
if err != nil {
logger.Sugar().Warnf("Failed to get pod. " + err.Error())
return nil, false
}
if pod.UID != types.UID(podUid[0]) {
logger.Sugar().Warnf("Token is not a pod service account. " + reviewRes.Status.User.Username)
return nil, false
}
e := &rule.Endpoint{}
e.ID = string(pod.UID)
for _, i := range pod.Status.PodIPs {
if i.IP != "" {
e.Ips = append(e.Ips, i.IP)
}
}
e.SpiffeID = "spiffe://cluster.local/ns/" + pod.Namespace + "/sa/" + pod.Spec.ServiceAccountName
if strings.HasPrefix(reviewRes.Status.User.Username, "system:serviceaccount:") {
names := strings.Split(reviewRes.Status.User.Username, ":")
if len(names) == 4 {
e.SpiffeID = "spiffe://cluster.local/ns/" + names[2] + "/sa/" + names[3]
}
}
e.KubernetesEnv = &rule.KubernetesEnv{
Namespace: pod.Namespace,
PodName: pod.Name,
PodLabels: pod.Labels,
PodAnnotations: pod.Annotations,
}
return e, true
}