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 org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
@Component @Component
public class JwtAuthenticationFilter extends OncePerRequestFilter { public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String BEARER_TOKEN_PREFIX = "Bearer ";
@Autowired @Autowired
private UserDetailsService userDetailsService; private UserDetailsService userDetailsService;
@ -32,33 +34,51 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
throws ServletException, IOException { throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
// Extract username from token ... final Optional<String> token = getJwtTokenFromRequest(request);
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) {
jwtToken = authorizationHeader.substring(7); // Extract email from token ...
try { final Optional<String> email = extractEmailFromToken(token.get());
username = jwtTokenUtil.extractFromJwtToken(jwtToken);
} catch (Exception e) { if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) {
// Handle token extraction/validation errors // Is it an existing user ?
logger.debug("Error extracting username from token: " + e.getMessage()); 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); 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 { public ResponseEntity<?> createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception {
// Is a valid user ? // Is a valid user ?
authenticate(user.getUsername(), user.getPassword()); authenticate(user.getEmail(), user.getPassword());
// Create token ... // Create token ...
final UserDetails userDetails = userDetailsService final UserDetails userDetails = userDetailsService
.loadUserByUsername(user.getUsername()); .loadUserByUsername(user.getEmail());
final String token = jwtTokenUtil.generateJwtToken(userDetails); final String token = jwtTokenUtil.generateJwtToken(userDetails);

View File

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

View File

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

View File

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