shiro(六)授权

1自定义realm中的授权方法

public class CustomRealm1 extends AuthorizingRealm {

	@Autowired
	private SysService sysService;

	@Override
	public String getName() {
		return "customRealm";
	}

	// 支持什么类型的token
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof UsernamePasswordToken;
	}


	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		
		//身份信息
		ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
		//用户id
		String userid = activeUser.getUserid();
		//获取用户权限
		List<SysPermission> permissions = null;
		try {
			permissions = sysService.findSysPermissionList(userid);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//构建shiro授权信息
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		for(SysPermission sysPermission:permissions){
			simpleAuthorizationInfo.addStringPermission(sysPermission.getPercode());
		}
		
		return simpleAuthorizationInfo;
		
	}

}

2)多controller开启AOP

springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置权限:

<!-- 开启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>

3)注解权限控制

商品查询controller方法添加权限(item:query):

// 查询商品列表
	@RequestMapping("/queryItem")
	@RequiresPermissions("item:query")
	public ModelAndView queryItem() throws Exception {

上边代码@RequiresPermissions("item:query")表示必须拥有item:query”权限方可执行。

 同理,商品修改controller方法添加权限(item:update):

@RequestMapping(value = "/editItem")
	@RequiresPermissions("item:update")
	public String editItem(@RequestParam(value = "id", required = true) Integer id, Model model) throws Exception

// 商品修改提交
	@RequestMapping("/editItemSubmit")
	@RequiresPermissions("item:update")
	public String editItemSubmit(@ModelAttribute("item") Items items,BindingResult result,
			MultipartFile pictureFile,Model model,HttpServletRequest request)
			throws Exception

4)jsp标签控制

Jsp页面添加:

<%@ tagliburi="http://shiro.apache.org/tags" prefix="shiro" %>

标签名称

标签条件(均是显示标签内容)

<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"/>     显示用户身份中的属性值

如果有商品修改权限页面显示“修改”链接。

<shiro:hasPermission name="item:update">
	<a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a>
	</shiro:hasPermission>

二,缓存

shiro每次授权都会通过realm获取权限信息,为了提高访问速度需要添加缓存,第一次从realm中读取权限数据,之后不再读取,这里ShiroEhcache整合

1)添加Ehcachejar


2) 配置cacheManager

applicationContext-shiro.xml中配置缓存管理器。

<!-- 安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="userRealm" />
		<property name="cacheManager" ref="cacheManager"/>
	</bean>

<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    	<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
    </bean>

3) 配置shiro-ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="shirocache">

    <diskStore path="d:\cache"/>
	<defaultCache

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="120"

        timeToLiveSeconds="120"

        overflowToDisk="true"

        />
    <!-- 登录记录缓存 锁定60秒 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="60"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-activeSessionCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
	<!--diskStore:缓存数据持久化的目录 地址  -->
	<diskStore path="F:\develop\ehcache" />
	<defaultCache 
		maxElementsInMemory="1000" 
		maxElementsOnDisk="10000000"
		eternal="false" 
		overflowToDisk="false" 
		diskPersistent="false"
		timeToIdleSeconds="120"
		timeToLiveSeconds="120" 
		diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
	</defaultCache>
</ehcache>

4)清空缓存

当用户权限修改后,用户再次登陆shiro会自动调用realm从数据库获取权限数据,如果在修改权限后想立即清除缓存则可以调用realmclearCache方法清除缓存。realm中定义clearCached方法:

//清除缓存
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}

5)session管理

applicationContext-shiro.xml中配置sessionManager

<!-- 安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="userRealm" />
		<property name="sessionManager" ref="sessionManager" />
	</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>

 验证码   自定义FormAuthenticationFilter

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
	protected boolean onAccessDenied(ServletRequest request,
			ServletResponse response, Object mappedValue) throws Exception {

		// 校验验证码
		// 从session获取正确的验证码
		HttpSession session = ((HttpServletRequest)request).getSession();
		//页面输入的验证码
		String randomcode = request.getParameter("randomcode");
		//从session中取出验证码
		String validateCode = (String) session.getAttribute("validateCode");
		if (randomcode!=null && validateCode!=null) {
			if (!randomcode.equals(validateCode)) {
				// randomCodeError表示验证码错误 
				request.setAttribute("shiroLoginFailure", "randomCodeError");
				//拒绝访问,不再校验账号和密码 
				return true; 
			}
		}
		return super.onAccessDenied(request, response, mappedValue);
	}
}

1) FormAuthenticationFilter配置

修改applicationContext-shiro.xml中对FormAuthenticationFilter的配置。

n 在shiroFilter中添加filters

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="filters">
			<map>
				<!-- FormAuthenticationFilter是基于表单认证的过虑器 -->
				<entry key="authc" value-ref="formAuthenticationFilter" />
			</map>
		</property>
.....
.....

n formAuthenticationFilter定义

<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
	<bean id="formAuthenticationFilter" 
	class="org.apache.shiro.web.filter.authc.MyFormAuthenticationFilter ">
		<!-- 表单中账号的input名称 -->
		<property name="usernameParam" value="username" />
		<!-- 表单中密码的input名称 -->
		<property name="passwordParam" value="password" />
 </bean>

2) 登陆页面

添加验证码:
<TR>
							<TD>验证码:</TD>
							<TD><input id="randomcode" name="randomcode" size="8" /> <img
								id="randomcode_img" src="${baseurl}validatecode.jsp" alt=""
								width="56" height="20" align='absMiddle' /> <a
								href=javascript:randomcode_refresh()>刷新</a></TD>
						</TR>
3)   配置validatecode.jsp匿名访问

修改applicationContext-shiro.xml



四,记住我

用户登陆选择“自动登陆”本次登陆成功会向cookie写身份信息,下次登陆从cookie中取出身份信息实现自动登陆。

1) 用户身份实现 java.io.Serializable 接口




2)配置rememberMeManager

<!-- 安全管理器 -->
	<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"/>
		<!-- 记住我 -->
		<property name="rememberMeManager" ref="rememberMeManager"/>
	</bean>

<!-- rememberMeManager管理器 -->
	<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
		<property name="cookie" ref="rememberMeCookie" />
	</bean>
	<!-- 记住我cookie -->
	<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
		<constructor-arg value="rememberMe" />
		<!-- 记住我cookie生效时间30天 -->
		<property name="maxAge" value="2592000" />
	</bean>
3)   FormAuthenticationFilter配置

修改formAuthenticationFitler添加页面中“记住我checkbox”的input名称:

<bean id="formAuthenticationFilter"
		class="cn.itcast.ssm.shiro.MyFormAuthenticationFilter">
		<!-- 表单中账号的input名称 -->
		<property name="usernameParam" value="usercode" />
		<!-- 表单中密码的input名称 -->
		<property name="passwordParam" value="password" />
		<property name="rememberMeParam" value="rememberMe"/>
	</bean>

4)登录页面

login.jsp中添加“记住我”checkbox


<TR>
							<TD></TD>
							<TD>
							<input type="checkbox" name="rememberMe" />自动登陆
							</TD>
						</TR>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值