4. Shiro授权

shiro权限配置

shiro支持三种授权方式:

  • 编程式:通过写if/else授权代码块完成
  • 注解式:通过在执行的java方法上放置相应的注解完成,没有权限将抛出相应的异常
  • JSP/GSP标签:在JSP/GSP页面通过相应的标签完成

shiro内置了很多默认的拦截器,比如身份验证、授权等相关的。默认的拦截器可以参考org.apache.shiro.web.filter.mgt.DefaultFilter中的枚举拦截器。

【身份验证相关的拦截器】

【授权相关的拦截器】

shiro授权流程分析

  1. 授权需要继承AuthorizingRealm类,并实现其doGetAuthorizationInfo方法;
  2. AuthorizingRealm类继承自AuthenticatingRealm,但没有实现AuthenticatingRealmdoGetAuthenticationInfo,所以认证和授权只需要继承AuthorizingRealm就可以了,同时实现它的两个抽象方法。

如果有多Realm的话,授权通过标准是怎么样的呢?分析源码可以看到,只要有一个Realm授权通过的话就return true:

实现授权Realm

多个Realm配置的时候是有顺序的,所以当我们在Realm获取principals的时候也是有顺序的。

realmPrincipalsPrincipalCollection里面放置principal的属性,它是一个LinkedHashMap,所以放principal是有先后顺序的,一定是先放第一个Realm的principal,再放第二个Realm的principal。

shiro权限注解

  • @RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;即Subject.isAuthenticated()返回true
  • @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的
  • @RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份
  • @RequiresRoles(value={"admin","user"},logical=Logical.AND):表示当前Subject需要角色admin和user
  • @RequiresPermissions(value={"user:a","user:b"}):表示当前Subject需要权限user:a或user:b

【代码示例】

要注意,方法开始的时候会有事务,那么这个时候Service已经是一个代理对象,这个时候把注解加到Service层是不好用的,这个时候需要加到Controller层,就是说不能让Service是代理的代理,否则注入的时候会发生类型转换异常。

推荐阅读更多精彩内容