Complete JWT token support.
parent
082f2614e3
commit
34a5328a2c
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue