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());
}
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;
}
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);
}
Aggregations