A self hosted chat application with end-to-end encrypted messaging.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

163 lines
5.9 KiB

package org.ros.chatto.security;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ros.chatto.model.UserToken;
import org.ros.chatto.service.UserTokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.token.Token;
import org.springframework.security.core.token.TokenService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private UserTokenService userTokenService;
@Autowired
private TokenService tokenService;
private final Logger logger = LoggerFactory.getLogger(TokenAuthenticationFilter.class);
private final int tokenTimeoutDuration;
public TokenAuthenticationFilter(@Value("${chatto.token.timeout-duration}") String tokenTimeoutDuration) {
// super();
this.tokenTimeoutDuration = Integer.parseInt(tokenTimeoutDuration);
}
// @Override
// public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
// throws IOException, ServletException {
// final HttpServletRequest httpRequest = (HttpServletRequest) request;
//
// // extract token from header
// final String accessToken = httpRequest.getHeader("X-AUTH-TOKEN");
// if (null != accessToken) {
// // get and check whether token is valid ( from DB or file wherever you are
// // storing the token)
// Token token = tokenService.verifyToken(accessToken);
//
// if (token == null) {
// throw new UsernameNotFoundException("Token not issued by us");
// }
// UserToken userToken = userTokenService.getTokenByTokenString(accessToken);
//
// if (userToken == null) {
// throw new UsernameNotFoundException("Token not associated with any user");
// }
//
// String userName = userToken.getUserName();
// if (userName == null) {
// throw new UsernameNotFoundException("User not found");
// }
//
//
//
// System.out.println("Timeout duration = " + tokenTimeoutDuration);
// boolean isTokenExpired = isTokenExpired(userToken);
// System.out.println("expired? " + isTokenExpired);
// if (!isTokenExpired) {
// userTokenService.saveToken(userToken);
// SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(userToken.getRole());
// List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
// updatedAuthorities.add(simpleGrantedAuthority);
// final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
// userName, token.getKey(), updatedAuthorities);
// SecurityContextHolder.getContext().setAuthentication(authentication);
// } else {
// userTokenService.deleteToken(userToken.getUserName());
// }
//
// }
//
// chain.doFilter(request, response);
// }
private boolean isTokenExpired(UserToken userToken) {
Duration duration = Duration.between(userToken.getCreationTime(), Instant.now());
long minutes = Math.abs(duration.toMinutes());
if (minutes > tokenTimeoutDuration) {
return true;
}
return false;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
final String accessToken = request.getHeader("X-AUTH-TOKEN");
if (null != accessToken) {
// get and check whether token is valid ( from DB or file wherever you are
// storing the token)
Token token = tokenService.verifyToken(accessToken);
if (token == null) {
throw new BadCredentialsException("Token not issued by us");
}
UserToken userToken = userTokenService.getTokenByTokenString(accessToken);
if (userToken == null) {
throw new BadCredentialsException("Token not found");
}
String userName = userToken.getUserName();
if (userName == null) {
throw new BadCredentialsException("User not found");
}
System.out.println("Timeout duration = " + tokenTimeoutDuration);
boolean isTokenExpired = isTokenExpired(userToken);
System.out.println("expired? " + isTokenExpired);
if (!isTokenExpired) {
userToken.setCreationTime(Instant.now());
userTokenService.saveToken(userToken);
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(userToken.getRole());
List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
updatedAuthorities.add(simpleGrantedAuthority);
final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userName, token.getKey(), updatedAuthorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
userTokenService.deleteToken(userToken.getUserName());
}
}
filterChain.doFilter(request, response);
}
catch (Exception e) {
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
// response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
response.getWriter().write("Token authentication error");
logger.warn("Token authentication error: " + e.getMessage());
}
}
}