一、前言
总结上一章节,我们搭建springmvc+mybatis+shrio初级整合。主要步骤web.xml+applicationContext-shiro配置filter,最后实现自己的realm。
我们用到的过滤器配置:
anon org.apache.shiro.web.filter.authc.AnonymousFilter 匿名过滤器 :例子: /js/** anon
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 需要认证过滤器:例子: /admins/user/**=authc
logout org.apache.shiro.web.filter.authc.LogoutFilte 退出过滤器,例子:/logout=logout
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter 权限过滤器,例子:/items/queryItems=perms[item:query]
二、shiro注解
先前看到的都是需要xml配置,现在我们来看看shiro支持的注解权限配置,与jsp标签权限控制。取消url拦截器xml配置, 使用注解才是真正项目实用。。
2.1 注解授权
2.1.1 配置注解的springMVC.xml
1
2
3
4
5
6
7
|
<!-- ========================================shrio=========================================================== -->
<!-- 开启aop,对类代理 -->
<
aop:config
proxy-target-class
=
"true"
></
aop:config
>
<!-- 开启shiro注解支持 -->
<
bean
class
=
"org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"
>
<
property
name
=
"securityManager"
ref
=
"securityManager"
/>
</
bean
>
|
2.1.2 controller注解
的controller的方法头上加注解requiresPermissions注解+权限表达式即可以
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@RequestMapping
(
"/queryItems"
)
@RequiresPermissions
(
"item:query"
)
//表示必须拥有“item:query”权限方可执行。
public
ModelAndView queryItems(javax.servlet.http.HttpServletRequest httpServletRequest,
javax.servlet.http.HttpServletResponse httpServletResponse)
throws
Exception {
//如果是转发:httpServletRequest的数据是可以共享的
//商品列表
List<ItemsCustom> itemsList = itemsService.findtemsList(
null
);
//创建modelAndView准备填充数据、设置视图
ModelAndView modelAndView =
new
ModelAndView();
//填充数据
modelAndView.addObject(
"itemsList"
, itemsList);
//视图
modelAndView.setViewName(
"order/itemsList"
);
return
modelAndView;
}
|
2.2 shirob标签
2.2.1 加入标签url
1
|
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
|
2.2.2 编写jsp页面的标签
这里的标签好比我们的if标签
1
2
3
|
<
shiro:hasPermission
name
=
"item:update"
>
<
td
><
a
href
=
"${pageContext.request.contextPath }/items/editItems?id=${item.id}"
>修改</
a
></
td
>
</
shiro:hasPermission
>
|
标签名称 标签条件(均是显示标签内容)
<shiro:authenticated> 登录之后
<shiro:notAuthenticated> 不在登录状态时
<shiro:guest> 用户在没有RememberMe时
<shiro:user> 用户在RememberMe时
<shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时
<shiro:hasRole name="abc"> 拥有角色abc
<shiro:lacksRole name="abc"> 没有角色abc
<shiro:hasPermission name="abc"> 拥有权限资源abc
<shiro:lacksPermission name="abc"> 没有abc权限资源
<shiro:principal> 显示用户身份名称
<shiro:principal property="username"/> 显示用户身份中的属性值
测试:我们发现我们没有了修改的选项
我们发现我们用注解其实在程序开发的时候已经解决权限问题,但是需要项目经理规定权限命名,个人经验根据数据表名称而定。。。。。。例如:sys_user:update
三、缓存
我们发现授权会频繁查询数据的问题,我们会使用缓存。不能每次查询都查询一次数据库。
3.1 加入缓存jar包
1
2
3
4
5
|
<
dependency
>
<
groupId
>org.apache.shiro</
groupId
>
<
artifactId
>shiro-ehcache</
artifactId
>
<
version
>1.2.4</
version
>
</
dependency
>
|
3.2 配置缓存xml
在applicationContext-shiro.xml中配置缓存管理器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<!-- ==============================================2、安全管理器============================================== -->
<
bean
id
=
"securityManager"
class
=
"org.apache.shiro.web.mgt.DefaultWebSecurityManager"
>
<
property
name
=
"realm"
ref
=
"userRealm"
/>
<!--缓存管理-->
<
property
name
=
"sessionManager"
ref
=
"sessionManager"
/>
<
property
name
=
"cacheManager"
ref
=
"cacheManager"
/>
</
bean
>
<!-- 缓存管理器 -->
<
bean
id
=
"cacheManager"
class
=
"org.apache.shiro.cache.ehcache.EhCacheManager"
>
<
property
name
=
"cacheManager"
value
=
"classpath:cache/ehcache.xml"
/>
</
bean
>
<!-- 会话管理器 -->
<
bean
id
=
"sessionManager"
class
=
"org.apache.shiro.web.session.mgt.DefaultWebSessionManager"
>
<!-- session的失效时长,单位毫秒 -->
<
property
name
=
"globalSessionTimeout"
value
=
"600000"
/>
<!-- 删除失效的session -->
<
property
name
=
"deleteInvalidSessions"
value
=
"true"
/>
</
bean
>
|
ehcache.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
ehcache
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation
=
"http://ehcache.org/ehcache.xsd"
>
<!--diskStore:缓存数据持久化的目录 地址 -->
<
diskStore
path
=
"F:\ycydevelop\ehcache"
/>
<
defaultCache
maxElementsInMemory
=
"1000"
maxElementsOnDisk
=
"10000000"
eternal
=
"false"
overflowToDisk
=
"false"
diskPersistent
=
"true"
timeToIdleSeconds
=
"120"
timeToLiveSeconds
=
"120"
diskExpiryThreadIntervalSeconds
=
"120"
memoryStoreEvictionPolicy
=
"LRU"
>
</
defaultCache
>
</
ehcache
>
|
3.3 及时生效缓存
在我们自定义的realm里面定义清除缓存,即是生效。一般在我们的service方法里面调用,为了保证权限及时性。
1
2
3
4
|
public
void
clearCached() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super
.clearCache(principals);
}
|
3.4 缓存总结
新版shiro的缓存无论是否正常退出,都会清空缓存。一定要记住修改权限数据之后,要情况缓存。到后面我们用radis的时候可以用缓存框架来实现cacheDao另说