Shiro, redis, cache realize several improvements in the shared session code

 

Shiro, redis, cache realize several improvements in the shared session code

 That is, shiro gives me the session part for redis management: Note:

token.setRememberMe(true);// The design remembers the user, so that the reverse generation of the cookie-->session after the machine escapes

 

Shiro integrated cas is to hand over the authentication to cas

 

1, setExtNo is used for this special purpose, and it is used before the cookie has been written (if it is not, use Shiro's own)

2. When logging in, there is no current cookie to store the websession --> LoginFilter

 

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

throws IOException, ServletException {

 

Subject currentUser = SecurityUtils.getSubject(); // Get the current Subject

// Verify that the login was successful

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");

//Use shrio's own if you haven't yet, and generate a cookie later, username1 is still the last time, use shrio's own

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&¤tUserrds.getSession()!=null){

currentUser=currentUserrds;

}

 

// Verify that the login was successful

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会报错

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326083006&siteId=291194637