Search in sources :

Example 1 with BearerAuthenticationToken

use of com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken in project ma-core-public by infiniteautomation.

the class MangoTokenAuthenticationProvider method authenticate.

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if (!(authentication instanceof BearerAuthenticationToken)) {
        return null;
    }
    String bearerToken = (String) authentication.getCredentials();
    User user;
    Jws<Claims> jws;
    try {
        jws = tokenAuthenticationService.parse(bearerToken);
        user = tokenAuthenticationService.verify(jws);
    } catch (ExpiredJwtException e) {
        throw new CredentialsExpiredException(e.getMessage(), e);
    } catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
        // assume that this is not a JWT, allow the next AuthenticationProvider to process it
        return null;
    } catch (SignatureException | MissingClaimException | IncorrectClaimException e) {
        throw new BadCredentialsException(e.getMessage(), e);
    } catch (NotFoundException e) {
        throw new BadCredentialsException("Invalid username", e);
    } catch (Exception e) {
        throw new InternalAuthenticationServiceException(e.getMessage(), e);
    }
    userDetailsChecker.check(user);
    if (log.isDebugEnabled()) {
        log.debug("Successfully authenticated user using JWT token, header: " + jws.getHeader() + ", body: " + jws.getBody());
    }
    return new PreAuthenticatedAuthenticationToken(user, bearerToken, user.getAuthorities());
}
Also used : User(com.serotonin.m2m2.vo.User) Claims(io.jsonwebtoken.Claims) ExpiredJwtException(io.jsonwebtoken.ExpiredJwtException) CredentialsExpiredException(org.springframework.security.authentication.CredentialsExpiredException) NotFoundException(com.serotonin.m2m2.vo.exception.NotFoundException) InternalAuthenticationServiceException(org.springframework.security.authentication.InternalAuthenticationServiceException) PreAuthenticatedAuthenticationToken(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken) SignatureException(io.jsonwebtoken.SignatureException) IncorrectClaimException(io.jsonwebtoken.IncorrectClaimException) BadCredentialsException(org.springframework.security.authentication.BadCredentialsException) BadCredentialsException(org.springframework.security.authentication.BadCredentialsException) NotFoundException(com.serotonin.m2m2.vo.exception.NotFoundException) UnsupportedJwtException(io.jsonwebtoken.UnsupportedJwtException) InternalAuthenticationServiceException(org.springframework.security.authentication.InternalAuthenticationServiceException) MissingClaimException(io.jsonwebtoken.MissingClaimException) IncorrectClaimException(io.jsonwebtoken.IncorrectClaimException) CredentialsExpiredException(org.springframework.security.authentication.CredentialsExpiredException) MalformedJwtException(io.jsonwebtoken.MalformedJwtException) ExpiredJwtException(io.jsonwebtoken.ExpiredJwtException) SignatureException(io.jsonwebtoken.SignatureException) AuthenticationException(org.springframework.security.core.AuthenticationException) MissingClaimException(io.jsonwebtoken.MissingClaimException) MalformedJwtException(io.jsonwebtoken.MalformedJwtException) UnsupportedJwtException(io.jsonwebtoken.UnsupportedJwtException)

Example 2 with BearerAuthenticationToken

use of com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken in project ma-core-public by infiniteautomation.

the class MangoWebSocketPublisher method getUser.

/**
 * Gets the Mango user for a WebSocketSession. If there is no user and closeOnLogout is true then the WebSocketSession is closed.
 *
 * Will return null when:
 * <ul>
 *   <li>There never was a user</li>
 *   <li>Session was invalidated (user logged out, admin disabled them or changed their password)</li>
 *   <li>JWT auth token has expired, been revoked or the private/public keys changed</li>
 * </ul>
 *
 * TODO Mango 3.4 store the user and authentication in the WebSocketSession attributes using the handshake intercepter.
 * Use the sessionDestroyed/user modified/JWT key changed events to replace the user in the attributes or close the session as appropriate.
 * If we have a user modified and JWT key changed event we don't have to re-parse and re-validate the JWT token every time.
 *
 * @param session
 * @return user or null
 */
