SUPPORT-8755: Fix

This commit is contained in:
Eduard Tihomirov 2024-12-25 11:06:49 +03:00
parent 44bcba2faf
commit 69f1094bbf
5 changed files with 38 additions and 32 deletions

View file

@ -25,7 +25,6 @@ import ru.micord.ervu.security.webbpm.jwt.JwtMatcher;
import ru.micord.ervu.security.webbpm.jwt.UnauthorizedEntryPoint;
import ru.micord.ervu.security.webbpm.jwt.filter.JwtAuthenticationFilter;
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
import static ru.micord.ervu.security.SecurityConstants.ESIA_LOGOUT;
@ -105,10 +104,9 @@ public class SecurityConfig {
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter(SecurityHelper securityHelper,
AuthenticationManager manager,
JwtTokenService jwtTokenService) {
AuthenticationManager manager) {
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(
new JwtMatcher("/**", PERMIT_ALL), entryPoint(), securityHelper, jwtTokenService);
new JwtMatcher("/**", PERMIT_ALL), entryPoint(), securityHelper);
jwtAuthenticationFilter.setAuthenticationManager(manager);
return jwtAuthenticationFilter;
}

View file

@ -1,14 +1,17 @@
package ru.micord.ervu.security.esia.token;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Eduard Tihomirov
*/
public class EsiaTokensStore {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Map<String, ExpiringToken> accessTokensMap = new ConcurrentHashMap<>();
private static final Map<String, ExpiringToken> refreshTokensMap = new ConcurrentHashMap<>();
@ -23,14 +26,17 @@ public class EsiaTokensStore {
return accessTokensMap.get(prnOid).getAccessToken();
}
public static void validateAccessToken(String prnOid) {
public static boolean validateAccessToken(String prnOid) {
ExpiringToken token = accessTokensMap.get(prnOid);
if (token == null || token.getAccessToken() == null) {
throw new CredentialsExpiredException("No ESIA access token for prnOid: " + prnOid);
LOGGER.error("No ESIA access token for prnOid: " + prnOid);
return false;
}
else if (token.isExpired()) {
throw new CredentialsExpiredException("ESIA access token expired for prnOid: " + prnOid);
LOGGER.error("ESIA access token expired for prnOid: " + prnOid);
return false;
}
return true;
}
public static void removeExpiredAccessToken() {

View file

@ -2,6 +2,8 @@ package ru.micord.ervu.security.webbpm.jwt;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
@ -11,9 +13,13 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import ru.micord.ervu.security.webbpm.jwt.model.Token;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
import static org.springframework.web.context.request.RequestAttributes.REFERENCE_REQUEST;
@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {
@ -42,16 +48,24 @@ public class JwtAuthenticationProvider implements AuthenticationProvider {
throw new BadCredentialsException("Authentication Failed.", e);
}
if (!jwtTokenService.isValid(token)) {
throw new BadCredentialsException("Auth token is not valid for user " + token.getUserAccountId());
if (jwtTokenService.isValid(token)) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(
REFERENCE_REQUEST);
String[] ids = token.getUserAccountId().split(":");
if (request != null && (request.getRequestURI()
.endsWith("esia/logout") || ids.length == 2)) {
UsernamePasswordAuthenticationToken pwdToken =
UsernamePasswordAuthenticationToken.authenticated(token.getUserAccountId(), null,
Collections.emptyList()
);
return new JwtAuthentication(pwdToken, token.getUserAccountId(), token.getValue());
}
}
UsernamePasswordAuthenticationToken pwdToken =
UsernamePasswordAuthenticationToken.authenticated(token.getUserAccountId(), null,
Collections.emptyList()
);
return new JwtAuthentication(pwdToken, token.getUserAccountId(), token.getValue());
throw new BadCredentialsException(
"Auth token is not valid for user " + token.getUserAccountId());
}
@Override

View file

@ -36,16 +36,12 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
private final SecurityHelper securityHelper;
private final JwtTokenService jwtTokenService;
public JwtAuthenticationFilter(RequestMatcher requestMatcher,
AuthenticationEntryPoint entryPoint,
SecurityHelper securityHelper,
JwtTokenService jwtTokenService) {
SecurityHelper securityHelper) {
super(requestMatcher);
this.entryPoint = entryPoint;
this.securityHelper = securityHelper;
this.jwtTokenService = jwtTokenService;
}
@Override
@ -59,19 +55,11 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
}
try {
authentication = getAuthenticationManager().authenticate(authentication);
if (!httpServletRequest.getRequestURI().endsWith("esia/logout")) {
Token token = jwtTokenService.getToken(tokenStr);
String[] ids = token.getUserAccountId().split(":");
if (ids.length != 2) {
throw new CredentialsExpiredException("Invalid token. User has no ervuId");
}
EsiaTokensStore.validateAccessToken(token.getUserAccountId());
}
}
catch (CredentialsExpiredException e) {
catch (AuthenticationException e) {
LOGGER.warn(e.getMessage());
securityHelper.clearAccessCookies(httpServletResponse);
httpServletResponse.setStatus(401);
LOGGER.warn(e.getMessage());
return null;
}
return authentication;

View file

@ -64,7 +64,7 @@ public class JwtTokenService {
LOGGER.info("Token {} is expired ", token.getValue());
return false;
}
return true;
return EsiaTokensStore.validateAccessToken(token.getUserAccountId());
}
public Token getToken(String token) {