Spring中集成Shiro授权实例

来源:互联网 发布:私募投资软件 编辑:程序博客网 时间:2024/06/07 03:44

授权流程回顾

首先说一句,使用授权的前提当然是先要实现身份验证,也就是要保证用户登录之后才可能考虑授权的问题。关于身份验证之前已经写过了,还不清楚的童鞋可以点这里

上一篇文章介绍了Shiro中授权的一些基础知识和原理。学了就要用,本篇文章就介绍如何在项目中应用Shiro的授权。这里为了方便大家阅读,先贴出上一篇文章中分析出的授权流程:

  1. 当我们调用Subject.hasRole(...)
  2. 首先会委托给securityManager来处理,而securityManager内部有一个Authorizer来做真正的授权,默认实现为ModularRealmAuthorizer
  3. ModularRealmAuthorizer可以根据多个Realm来判断是否拥有相应的角色,其中只要某个Realm匹配,则返回true
  4. AuthorizingRealm对于判断hasRole的逻辑也很简单(这里的AuthorizationInfo是通过覆盖doGetAuthorizationInfo(PrincipalCollection principals)方法来得到的)
    protected boolean hasRole(String roleIdentifier, AuthorizationInfo info) {        return info != null && info.getRoles() != null && info.getRoles().contains(roleIdentifier);    }

而对于Subject.isPermitted(...)稍微会显得复杂一些,前三步都一样,就是AuthorizingRealm对于判断isPermitted的逻辑稍微有点不一样。它会先将权限字符串转换成Permission,将用户的权限转换成List<Permission>,这里的List<Permission>由三个部分组成:

  • 通过AuthorizationInfo.getObjectPermissions()得到Permission实例集合
  • 通过AuthorizationInfo. getStringPermissions()得到字符串集合并通过PermissionResolver解析为Permission实例
  • 然后获取用户的角色,并通过RolePermissionResolver解析角色对应的权限集合(默认没有实现,可以自己提供)

接下来,用PermissionList进行匹配,其中遍历用户权限的匹配方法就是implies(...),这个单词可以理解成“蕴含”的意思,这样就比较好理解了。

由于各组件角色定位都很清楚,所以我们这里实现授权只需要实现AuthorizingRealm就可以了。那么Shiro是否有线程的AuthorizingRealm供我们使用呢?答案是肯定的。AuthorizingRealm的实现有:JdbcRealmInitRealmPropertiesRealm等。由于我决定将授权数据存在数据库中(大多数情况也应该是这样),所以这里使用JdbcRealm。注意:下文直接用细粒度的模式来实现授权(即用户到角色,角色关联到权限的方式)

准备工作

首先,我们要建两张表,一张是用户到角色的关联表,一张的角色到权限的关联表。

  • 首先是用户到角色的关联表 user_roles
id username role_name
  • 然后是角色到权限关联表 roles_permissions
id role_name permission

配置Shiro

Shiro提供了两个可配置的SQL语句来取得某用户的所有权限:userRolesQuerypermissionsQuery,其中userRolesQuery是用来得到该用户的所有角色,而permissionsQuery是根据该用户的所有角色来取出所有的权限。这里我们配置的SQL为:

userRolesQuery= select role_name from user_roles where username = ?permissionsQuery = select permission from roles_permissions where role_name = ?

这也是Shiro提供的默认的SQL内容,由于我们表名和列名都是参照该SQL建立的,所以直接使用默认的SQL即可。

另外还有一点需要注意的是,JdbcRealm默认是不支持权限查找的,也就是permissionsQuery默认是不会执行的。需要配置permissionsLookupEnabledtrue,才能使之生效。另外别忘了配置数据源datasource,下面贴上配置文件:

    <bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">        <property name="credentialsMatcher" ref="credentialsMatcher"></property>        <property name="authenticationQuery" value="select password from user where username = ?"></property>        <property name="dataSource" ref="dataSource"></property>        <property name="permissionsLookupEnabled" value="true"></property>    </bean>

使用授权

配置好后就可以像上一篇文章里写的那样使用了:
比如我们在Controller中写一个方法

    @RequiresPermissions("news:view")    @RequestMapping("/newsList")    public String newsList() {        return "newsList";    }

当该用户没有news:view权限时,就会抛出UnauthorizedException异常,我们捕获该类异常并提供“未授权”页面返回给用户。在Spring中是可以配置一个全局的ExceptionHandler的。当然在Spring3.2之后的版本还提供了@ControllerAdvice来增强Controller,其中定义的所有@ExceptionHandler方法将会应用于所有的@RequestMapping方法,那么我们可以这么来定义异常处理类:

@ControllerAdvicepublic class DefaultExceptionHandler {    @ExceptionHandler( { UnauthorizedException.class })    @ResponseStatus(HttpStatus.UNAUTHORIZED)    public ModelAndView processUnauthorizedException(            NativeWebRequest request, UnauthorizedException e) {        ModelAndView mv = new ModelAndView();        mv.addObject("contextPath", request.getContextPath());        mv.addObject("exception", e);        mv.setViewName("special/unauthorized");        return mv;    }}

这里若启用声明式的鉴权,还需要启用aspectJ自动代理,并支持对类的代理。

    <aop:aspectj-autoproxy proxy-target-class="true" />    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">        <property name="securityManager" ref="securityManager" />    </bean>
3 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 签了合同上两天班想辞职怎么办 刚到公司上班两天想辞职怎么办 签入职合同一天后就不想干了怎么办 入职材料交了第二天就想离职怎么办 宝宝40周多了还不想出来怎么办 工厂上班不到三个月不给辞工怎么办 单位辞职后不上班了保险怎么办 药流6个小时没流下来怎么办 小孩有口臭怎么办这几天不想吃饭 七个月宝宝口臭不想吃饭怎么办啊 老公工作累想要辞职不上班怎么办 药物流产后第6天咋下坠的怎么办 药流第一天胎囊没有掉下来怎么办 药流还有一点没流干净怎么办 3个月的宝宝被电了一下怎么办 宝宝吃奶粉过敏下巴红有疙瘩怎么办 小孩牙齿没掉又长出新牙怎么办 8个月婴儿地包天怎么办 欠别人很多钱 要告我怎么办 ps意外的遇到文件尾损坏了怎么办 长期作息不规律引起的头疼怎么办 退休年龄到了社保没满15年怎么办 要退休了单位把我工资表丢了怎么办 非工伤单位不支付病假工资怎么办 十个月宝宝咳嗽有痰怎么办崔玉涛 怀孕五个月胎儿脐带绕颈怎么办 6个月宝宝白天睡眠不好怎么办 22个月宝宝身高才79公分怎么办 宝宝十个月了还没长牙怎么办 腰椎间盘突出翻身都困难了怎么办 上课很困怎么办犯困快速清醒的绝招 孩子上小学放学早父母上班怎么办 想玩滑冰鞋的手受伤了怎么办? 美团酒店商家入住没审核通过怎么办 顺丰离职人员被列入黑名单怎么办 洗了衣服晾起来衣服被拉长了怎么办 宝宝拉肚子半个月了还不好怎么办 宝宝咳嗽半个月了还不好怎么办 顾客试了一大堆衣服不买怎么办 宝宝屁屁用尿布捂的红的怎么办? 车被别人撞了人跑了怎么办