|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public class ShiroAuthFilter extends FormAuthenticationFilter { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public ShiroAuthFilter(SessionManager sessionManager,ShiroCacheManager shiroCacheManager) { | 
|---|
|  |  |  | super(); | 
|---|
|  |  |  | this.sessionManager =   (ShiroSessionManager)sessionManager; | 
|---|
|  |  |  | this.cache = shiroCacheManager.getCache("shiro_redis_cache"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)  { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private int maxSession = 1; //最大会话数量 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private boolean kickOutAfter = false;   //踢出前者还是后者 | 
|---|
|  |  |  | private Cache<String, Deque<Serializable>> cache; //缓存管理 | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private ShiroSessionManager sessionManager;  //会话管理 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { | 
|---|
|  |  |  | Subject subject = getSubject(request, response); | 
|---|
|  |  |  | if (!subject.isAuthenticated() && !subject.isRemembered()) { //如果不是认证过和记住密码的,就直接放行请求,避免造成访问过慢 | 
|---|
|  |  |  | // return Boolean.TRUE; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Session session = subject.getSession(); //获取会话session | 
|---|
|  |  |  | Object principal = subject.getPrincipal(); | 
|---|
|  |  |  | Serializable sessionId = session.getId(); | 
|---|
|  |  |  | LoginUserInfo userInfo = (LoginUserInfo) principal; | 
|---|
|  |  |  | if(userInfo == null  ){ | 
|---|
|  |  |  | HttpServletResponse servletResponse = (HttpServletResponse) response; | 
|---|
|  |  |  | servletResponse.setHeader("content-type", "application/json;charset=UTF-8"); | 
|---|
|  |  |  | servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "未登录或登录信息已过期"))); | 
|---|
|  |  |  | return Boolean.FALSE; | 
|---|
|  |  |  | //           return  super.onAccessDenied(request,response); | 
|---|
|  |  |  | }else if( Constants.equalsInteger(userInfo.getType(), Constants.UserType.COMPANY.getKey()) ){ | 
|---|
|  |  |  | return Boolean.TRUE; | 
|---|
|  |  |  | //           return  super.onAccessDenied(request,response); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String userName = userInfo.getCompanyId() +"_"+ userInfo.getId(); | 
|---|
|  |  |  | Deque<Serializable> deque = cache.get(userName); | 
|---|
|  |  |  | if (deque == null) { | 
|---|
|  |  |  | deque = new LinkedList<>(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!deque.contains(sessionId) && session.getAttribute("kickOut") == null) { | 
|---|
|  |  |  | deque.push(sessionId); | 
|---|
|  |  |  | cache.put(userName, deque); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | while (deque.size() > maxSession) { | 
|---|
|  |  |  | Serializable kickOutSessionId; | 
|---|
|  |  |  | if (kickOutAfter) { | 
|---|
|  |  |  | kickOutSessionId = deque.removeFirst(); | 
|---|
|  |  |  | cache.put(userName, deque); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | kickOutSessionId = deque.removeLast(); | 
|---|
|  |  |  | cache.put(userName, deque); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | Session kickOutSession = sessionManager.getSession(new DefaultSessionKey(kickOutSessionId)); | 
|---|
|  |  |  | if (kickOutSession != null) { | 
|---|
|  |  |  | kickOutSession.setAttribute("kickOut", Boolean.TRUE); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | //                log.error("踢出异常未踢出"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (session!=null && session.getAttribute("kickOut") != null && (Boolean) session.getAttribute("kickOut") == true) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | subject.logout(); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | saveRequest(request); | 
|---|
|  |  |  | HttpServletResponse servletResponse = (HttpServletResponse) response; | 
|---|
|  |  |  | servletResponse.setHeader("content-type", "application/json;charset=UTF-8"); | 
|---|
|  |  |  | servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "未登录或登录信息已过期"))); | 
|---|
|  |  |  | return Boolean.FALSE; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return Boolean.TRUE; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public int getMaxSession() { | 
|---|
|  |  |  | return maxSession; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setMaxSession(int maxSession) { | 
|---|
|  |  |  | this.maxSession = maxSession; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public boolean isKickOutAfter() { | 
|---|
|  |  |  | return kickOutAfter; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setKickOutAfter(boolean kickOutAfter) { | 
|---|
|  |  |  | this.kickOutAfter = kickOutAfter; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public Cache<String, Deque<Serializable>> getCache() { | 
|---|
|  |  |  | return cache; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setCache(Cache<String, Deque<Serializable>> cache) { | 
|---|
|  |  |  | this.cache = cache; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public ShiroSessionManager getSessionManager() { | 
|---|
|  |  |  | return sessionManager; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setSessionManager(ShiroSessionManager sessionManager) { | 
|---|
|  |  |  | this.sessionManager = sessionManager; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|