两种解决方式:(实验可行,)
一、shiro的xml中配置了相关页面的访问权限
xml配置:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" /><!-- login.action -->
<!-- 认证成功之后统一跳转到/index.jsp建议不配置,因为shiro认证成功后会自动跳转到上一个请求路径 -->
<property name="successUrl" value="/first.action"></property><!-- first.action -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/bs/** = anon
/controls/** = anon
/css/** = anon
/image/** = anon
/images/** = anon
/js/** = anon
/META-INF/** = anon
/refuse.jsp = anon
/queryView_findDanger2.action = anon
/login.jsp = anon
/public/** = anon
/login.action = authc
/logout.action = logout
/** = authc
<!-- /** = anon -->
</value>
</property>
前台:
form表单的action
action="<%=path%>/login.action"
以上配置,再每次登录之后会自动执行shiro过滤,自助认证;如果认证失败会跳转以下红框action,在此方法中可以捕获认证失败异常作相应处理。但是,在没有点击退出注销时,再次访问登录页面登录,会登录不上去,并且输入正确用户名、面仍会跳转该action。
作者认为这是因为session中的信息没有清楚造成的,所以作者的解决方式是在失败跳转的action中添加以下处理模块:判断现在输入用户名密码,是否和当前会话中的用户名相同,相同直接进入(关于密码是否正确,action中有捕获异常代码,包含了用户名、密码错误问题;只有通过异常判断的才能走到这一步),不相同,重新调用shiro认证,并重写session。
Subject subject = SecurityUtils.getSubject();
// 获取身份信息
ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
AuthenticationToken token = new UsernamePasswordToken(username,password);
HttpSession session = request.getSession();
if(username!=null) {
if(username.equals(activeUser.getUsercode())) {
return "index";
}else{
subject.login(token);
session.setAttribute("activeUser", activeUser);
return "index";
}
}
二、之前写过一个项目,在xml配置中没有设置认证拦截,登录方法直接跳转自己的逻辑处理模块,再调用shiro的认证方法帮忙认证。这样作可以实现多用户登录,但是必须配置页面对应权限。即便页面没有经过过滤,但是只有具备相关权限的用户才可访问,也可以变相的实现过滤。
还有一种是重写isAccessAllowed方法,这个网上有很多。