本帖最后由 shjava 于 2017-11-28 23:06 编辑
授权,也叫做访问控制。
了解几个关键对象: 主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)
主体:访问应用的对象。 资源:在应用中可以访问的任何东西,jsp页面,方法等都是资源。 权限:安全策略中的原子授权单位,表示用户(主体Subject)有没有权限去访问某个资源。
Shiro支持粗粒度权限和细粒度权限的验证,后续介绍。
角色:代表了权限的集合。 隐式角色:直接通过角色来验证用户有没有操作权限,粒度较粗。 显式角色:通过权限控制访问资源,粒度较细。
google搜索“RBAC”和“RBAC新解”分别了解“基于角色的访问控制”“基于资源的访问控制(Resource-BasedAccess Control)”。
Shiro支持三种方式的权限控制: 1、通过代码完成权限控制 Subject subject = SecurityUtils.getSubject(); if(subject.hasRole("admin")) { //有权限 } else { //无权限 } |
2、通过方法上的注解完成权限控制 @RequiresRoles("admin") public void hello() { //有权限 } |
3、通过JSP页面标签完成权限控制 <shiro:hasRole name="admin"> <!— 有权限 —> </shiro:hasRole> |
授权流程的分析:
授权的流程: 1、当我们需要判断用户是否有权限执行相关的资源时,比如我们调用Subject.isPermitted或者hasRole方法时,Subject会自动委托给SecurityManager。 2、SecurityManager会将授权功能委托给Authorizer进行授权。 3、Authorizer会调用PermissionResolver将我们想要验证的权限字符串转换成对应的Permission实例。 4、在授权之前,会调用相应的Realm获取对应的角色,权限来匹配 5、Authorizer会判断Relam中的角色和权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配到返回true,如果失败返回false
继承了AuthorizingRealm的Realm进行授权的流程: 1、如果调用hasRole,则直接获取AuthorizationInfo.getRoles()与传入角色进行比较。 2、如果调用isPermitted,首先通过PermissionResolver将权限字符串转换为对应Permission对象(默认使用WildcardPermission)。 3、通过AuthorizationInfo.getObjectPermissions()得到Permission实例集合。通过AuthorizationInfo.getStringPermissions()得到字符串集合并通过PermissionResolver解析为Permission实例。 然后获取用户的角色,并通过RolePermissionResolver解析角色对应的权限集合(默认没有实现,可以自己提供)。 4、接着调用Permission.implies(Permission p)逐个与传入的权限比较,如果有匹配的则返回true,否则false。
|