Complete JWT token support.

This commit is contained in:
Paulo Gustavo Veiga 2024-02-04 20:53:24 -08:00
parent 082f2614e3
commit 34a5328a2c
5 changed files with 64 additions and 43 deletions

View File

@ -18,9 +18,11 @@ import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Optional;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String BEARER_TOKEN_PREFIX = "Bearer ";
@Autowired
private UserDetailsService userDetailsService;
@ -32,33 +34,51 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
// Extract username from token ...
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwtToken = authorizationHeader.substring(7);
try {
username = jwtTokenUtil.extractFromJwtToken(jwtToken);
} catch (Exception e) {
// Handle token extraction/validation errors
logger.debug("Error extracting username from token: " + e.getMessage());
final Optional<String> token = getJwtTokenFromRequest(request);
if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) {
// Extract email from token ...
final Optional<String> email = extractEmailFromToken(token.get());
if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) {
// Is it an existing user ?
final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get());
if (userDetails != null) {
final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} else {
logger.trace("User " + email.get() + " could not be found");
}
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateJwtToken(jwtToken)) {
final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
filterChain.doFilter(request, response);
}
private Optional<String> extractEmailFromToken(final @NotNull String token) {
Optional<String> result = Optional.empty();
try {
result = Optional.of(jwtTokenUtil.extractFromJwtToken(token));
} catch (Exception e) {
// Handle token extraction/validation errors
logger.debug("Error extracting email from token: " + e.getMessage());
}
return result;
}
private static Optional<String> getJwtTokenFromRequest(@NotNull HttpServletRequest request) {
Optional<String> result = Optional.empty();
final String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null) {
if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) {
logger.trace("JWT Bearer token found");
final String token = authorizationHeader.substring(BEARER_TOKEN_PREFIX.length());
result = Optional.of(token);
}
}
return result;
}
}

View File

@ -55,11 +55,11 @@ public class JwtAuthController {
public ResponseEntity<?> createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception {
// Is a valid user ?
authenticate(user.getUsername(), user.getPassword());
authenticate(user.getEmail(), user.getPassword());
// Create token ...
final UserDetails userDetails = userDetailsService
.loadUserByUsername(user.getUsername());
.loadUserByUsername(user.getEmail());
final String token = jwtTokenUtil.generateJwtToken(userDetails);

View File

@ -33,21 +33,20 @@ import org.jetbrains.annotations.NotNull;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RestJwtUser {
private String username;
private String email;
private String password;
public RestJwtUser(@NotNull String username, @NotNull String password) {
this.setUsername(username);
public RestJwtUser(@NotNull String email, @NotNull String password) {
this.setEmail(email);
this.setPassword(password);
}
public String getUsername() {
return this.username;
public String getEmail() {
return this.email;
}
public void setUsername(String username) {
this.username = username;
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {

View File

@ -21,14 +21,14 @@ public class JwtTokenUtil implements Serializable {
@Value("${app.jwt.secret}")
private String jwtSecret;
@Value("${app.jwt.expirationMs}")
private int jwtExpirationMs;
@Value("${app.jwt.expirationMin}")
private int jwtExpirationMin;
public String generateJwtToken(@NotNull final UserDetails user) {
return Jwts.builder()
.setSubject((user.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMin * 1000L * 60))
.signWith(key(), SignatureAlgorithm.HS256)
.compact();
}

View File

@ -29,12 +29,20 @@ spring:
mode: always
platform: hsqldb
# Login ...
logging:
level:
org:
apache:
tomcat: INFO
root: TRACE
# Application Configuration.
app:
jwt:
secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3
expirationMs: 10000
expirationMin: 10080 # One week
admin:
user: admin@wisemapping.org
@ -48,12 +56,6 @@ google:
enabled: true
secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
logging:
level:
org:
apache:
tomcat: INFO
root: INFO
mail:
password: ''
serverSendEmail: root@localhost