@@ -1,43 +1,48 @@
|
|||||||
package net.gepafin.tendermanagement.config.jwt;
|
package net.gepafin.tendermanagement.config.jwt;
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.ServletRequest;
|
|
||||||
import jakarta.servlet.ServletResponse;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class JWTFilter extends GenericFilterBean {
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
private final TokenProvider tokenProvider;
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
public JWTFilter(TokenProvider tokenProvider) {
|
public class JWTFilter extends OncePerRequestFilter {
|
||||||
this.tokenProvider = tokenProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private final TokenProvider tokenProvider;
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
|
||||||
throws IOException, ServletException {
|
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
|
||||||
String token = resolveToken(httpServletRequest);
|
|
||||||
|
|
||||||
if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) {
|
public JWTFilter(TokenProvider tokenProvider) {
|
||||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
this.tokenProvider = tokenProvider;
|
||||||
if (authentication != null) {
|
}
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filterChain.doFilter(servletRequest, servletResponse);
|
protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
|
||||||
}
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
|
||||||
private String resolveToken(HttpServletRequest request) {
|
try {
|
||||||
String bearerToken = request.getHeader("Authorization");
|
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
||||||
return StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ") ? bearerToken.substring(7) : null;
|
String token = resolveToken(httpServletRequest);
|
||||||
}
|
|
||||||
|
if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) {
|
||||||
|
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||||
|
if (authentication != null) {
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filterChain.doFilter(servletRequest, servletResponse);
|
||||||
|
} catch (Exception e) {
|
||||||
|
servletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveToken(HttpServletRequest request) {
|
||||||
|
String bearerToken = request.getHeader("Authorization");
|
||||||
|
return StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ") ? bearerToken.substring(7) : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,39 @@
|
|||||||
package net.gepafin.tendermanagement.config.jwt;
|
package net.gepafin.tendermanagement.config.jwt;
|
||||||
|
|
||||||
|
import static io.micrometer.common.util.StringUtils.isEmpty;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
|
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.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
@@ -14,30 +48,6 @@ import net.gepafin.tendermanagement.repositories.UserRepository;
|
|||||||
import net.gepafin.tendermanagement.util.Utils;
|
import net.gepafin.tendermanagement.util.Utils;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException;
|
import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
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.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import static io.micrometer.common.util.StringUtils.isEmpty;
|
|
||||||
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -48,7 +58,7 @@ public class TokenProvider {
|
|||||||
private String secretKey;
|
private String secretKey;
|
||||||
|
|
||||||
@Value("${security.authentication.jwt.token-validity-in-seconds}")
|
@Value("${security.authentication.jwt.token-validity-in-seconds}")
|
||||||
private long tokenValidityInSeconds;
|
private int tokenValidityInSeconds;
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
@@ -60,7 +70,6 @@ public class TokenProvider {
|
|||||||
private static final String MERCHANTID="merchantId";
|
private static final String MERCHANTID="merchantId";
|
||||||
|
|
||||||
static final String AUTH_SECRET = "X-Api-Secret";
|
static final String AUTH_SECRET = "X-Api-Secret";
|
||||||
private final Set<String> invalidatedTokens = new HashSet<>();
|
|
||||||
private static final String USER_ID = "userId";
|
private static final String USER_ID = "userId";
|
||||||
|
|
||||||
public UserEntity validateUser(Map<String, Object> userInfo) {
|
public UserEntity validateUser(Map<String, Object> userInfo) {
|
||||||
@@ -96,12 +105,12 @@ public class TokenProvider {
|
|||||||
Date validity;
|
Date validity;
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(rememberMe)) {
|
if (Boolean.TRUE.equals(rememberMe)) {
|
||||||
now = DateUtils.addMonths(new Date(), 2).getTime();
|
now = DateUtils.addDays(new Date(), 2).getTime();
|
||||||
validity = new Date(now);
|
validity = new Date(now);
|
||||||
log.info("Creating token with extended validity for 2 months.");
|
log.info("Creating token with extended validity for 2 days.");
|
||||||
} else {
|
} else {
|
||||||
now = (new Date()).getTime();
|
now = DateUtils.addSeconds(new Date(), this.tokenValidityInSeconds).getTime();
|
||||||
validity = new Date(now + (this.tokenValidityInSeconds * 1000));
|
validity = new Date(now);
|
||||||
log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds);
|
log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,32 +157,15 @@ public class TokenProvider {
|
|||||||
return authorities;
|
return authorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validateToken(String authToken) {
|
public boolean validateToken(String authToken) {
|
||||||
try {
|
|
||||||
if (isTokenInvalid(authToken)) {
|
|
||||||
log.warn("Token is invalidated.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Jwts.parserBuilder()
|
|
||||||
.setSigningKey(key)
|
|
||||||
.build()
|
|
||||||
.parseClaimsJws(authToken);
|
|
||||||
log.info("Token is valid.");
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Token validation failed: {}", e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void invalidateToken(String token) {
|
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(authToken);
|
||||||
invalidatedTokens.add(token);
|
log.info("Token is valid.");
|
||||||
log.info("Token invalidated: {}", token);
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTokenInvalid(String token) {
|
}
|
||||||
return invalidatedTokens.contains(token);
|
|
||||||
}
|
|
||||||
public Map<String, Object> getUserInfoAndUserIdFromToken(HttpServletRequest request) {
|
public Map<String, Object> getUserInfoAndUserIdFromToken(HttpServletRequest request) {
|
||||||
Map<String, Object> userInfo = new HashMap<>();
|
Map<String, Object> userInfo = new HashMap<>();
|
||||||
String authSecretHeader=request.getHeader(AUTH_SECRET);
|
String authSecretHeader=request.getHeader(AUTH_SECRET);
|
||||||
|
|||||||
@@ -203,8 +203,6 @@ public class AuthenticationService {
|
|||||||
public void logout(HttpServletRequest request, HttpServletResponse response) {
|
public void logout(HttpServletRequest request, HttpServletResponse response) {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
String token = tokenProvider.extractTokenFromRequest(request);
|
|
||||||
tokenProvider.invalidateToken(token);
|
|
||||||
new SecurityContextLogoutHandler().logout(request, response, auth);
|
new SecurityContextLogoutHandler().logout(request, response, auth);
|
||||||
}
|
}
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
SecurityContextHolder.getContext().setAuthentication(null);
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/
|
|||||||
#aws.s3.url.folder.signed.document=gepafin/signed-document
|
#aws.s3.url.folder.signed.document=gepafin/signed-document
|
||||||
# JWT configuration
|
# JWT configuration
|
||||||
# Ensure these values match your expectations
|
# Ensure these values match your expectations
|
||||||
security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key
|
security.authentication.jwt.secret=Z3/zjSD96Hdvh/AMyaMLJLWSVF00AOmxxEk4Kv8E+bM3bUW/QXOu45OSgRD6H16RvQ/pWZznDQP3l2ZkPlu9Sg==
|
||||||
security.authentication.jwt.token-validity-in-seconds=86400
|
security.authentication.jwt.token-validity-in-seconds=7200
|
||||||
|
|
||||||
# Default system base URLs
|
# Default system base URLs
|
||||||
base-url=https://api-dev-gepafin.memento.credit
|
base-url=https://api-dev-gepafin.memento.credit
|
||||||
|
|||||||
Reference in New Issue
Block a user