上一篇文章中我们介绍的权限控制方案的实现方式是通过URL拦截实现的,这里介绍通过shiro实现权限控制。shiro是apache下的开源的权限管理框架。
Subject:主体,是用户和程序的统一抽象。
SecurityManager:安全管理器,认证和授权的核心处理类。
Authenticator:认证器,主体认证的处理类。
Authorizer:授权器,主体授权的处理类。
SessionManager:shiro提供的一套session管理机制。
SessionDao:对于session的存储需要用到sessionDao。
CacheManager;缓存管理器,主要对session和相关数据进行缓存管理。
Realm:通过realm间接连接数据源,认证和授权需要通过realm存取认证和授权数据。
Cryptography:密码管理器,shiro提供的一套加密解密组建。
1、通过shiro默认的IniRealm实现(开发中一般不用该方式),该方式需要将认证和授权信息配置在一个ini文件中,shiro会默认通过IniRealm读取该文件信息,实现认证。
2、通过自定义Realm实现(一般都需要自定义Realm),自定义的Realm可以自定义认证和授权信息获取的方式(例如从数据库中查询),自定义的Realm继承AuthorizingRealm。
这里主要介绍通过自定义Realm实现认证和授权的方式。下面通过将shiro整合到项目中的过程来介绍shiro的基本用法和shiro的工作原理。
1、添加jar包
主要包括:shiro和spring整合的jar包,shiro和web应用整合的jar包和shiro一些基本的包。
2、配置shiro的filter
上篇文章我们介绍通过URL拦截中用到了拦截器,shiro内部也是用到了filter拦截进行实现。
配置信息:
3、applicationContext-shiro.xml
在applicationContext-shiro.xml中配置shiroFilter需要的Bean及其他相关配置。
4、认证:
实现原理:由上边的配置可知,当用户进行认证时,会去请求loginurl进行认证,中间FormAuthenticationFilter进行拦截,取出request中携带的username和password参数(注:这里默认为username和password,也可以自行配置),FormAuthenticationFilter会调用realm(自定义的吗?)进行认证,同时传给realm一个token参数,username和password封装在token中,realm会根据username查询用户信息,如果查询到则返回,如果查询不到则会返回null,这时FormAuthenticationFilter会向request中设置异常参数和信息。
5、登出
对于登出可以不用去实现具体的退出操作,只需要访问一个指定的登出的url,因为中间会由LogoutFilter拦截,同时清除session数据。配置方式见applicationContext-shiro.xml中的logout配置
6、授权配置
说明:对于shiro的授权配置有三种方法:
1、通过配置文件进行配置。
2、通过注解进行配置。
3、通过jsp标签进行配置。
对于配置文件的配置方式见applicationContext-shiro.xml中的授权配置部分。
实现原理为:在用户请求到/users/deleteUser.action时会被PermissionsAuthorizationFilter拦截,filter根据配置发现需要“item:query”权限,这时PermissionAuthorizationFilter会调用realm从数据库中获取权限信息,如果发现用户拥有该权限会放行,如果发现没有会转到前边配置中指定的refuse.jsp页面。
7、权限判断
8、设置凭证匹配器
由于在数据库中存放的密码是经过加密算法的散列值,所以在shiro也需要对取到的密码进行相同的加密算法才能进行密码比对,这里通过在配置文件中配置的凭证匹配器对加密算法进行配置,对于凭证匹配器的配置见applicationContext-shiro.xml。
上边对于授权的方式我们使用的是通过配置文件进行实现的,但是这样的缺点在,URL和对应的权限成对配置,这样将造成很大的配置量,相对来说比较麻烦;下边我们说明一下如何通过注解的方式进行配置。
上边介绍了对于shiro的授权配置有三种方式,上边的方式是通过配置文件的方式实现的,下边介绍一下如何通过注解方式和jsp标签方式进行授权配置。
开启注解:
由于注解方式内部使用了spring的AOP方式,所以需要首先开启spring的AOP,同时开启shiro的注解支持。配置如下:
注解使用:
注解的使用方式为,在需要进行权限控制的方法上添加相应注解,注解的写法为:
@RequiresPermissions(“users:delete”),表示执行此方法需要“users:delete”权限。
对于通过jsp标签实现授权需要引入shiro的自定义标签
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
标签使用:shiro提供的标签很多,这里介绍其中几个:
1、认证成功后可以显示的内容放在
2、当用户有指定角色时才显示的内容放在
3、当用户有指定的权限时才显示的内容放在<shiro:hasPermission name="item:query">内
在实际应用当中,通过注解和jsp标签的方式相对多些。
对于上边的使用,无论是通过何种方式配置的权限,存在一个较大的问题是,对于权限的判断,每次都需要realm从数据库中查询权限信息进行比对,这样对系统的性能消耗是很大的,为了解决该问题,我们为shiro引入缓存处理,这样就只需要在用户第一次访问时去查询数据库,再后边就可以直接从缓存中取,这里使用的是ehcache。
1、添加ehcache的jar包。
2、配置cacheManager,需要将cacheManager注入到securityManager中,对于相关配置见applicationContext-shiro.xml。
3、创建shiro-ehcache.xml,定义ehcache的使用方案,具体配置如下:
shiro提供了在用户退出后缓存的自动清空处理,然而,在用户登录期间对用户的缓存进行更新处理,需要调用realm的clearCached方法对缓存进行清空。
对于利用shiro对权限的控制和前边基于URL拦截的控制进行对比来说,shiro的控制功能更加强大一些,但是对于框架的依赖性大些,虽然shiro本身是不依赖与其他框架的,但是这里和项目整合还是依赖了spring框架,在使用shiro时如果使用注解的方式进行权限控制会更加方便和直观。这里主要介绍了shiro和项目整合中的基本用法,其中对于认证和授权的流程在后边进行介绍,这些只是shiro的一些基本用法,对于shiro的其他应用特点还有待继续了解和学习,也希望这篇文章可以对你有所帮助吧。