shiro-授权

  授权:也叫访问控制,即在应用中控制谁可以访问哪些资源(如:访问页面、编辑数据、页面操作等)。授权中需要几个关键对象:主机(Subject)、资源(Resource)、权限(Permission)、角色(Role)。

  主体(Subject):访问应用的用户,在shiro中使用Subject代表该用户,用户只有授权后才允许访问相应的资源。

  资源(Resource):在应用中用户可以访问的URL,比如访问的JSP页面、查看/编辑某些数据、访问某个业务方法、打印文本等都是资源。用户只有授权后才可以访问。

  权限(Permission):安全策略中原子授权单位,通过权限可以表示在应用中用户有没有操作某个资源的权利。即权限表示在应用中用户能不能访问某个资源,如:访问用户页面查看/新增/修改/删除用户数据(即很多时候都是CRUD式权限控制)等。权限代表了用户有没有操作某个资源的权利,即反应在某个资源上的操作允不允许。

  角色(Role):权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户拥有一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等,不同的角色拥有一组不同的权限。

一、授权方式:

  1. 编程式:通过if/else授权代码块完成;

  2. 注解式:通过在执行的Java方法上放置相应的注解完成,没有权限将抛出相应的异常;

  3. JSP/GSP标签:在JSP/GSP页面通过相应的标签完成;

二、权限规则:

  1.规则:资源标识符:操作:对象实例ID

    表示对那个资源的哪个实例进行什么操作,其默认支持通配符权限字符串。

    “:”:表示资源/操作/实例的分割。例如:user:query、user:edit

    “,”:表示操作的分割。例如:user:query,edit

    “*”:表示任意资源/操作/实例。例如:user:*、*:query、user:*:*

 三、授权流程:

  1. 首先调用Subjec接口的isRemembered*/方法,岂会委托给SecutityManager,而SecutityManager接着会委托给Authorizer。

  2. Authorizer才是真正的授权者,如果调用isRemembered(“user:view”)方法,首先会通过PermissionResolver接口把字符串转换成相应的Permission接口实例。

  3. 在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限。

  4. Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托ModularRealmAuthorizer进行循环判断,如果匹配Subjec接口的isRemembered()返回true,反正false,授权失败。

四、核心类:

  1. org.apache.shiro.subject.Subject接口:代表着用户,用户所拥有的行为包括:登录、退出、校验权限、获得Session等,符合面向对象,任何与系统交互的行为都可以由Subject完成。


SecurityUtils.getSubject();                   //获取当前正在执行的subject
//权限方法
boolean boolean isPermitted(String permission); //是否拥有权限
boolean[] isPermitted(String... permissions); //是否一组权限,返回boolean[]
boolean isPermittedAll(String... permissions); //全部满足才返回true
boolean isPermittedAll(Collection<Permission> permissions);//全部满足才返回true
//角色方法
boolean hasRole(String roleIdentifier);          //是否拥有角色
boolean[] hasRoles(List<String> roleIdentifiers);    //是否拥有一组角色,返回boolean[]
boolean hasAllRoles(Collection<String> roleIdentifiers);//是否拥有一组角色,全部满足,返回true

  2. org.apache.shiro.authz.Authorizer接口:授权接口

  3. org.apache.shiro.authz.ModularRealmAuthorizer接口:进行多个Realm匹配流程:

    (1.首先检查相应的Realm是否实现了Authorizer。

    (2.如果实现了Authorizer,那么接着调用其他的isPermitted*/hasRole*接口进行匹配。

    (3.如果有一个Realm匹配,那么将返回true,反之false。     

五、权限注解:注解业务层和控制层都可以使用

  1.@RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;即:Subject.isAuthenticated()返回true。

  2. @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录。

  3. @RequiresGuest:表示当前Subject没有身份验证或通过记住我登录过,即:游客身份

  4. @RequiresRoles(value = {"user:a","user:b"},logical = Logical.AND):表示Subject需要角色admin和user

  5. @RequiresPermissions(value = {"user:a","user:b"},logical = Logical.OR):表示Subject需要权限user:a或user:b

原文地址:https://www.cnblogs.com/luliang888/p/11161501.html