shiro,redis,cache实现共享session代码中几个注意的地方改进

 

shiro,redis,cache实现共享session代码中几个注意的地方改进

 即shiro把session部分交给我redis管理:注意:

token.setRememberMe(true);// 设计记住用户,这样才能机器转义后cookie-->session的反向生成

 

shiro集成cas就是把认证这块交给了cas

 

1, setExtNo  就这个特殊还没跳转完,还没写好cookie就用了(判断没有就用shiro自己的)

2,在登录的时候没有当前的cookie就用来存 websession  -->LoginFilter

 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

 

Subject currentUser = SecurityUtils.getSubject(); // 获取当前的Subject

// 验证是否登录成功

String resultPageURL = "/flex/rbac/preLogin.action";// InternalResourceViewResolver.FORWARD_URL_PREFIX

// + "/";

 

String username = request.getParameter("j_username");

String password = request.getParameter("j_password");

RequestDispatcher rd = null;

 

HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();  //ServletActionContext.getRequest();

Cookie[] cookies = request1.getCookies();

String username1=getCookieValue(cookies, "username");

//此时还没有就用shrio自己的,后续生成cookie,username1此时还是上一次的就用shiro自己的

if(username!=null&&((username1==null||username1=="")||!username.equals(username1))){

username1=username;

}

WebSession webSession= WebSessionManager.getInstance().getSession(username1);

if(webSession==null){

 

webSession=WebSessionManager.getInstance().createSession(username1);

}

String uk="Subject"+username1;

Subject currentUserrds=(Subject)webSession.getAttribute(uk);

if(currentUserrds!=null&&currentUserrds.getSession()!=null){

currentUser=currentUserrds;

}

 

// 验证是否登录成功

if (currentUser.isAuthenticated()) {

System.out.println("用户[" + currentUser.getSession().getAttribute("j_username") + "]登录认证通过");

authenticationFilter.setLoginSession(request, response);

rd = request.getRequestDispatcher("/flex/rbac/getLoginIndex.action");

// response.setBufferSize(1024000000);

rd.forward(request, response);

return;

// chain.doFilter(request, response);

} else {

if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {

HttpServletResponse res = (HttpServletResponse)response;

      request.setAttribute("msg", "您的账号存在信息不全的问题,请联系管理员完善信息!");

      System.out.println("登录过滤器@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

rd = request.getRequestDispatcher("/flex/rbac/preLogin.action");

rd.forward(request, response);

return;

}

// password = MD5.encryptMD5(Base64.encode(password));

/* password = MD5.encryptMD5(Base64.encode("111111")); */

UsernamePasswordToken token = new UsernamePasswordToken(username, password); // 为了验证登录用户而封装的token

token.setRememberMe(true);// 设计记住用户

 

try {

// 在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查

// 每个Realm都能在必要时对提交的AuthenticationTokens作出反应

// 所以这一步在调用login(token)方法时,它会走到AuthenticationRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法

currentUser.login(token);

resultPageURL = "/flex/rbac/preLogin.action";

} catch (UnknownAccountException uae) {

System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");

request.setAttribute("msg", "未知账户");//message_login

} catch (IncorrectCredentialsException ice) {

System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");

request.setAttribute("msg", "密码不正确");

} catch (LockedAccountException lae) {

System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");

request.setAttribute("msg", "账户已锁定");

} catch (ExcessiveAttemptsException eae) {

System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");

request.setAttribute("msg", "用户名或密码错误次数过多");

} catch (AuthenticationException ae) {

// 通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景

System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");

ae.printStackTrace();

request.setAttribute("msg", "用户名或密码不正确");

}

if (currentUser.isAuthenticated()) {

System.out.println("用户[" + username + "]登录认证通过");

authenticationFilter.setLoginSession(request, response);

rd = request.getRequestDispatcher("/flex/rbac/getLoginIndex.action");

rd.forward(request, response);

return;

// chain.doFilter(request, response);

} else {

token.clear();

}

 

}

// chain.doFilter(request, response);

// HttpServletResponse res = (HttpServletResponse)response;

//      request.setAttribute("msg", "您的账号存在信息不全的问题,请联系管理员完善信息!");

//      System.out.println("登录过滤器@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

rd = request.getRequestDispatcher(resultPageURL);

rd.forward(request, response);

return;

 

}

 

之前保存的是其他账户(紧上次)

String username1=getCookieValue(cookies, "username");同一个浏览器切换账户时,用的是上次成功的(只有登录完成之后有response才cookie记录)

没设置cooking共享成功但是登录成功(浏览器记住了缓存的缘故),后面用共享session的时候就出错(所以要清缓存)

 

Subject currentUser = SecurityUtils.getSubject(); // 获取当前的Subject 这个直接根据cookie获取,对比session 判断状态// 验证是否登录成功,和输入框五个

if (currentUser.isAuthenticated()) 

 

j_acegi_security_check这就就是优先走isAuthenticated校验

 

 

 

