3.6 rbac类型的Authorization鉴权

news/2025/1/31 21:17:30 标签: 贪心算法, 算法

本节重点总结 :

  • rbac模型四种对象的关系
    • role,clusterrole
    • rolebinding,clusterrolebinding
  • role、clusterrole中的rules规则
    • 资源对象
    • 非资源对象
    • apiGroups
    • verb动作
  • rbac鉴权的代码逻辑
    • 通过informer获取clusterRoleBindings列表,根据user匹配subject,通过informer获取clusterRoleBindings的rules,遍历调用visit进行rule匹配
    • 通过informer获取RoleBindings列表,根据user和namespace匹配subject,,通过informer获取RoleBindings的rules,遍历调用visit进行rule匹配

rbac鉴权模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 文档地址 https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

简介

  • 基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。
  • RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组 来驱动鉴权决定,允许你通过 Kubernetes API 动态配置策略。

看文档介绍

源码解读

  • 入口 D:\go_path\src\github.com\kubernetes\kubernetes\pkg\kubeapiserver\authorizer\config.go
		case modes.ModeRBAC:
			rbacAuthorizer := rbac.New(
				&rbac.RoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister()},
				&rbac.RoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister()},
				&rbac.ClusterRoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoles().Lister()},
				&rbac.ClusterRoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoleBindings().Lister()},
			)
			authorizers = append(authorizers, rbacAuthorizer)
			ruleResolvers = append(ruleResolvers, rbacAuthorizer)

rbac.New 传入Role、ClusterRole、RoleBinding 和 ClusterRoleBinding 4种对象的Getter

func New(roles rbacregistryvalidation.RoleGetter, roleBindings rbacregistryvalidation.RoleBindingLister, clusterRoles rbacregistryvalidation.ClusterRoleGetter, clusterRoleBindings rbacregistryvalidation.ClusterRoleBindingLister) *RBACAuthorizer {
	authorizer := &RBACAuthorizer{
		authorizationRuleResolver: rbacregistryvalidation.NewDefaultRuleResolver(
			roles, roleBindings, clusterRoles, clusterRoleBindings,
		),
	}
	return authorizer
}
  • 构建DefaultRuleResolver,并用DefaultRuleResolver构建RBACAuthorizer

RBACAuthorizer的Authorize解析

  • 核心判断点在ruleCheckingVisitor的allowed标志位,如果为true,则通过,否则就不通过
func (r *RBACAuthorizer) Authorize(ctx context.Context, requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
	ruleCheckingVisitor := &authorizingVisitor{requestAttributes: requestAttributes}

	r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit)
	if ruleCheckingVisitor.allowed {
		return authorizer.DecisionAllow, ruleCheckingVisitor.reason, nil
	}
    return authorizer.DecisionNoOpinion, reason, nil
}
  • 这个allowed标志位只有在visit方法中才会被设置,条件是RuleAllows=true
func (v *authorizingVisitor) visit(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool {
	if rule != nil && RuleAllows(v.requestAttributes, rule) {
		v.allowed = true
		v.reason = fmt.Sprintf("RBAC: allowed by %s", source.String())
		return false
	}
	if err != nil {
		v.errors = append(v.errors, err)
	}
	return true
}

VisitRulesFor调用visit方法校验每一条rule

r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit)

先校验clusterRoleBinding

  • 具体流程先用informer获取 clusterRoleBindings,出错了就校验失败,因为传给visitor的rule为nil就意味着allowed不会被设置为true
	if clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings(); err != nil {
		if !visitor(nil, nil, err) {
			return
		}
	}
  • 然后遍历clusterRoleBindings
先根据传入的user对象对比subject主体
	for _, clusterRoleBinding := range clusterRoleBindings {
			subjectIndex, applies := appliesTo(user, clusterRoleBinding.Subjects, "")
			if !applies {
				continue
			}
appliesToUser对比函数
  • 根据user类型判断
    • 如果是普通用户就判断名字
    • 如果是group就判断 里面的user名字
    • 如果是ServiceAccount就要用serviceaccount.MatchesUsername对比
func appliesToUser(user user.Info, subject rbacv1.Subject, namespace string) bool {
	switch subject.Kind {
	case rbacv1.UserKind:
		return user.GetName() == subject.Name

	case rbacv1.GroupKind:
		return has(user.GetGroups(), subject.Name)

	case rbacv1.ServiceAccountKind:
		// default the namespace to namespace we're working in if its available.  This allows rolebindings that reference
		// SAs in th local namespace to avoid having to qualify them.
		saNamespace := namespace
		if len(subject.Namespace) > 0 {
			saNamespace = subject.Namespace
		}
		if len(saNamespace) == 0 {
			return false
		}
		// use a more efficient comparison for RBAC checking
		return serviceaccount.MatchesUsername(saNamespace, subject.Name, user.GetName())
	default:
		return false
	}
}
  • serviceaccount.MatchesUsername对比 serviceaccount的全名 system:serviceaccount:namespace:name
  • 逐次进行对比
// MatchesUsername checks whether the provided username matches the namespace and name without
// allocating. Use this when checking a service account namespace and name against a known string.
func MatchesUsername(namespace, name string, username string) bool {
	if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) {
		return false
	}
	username = username[len(ServiceAccountUsernamePrefix):]

	if !strings.HasPrefix(username, namespace) {
		return false
	}
	username = username[len(namespace):]

	if !strings.HasPrefix(username, ServiceAccountUsernameSeparator) {
		return false
	}
	username = username[len(ServiceAccountUsernameSeparator):]

	return username == name
}

