Shiro的验证机制 和同一浏览器 多次登录的BUG

Shiro同时登陆多个账户异常

关于一个浏览器同时登陆多个账户,自动跳转到原登录页面的逻辑错误。
方法1

对shiro源码进行了调试,发现是AuthenticationFilter验证逻辑的问题:
1.它首先验证是否有允许访问页面(isAccessAllowed方法)。
2.在拒绝访问中(FormAuthenticationFilter的onAccessDenied方法)才会进行判断是否是登录提交(isLoginSubmission)。

因为已经登陆了一个用户所以isAccessAllowed直接返回为true,进入LoginController,找到匹配方法fail直接返回LOGIN_PAGE。
由于有权限访问该登录(其他)页面FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME没有值,返回为Null,所以在
keta-security中会跳转到login页面并且显示"登陆失败,其他错误!"。

分析、修改逻辑,首先验证是否是登录操作,再进行验证是否有权限访问页面。继承FormAuthenticationFilter,覆盖isAccessAllowed方法。

01 /**
02  
03  * @author  <a href="mailto:ketayao@gmail.com">ketayao</a>
04  * Version  1.1.0
05  * @since   2012-10-29 上午9:37:02
06  */
07   
08 public class BaseFormAuthenticationFilter extends FormAuthenticationFilter {
09     private static final Logger log = LoggerFactory.getLogger(BaseFormAuthenticationFilter.class);
10       
11     /**
12      *
13      * @param request
14      * @param response
15      * @param mappedValue
16      * @return 
17      * @see org.apache.shiro.web.filter.authc.AuthenticatingFilter#isAccessAllowed(javax.servlet.ServletRequest, javax.servlet.ServletResponse, java.lang.Object)
18      */
19     @Override
20     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
21         try {
22             // 先判断是否是登录操作
23             if (isLoginSubmission(request, response)) {
24                 if (log.isTraceEnabled()) {
25                     log.trace("Login submission detected.  Attempting to execute login.");
26                 }
27                 return false;
28             }
29         catch (Exception e) {
30             log.error(Exceptions.getStackTraceAsString(e));
31         }
32   
33         return super.isAccessAllowed(request, response, mappedValue);
34     }
35 }


方法2

  • 在loginUrl页面判断用户是否已经登陆,如果已经登陆了,则提示用户可以选择进入系统或者登出:
<ui:fragment rendered="#{not empty request.remoteUser}">  
    您已经登陆系统,请选择<a href="dashboard.html">进入系统</>,或者<a href="logout.do">登出系统来用其它用户登陆</>
</ui:fragment>
  • 方法3
  • 或者,你希望用户这样干的时候,直接将其重定向到系统首页去,则利用filter来做此事
@WebFilter(urlPatterns = "/login.xhtml")
public class LoginPageFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        if (request.getRemoteUser() != null)) {
            response.sendRedirect(request.getContextPath() + "/home.xhtml"); // Redirect to home page.
        } else {
            chain.doFilter(req, res); // User is not logged-in, so just continue request.
        }
    }

    // Add/generate init() and destroy() with NOOP.
}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值