3,

 

在认证通过之后才setcookies--》走完loginfilter调用MyAuthenticationFilter这里的savecooike方法

MyAuthenticationFilter

ShiroDbRealm(这时就用了),没设置cooking共享成功但是登录成功(浏览器记住了缓存的缘故),后面用共享session的时候就出错(所以要清缓存)

 

 

loginfilt还是拿到了以前的用户(没有正常退出(浏览器记住了缓存的缘故))

 

 

就不走ShiroDbRealm就无法记录共享的session信息

 

1ShiroDbRealm

2MyAuthenticationFilter

 

跳转以后才有cookie

private void userRolesInit(){

//Subject currentUser = SecurityUtils.getSubject();

//UserDetailsBean shiroUser = (UserDetailsBean) currentUser.getPrincipal();//userDetailsSessionService.getUserId();

HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();

Cookie[] cookies = request1.getCookies();

String username=getCookieValue(cookies, "username");

WebSession webSession= WebSessionManager.getInstance().getSession(username);

 

 

 

 

4,

ie浏览器的时候,cookie会比chrome写的慢,这就出现chrome可以拿到,ie还是拿不到,要比较久,这时需处理拿不到的时候用shiro自带的

 

 

    Cookie[] cookies = request1.getCookies();

    String username=getCookieValue(cookies, "username");

    Subject currentUser = SecurityUtils.getSubject();

    UserDetailsBean shiroUser =  (currentUser==null?new UserDetailsBean():(UserDetailsBean)currentUser.getPrincipal());

    logger.info("username=========="+username);

    logger.info("shiroUser=========="+shiroUser);

    logger.info("shiroUser.getUserId()=========="+shiroUser.getUserId());

    if(username!=null&&(shiroUser==null||shiroUser.getUserId()==null||username.equals(shiroUser.getUserId()))){

      WebSession webSession= WebSessionManager.getInstance().getSession(username);

      shiroUser = (UserDetailsBean) webSession.getAttribute(username);

 

    }

 

 

 ================================

上述用到的自己利用cookie不需要

其实shiro实现了session的共享之后切换

 Subject currentUser = SecurityUtils.getSubject();

    UserDetailsBean shiroUser =  (UserDetailsBean)currentUser.getPrincipal();

    这个方法的值也是利用cookie中的sessionid从cookie中获取,然后直接从共享缓存获取

不需要如下代码自己把客户信息缓存到一个session(自定义的和shiro无关的)中。这也就不需要自己向cookie写入键值,然后拿出用其setvalue,getvalue

     public String getUserId()

  {

    try {

      InetAddress address = InetAddress.getLocalHost();//获取的是本地的IP地址 //PC-20140317PXKX/192.168.0.121

      String hostAddress = address.getHostAddress();

      logger.info("============ip地址==================="+hostAddress);

      System.out.println(hostAddress);

    }catch (Exception e){

    }

    HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();

    Cookie[] cookies = request1.getCookies();

    String username=getCookieValue(cookies, "username");

    Subject currentUser = SecurityUtils.getSubject();

    UserDetailsBean shiroUser =  (currentUser==null?new UserDetailsBean():(UserDetailsBean)currentUser.getPrincipal());

//    logger.info("username=========="+username);

//    logger.info("shiroUser=========="+shiroUser);

//    logger.info("shiroUser.getUserId()==========");

//    if(username!=null&&(shiroUser==null||shiroUser.getUserId()==null||username.equals(shiroUser.getUserId()))){

//    WebSession webSession= WebSessionManager.getInstance().getSession(username);

//

//    if(webSession!=null){

//      UserDetailsBean shiroUser1 = (UserDetailsBean) webSession.getAttribute(username);

//      if(shiroUser1!=null){

//        logger.info("shiroUser1=========="+shiroUser1);

//        shiroUser =shiroUser1;

//      }else{

//        shiroUser =(UserDetailsBean)currentUser.getPrincipal();

//      }

//

//      logger.info("shiroUser2=========="+shiroUser);

//    }else{

//      shiroUser =(UserDetailsBean)currentUser.getPrincipal();

//    }

//

//

//  }

    logger.info("shiroUser3=========="+shiroUser);

     String ccidExtno=  request1.getParameter("j_extno");

     shiroUser.setExtNo(ccidExtno==null?"":ccidExtno);

//   Subject currentUser = SecurityUtils.getSubject();

//  UserDetailsBean shiroUser = (UserDetailsBean) currentUser.getPrincipal();//userDetailsSessionService.getUserId();

    //UserDetailsBean agentUser = (UserDetailsBean)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

    return shiroUser.getUserId();

  }

 

 注意

MyAuthenticationFilter中onLoginSuccess中的session.stop();需要注掉,否则用框架的登陆走了onLoginSuccess然后又清了session会报错

猜你喜欢

转载自yuhuiblog6338999322098842.iteye.com/blog/2401112
今日推荐