再根据clusterRoleBinding.RoleRef从informer获取rules
rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
遍历rule,传入找到的clusterRoleBinding,调用visit进行比对
			sourceDescriber.binding = clusterRoleBinding
			sourceDescriber.subject = &clusterRoleBinding.Subjects[subjectIndex]
			for i := range rules {
				if !visitor(sourceDescriber, &rules[i], nil) {
					return
				}
			}
资源型
  • 对比request和rule的verb是否一致
func VerbMatches(rule *rbacv1.PolicyRule, requestedVerb string) bool {
	for _, ruleVerb := range rule.Verbs {
		if ruleVerb == rbacv1.VerbAll {
			return true
		}
		if ruleVerb == requestedVerb {
			return true
		}
	}

	return false
}
非资源型的
  • 对比request和rule的url和verb
func NonResourceURLMatches(rule *rbacv1.PolicyRule, requestedURL string) bool {
	for _, ruleURL := range rule.NonResourceURLs {
		if ruleURL == rbacv1.NonResourceAll {
			return true
		}
		if ruleURL == requestedURL {
			return true
		}
		if strings.HasSuffix(ruleURL, "*") && strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
			return true
		}
	}

	return false
}

再校验RoleBinding

通过informer获取roleBinding列表
		if roleBindings, err := r.roleBindingLister.ListRoleBindings(namespace); err != nil {
			if !visitor(nil, nil, err) {
				return
			}
遍历对比subject
  • 一样的appliesTo判断subject
			for _, roleBinding := range roleBindings {
				subjectIndex, applies := appliesTo(user, roleBinding.Subjects, namespace)
				if !applies {
			
根据informer获取匹配到的roleBinding的rules对象
				rules, err := r.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
				if err != nil {
					if !visitor(nil, nil, err) {
						return
					}
					continue
				}
调用visit方法遍历rule进行匹配
  • 如果匹配中了,allowed置为true
				sourceDescriber.binding = roleBinding
				sourceDescriber.subject = &roleBinding.Subjects[subjectIndex]
				for i := range rules {
					if !visitor(sourceDescriber, &rules[i], nil) {
						return
					}
				}

本节重点总结 :

  • rbac模型四种对象的关系
    • role,clusterrole
    • rolebinding,clusterrolebinding
  • role、clusterrole中的rules规则
    • 资源对象
    • 非资源对象
    • apiGroups
    • verb动作
  • rbac鉴权的代码逻辑
    • 通过informer获取clusterRoleBindings列表,根据user匹配subject,通过informer获取clusterRoleBindings的rules,遍历调用visit进行rule匹配
    • 通过informer获取RoleBindings列表,根据user和namespace匹配subject,,通过informer获取RoleBindings的rules,遍历调用visit进行rule匹配

http://www.niftyadmin.cn/n/5838872.html

相关文章

课题推荐:基于matlab,适用于自适应粒子滤波的应用

自适应粒子滤波(Adaptive Particle Filter, APF)是一种用于状态估计的有效方法,特别适用于非线性和非高斯系统。 文章目录 应用场景MATLAB 代码示例代码说明结果扩展说明 以下是一个基于自适应粒子滤波的简单应用示例,模拟一个一维…

5.3.2 软件设计原则

文章目录 抽象模块化信息隐蔽与独立性衡量 软件设计原则:抽象、模块化、信息隐蔽。 抽象 抽象是抽出事物本质的共同特性。过程抽象是指将一个明确定义功能的操作当作单个实体看待。数据抽象是对数据的类型、操作、取值范围进行定义,然后通过这些操作对数…

LabVIEW微位移平台位移控制系统

本文介绍了基于LabVIEW的微位移平台位移控制系统的研究。通过设计一个闭环控制系统,针对微位移平台的通信驱动问题进行了解决,并提出了一种LabVIEW的应用方案,用于监控和控制微位移平台的位移,从而提高系统的精度和稳定性。 项目背…

linux的/proc 和 /sys目录差异

/proc 和 /sys 都是Linux系统中用于提供系统信息和进行系统配置的虚拟文件系统,但它们的原理并不完全一样,以下是具体分析: 目的与功能 /proc :主要用于提供系统进程相关信息以及内核运行时的一些参数等,可让用户和程…

Bash 基础与进阶实践指南

目录 Bash 简介与基础基本命令与文件操作权限管理与用户管理重定向与管道变量与环境变量通配符与正则表达式Shell 脚本结构与控制流常用内建命令与技巧文本处理常用命令作业控制与进程管理别名与函数实用技巧与注意事项更多 Bash 进阶话题参考资源 1. Bash 简介与基础 1.1 什…

MacOS 如何映射快捷键

MacOS 如何映射快捷键 背景步骤说明映射示例 背景 参考文档 macOS Sequoia 现在要求热键注册至少使用一个非 shift 或 option 的修饰符,对于原来使用快捷键 option * 的功能无法使用。通过软件 karabiner-element.app 做键盘映射,可以实现原有功能继续…

[EAI-027] RDT-1B,目前最大的用于机器人双臂操作的机器人基础模型

Paper Card 论文标题:RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者:Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接:https://arxiv.org/ab…

如何批量注册运营大量(X)Twitter账号?推特多账号防关联攻略!

Twitter(推特),现更名为”X”,作为全球最受欢迎的社交媒体平台之一,其用户群体遍布世界各地,越来越多的跨境玩家和社媒营销人员也将其纳入海外社媒运营矩阵中。然而,很多人在注册完Twitter账号后…