@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { SessionIdToken sessionIdToken = (SessionIdToken) token; final Subject subject = new Subject.Builder().sessionId(sessionIdToken.getSessionId()).buildSubject(); final Session session = subject.getSession(false); if (session == null) { LOG.debug( "Invalid session {}. Either it has expired or did not exist.", sessionIdToken.getSessionId()); return null; } final Object username = subject.getPrincipal(); final User user = userService.load(String.valueOf(username)); if (user == null) { LOG.debug("No user named {} found for session {}", username, sessionIdToken.getSessionId()); return null; } if (user.isExternalUser() && !ldapAuthenticator.isEnabled()) { throw new LockedAccountException("LDAP authentication is currently disabled."); } if (LOG.isDebugEnabled()) { LOG.debug("Found session {} for user name {}", session.getId(), username); } @SuppressWarnings("unchecked") final MultivaluedMap<String, String> requestHeaders = (MultivaluedMap<String, String>) ThreadContext.get("REQUEST_HEADERS"); // extend session unless the relevant header was passed. if (requestHeaders == null || !"true".equalsIgnoreCase(requestHeaders.getFirst("X-Graylog-No-Session-Extension"))) { session.touch(); } else { LOG.debug("Not extending session because the request indicated not to."); } ThreadContext.bind(subject); return new SimpleAccount(user.getName(), null, "session authenticator"); }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Check request type. // if (!(request instanceof HttpServletRequest)) { raiseSecurityError(response, "Unexpected request class detected."); return; } HttpServletRequest hsr = (HttpServletRequest) request; // Try to match URL against exclude pattern. // String requestUri = hsr.getRequestURI(); if (excludePattern != null && excludePattern.matcher(requestUri).matches()) { chain.doFilter(request, response); return; } // Extract security token from custom header. // String token = hsr.getHeader(SECURITY_TOKEN); logger.debug("Passed security token: " + token); // SecurityResource token must be present. // if (token == null) { logger.info("No token found in request header."); raiseSecurityError(response, "Null token detected"); return; } // Check if the passed token is associated with a valid session. // try { Session session = SecurityUtils.getSecurityManager().getSession(new DefaultSessionKey(token)); if (session == null) { logger.info("Unable to find a valid session using token."); raiseSecurityError(response, "Invalid session token."); return; } // Ensure that the last accessed timestamp gets updated. This should be made // internally by Shiro, but it looks like it is not working. Maybe the pattern // employed here to get the session is not canonical... // session.touch(); } catch (SessionException se) { logger.info(se.getMessage()); raiseSecurityError(response, "Invalid session token. Cause: " + se.getMessage()); return; } Subject requestSubject = new Subject.Builder().sessionId(token).buildSubject(); ThreadState threadState = new SubjectThreadState(requestSubject); threadState.bind(); try { chain.doFilter(request, response); } finally { threadState.clear(); } }