protected User getUser(WebSocketSession session) {
    User user = null;
    Authentication authentication = null;
    // get the user at the time of HTTP -> websocket upgrade
    Principal principal = session.getPrincipal();
    if (principal instanceof Authentication) {
        authentication = (Authentication) principal;
        Object authenticationPrincipal = authentication.getPrincipal();
        if (authenticationPrincipal instanceof User) {
            user = (User) authenticationPrincipal;
        }
    }
    // user should never be null as long as the websocket URLs are protected by Spring Security
    if (user != null) {
        String httpSessionId = httpSessionIdForSession(session);
        if (httpSessionId != null) {
            SessionInformation sessionInformation = sessionRegistry.getSessionInformation(httpSessionId);
            if (sessionInformation != null && !sessionInformation.isExpired()) {
                // we dont have to check if the user is disabled etc as the session would be invalidated if the user was modified
                return user;
            }
        }
        // no valid session, check for an authentication token
        if (authentication instanceof PreAuthenticatedAuthenticationToken) {
            PreAuthenticatedAuthenticationToken token = (PreAuthenticatedAuthenticationToken) authentication;
            Object credentials = token.getCredentials();
            if (credentials instanceof String) {
                String jwtString = (String) credentials;
                BearerAuthenticationToken bearerToken = new BearerAuthenticationToken(jwtString);
                /**
                 * Re-authenticate the token as
                 * a) The user might have been disabled
                 * b) The user's tokens might have been revoked
                 * c) The JWT private key might have changed
                 */
                try {
                    Authentication newAuthentication = this.authenticationManager.authenticate(bearerToken);
                    Object newPrincipal = newAuthentication.getPrincipal();
                    if (newPrincipal instanceof User) {
                        return (User) newPrincipal;
                    }
                } catch (AuthenticationException e) {
                // token is no longer valid
                // do nothing, just return null
                }
            }
        }
    }
    // TODO Mango 3.4 don't close sessions here
    if (this.closeOnLogout) {
        this.closeSession(session, NOT_AUTHENTICATED);
    }
    return null;
}
Also used : SessionInformation(org.springframework.security.core.session.SessionInformation) User(com.serotonin.m2m2.vo.User) AuthenticationException(org.springframework.security.core.AuthenticationException) Authentication(org.springframework.security.core.Authentication) BearerAuthenticationToken(com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken) PreAuthenticatedAuthenticationToken(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken) Principal(java.security.Principal)

Example 3 with BearerAuthenticationToken

use of com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken in project ma-core-public by infiniteautomation.

the class BearerAuthenticationFilter method doFilterInternal.

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
    String tokenString = null;
    String header = request.getHeader("Authorization");
    if (header != null && header.startsWith("Bearer ")) {
        tokenString = header.substring(7).trim();
    }
    if (tokenString == null || tokenString.isEmpty()) {
        chain.doFilter(request, response);
        return;
    }
    try {
        if (authenticationIsRequired()) {
            BearerAuthenticationToken authRequest = new BearerAuthenticationToken(tokenString);
            Authentication authResult = authenticationManager.authenticate(authRequest);
            authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authResult);
        }
    } catch (AuthenticationException failed) {
        SecurityContextHolder.clearContext();
        this.authenticationEntryPoint.commence(request, response, failed);
        return;
    }
    chain.doFilter(request, response);
}
Also used : AuthenticationException(org.springframework.security.core.AuthenticationException) BearerAuthenticationToken(com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken) Authentication(org.springframework.security.core.Authentication)

Aggregations

AuthenticationException (org.springframework.security.core.AuthenticationException)3 User (com.serotonin.m2m2.vo.User)2 BearerAuthenticationToken (com.serotonin.m2m2.web.mvc.spring.security.authentication.BearerAuthenticationToken)2 Authentication (org.springframework.security.core.Authentication)2 PreAuthenticatedAuthenticationToken (org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken)2 NotFoundException (com.serotonin.m2m2.vo.exception.NotFoundException)1 Claims (io.jsonwebtoken.Claims)1 ExpiredJwtException (io.jsonwebtoken.ExpiredJwtException)1 IncorrectClaimException (io.jsonwebtoken.IncorrectClaimException)1 MalformedJwtException (io.jsonwebtoken.MalformedJwtException)1 MissingClaimException (io.jsonwebtoken.MissingClaimException)1 SignatureException (io.jsonwebtoken.SignatureException)1 UnsupportedJwtException (io.jsonwebtoken.UnsupportedJwtException)1 Principal (java.security.Principal)1 BadCredentialsException (org.springframework.security.authentication.BadCredentialsException)1 CredentialsExpiredException (org.springframework.security.authentication.CredentialsExpiredException)1 InternalAuthenticationServiceException (org.springframework.security.authentication.InternalAuthenticationServiceException)1 SessionInformation (org.springframework.security.core.session.SessionInformation)1