SUPPORT-8579: Fix
This commit is contained in:
parent
1d7e30eb64
commit
d5082c3ce2
8 changed files with 147 additions and 72 deletions
|
|
@ -1,40 +0,0 @@
|
|||
package ru.micord.ervu.security.esia;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Eduard Tihomirov
|
||||
*/
|
||||
public class Tokens {
|
||||
private static final Map<String, String> accessTokensMap = new ConcurrentHashMap<>();
|
||||
private static final Map<String, String> refreshTokensMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static void addAccessToken(String prnOid, String token) {
|
||||
if (token != null) {
|
||||
accessTokensMap.put(prnOid, token);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAccessToken(String prnOid) {
|
||||
return accessTokensMap.get(prnOid);
|
||||
}
|
||||
|
||||
public static void removeAccessToken(String prnOid) {
|
||||
accessTokensMap.remove(prnOid);
|
||||
}
|
||||
|
||||
public static void addRefreshToken(String prnOid, String token) {
|
||||
if (token != null) {
|
||||
refreshTokensMap.put(prnOid, token);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRefreshToken(String prnOid) {
|
||||
return refreshTokensMap.get(prnOid);
|
||||
}
|
||||
|
||||
public static void removeRefreshToken(String prnOid) {
|
||||
refreshTokensMap.remove(prnOid);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ import ru.micord.ervu.kafka.model.Document;
|
|||
import ru.micord.ervu.kafka.model.Person;
|
||||
import ru.micord.ervu.kafka.model.Response;
|
||||
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
||||
import ru.micord.ervu.security.esia.Tokens;
|
||||
import ru.micord.ervu.security.esia.token.TokensStore;
|
||||
import ru.micord.ervu.security.esia.config.EsiaConfig;
|
||||
import ru.micord.ervu.security.esia.model.FormUrlencoded;
|
||||
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
|
||||
|
|
@ -205,10 +205,11 @@ public class EsiaAuthService {
|
|||
String decodedString = new String(decodedBytes);
|
||||
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString, EsiaAccessToken.class);
|
||||
String prnOid = esiaAccessToken.getSbj_id();
|
||||
Tokens.addAccessToken(prnOid, accessToken);
|
||||
Tokens.addRefreshToken(prnOid, refreshToken);
|
||||
Long expiresIn = tokenResponse.getExpires_in();
|
||||
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
||||
TokensStore.addRefreshToken(prnOid, refreshToken, expiresIn);
|
||||
String ervuId = getErvuId(accessToken);
|
||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), tokenResponse.getExpires_in(), ervuId);
|
||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId);
|
||||
Cookie authToken = new Cookie("auth_token", token.getValue());
|
||||
authToken.setPath(cookiePath);
|
||||
authToken.setHttpOnly(true);
|
||||
|
|
@ -234,19 +235,7 @@ public class EsiaAuthService {
|
|||
|
||||
public void getEsiaTokensByRefreshToken(HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
String authTokenCookie = null;
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("auth_token")) {
|
||||
authTokenCookie = cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
Token authJwtToken = jwtTokenService.getToken(authTokenCookie);
|
||||
String[] split = authJwtToken.getUserAccountId().split(":");
|
||||
String userId = split[0];
|
||||
String refreshToken = Tokens.getRefreshToken(userId);
|
||||
String refreshToken = jwtTokenService.getRefreshToken(request);
|
||||
String clientId = esiaConfig.getClientId();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss xx");
|
||||
ZonedDateTime dt = ZonedDateTime.now();
|
||||
|
|
@ -307,10 +296,11 @@ public class EsiaAuthService {
|
|||
String decodedString = new String(decodedBytes);
|
||||
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString, EsiaAccessToken.class);
|
||||
String prnOid = esiaAccessToken.getSbj_id();
|
||||
Tokens.addAccessToken(prnOid, accessToken);
|
||||
Tokens.addRefreshToken(prnOid, newRefreshToken);
|
||||
Long expiresIn = tokenResponse.getExpires_in();
|
||||
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
||||
TokensStore.addRefreshToken(prnOid, newRefreshToken, expiresIn);
|
||||
String ervuId = getErvuId(accessToken);
|
||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), tokenResponse.getExpires_in(), ervuId);
|
||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId);
|
||||
Cookie authToken = new Cookie("auth_token", token.getValue());
|
||||
authToken.setPath(cookiePath);
|
||||
authToken.setHttpOnly(true);
|
||||
|
|
@ -388,8 +378,8 @@ public class EsiaAuthService {
|
|||
Token token = jwtTokenService.getToken(authToken);
|
||||
String[] ids = token.getUserAccountId().split(":");
|
||||
String userId = ids[0];
|
||||
Tokens.removeAccessToken(userId);
|
||||
Tokens.removeRefreshToken(userId);
|
||||
TokensStore.removeAccessToken(userId);
|
||||
TokensStore.removeRefreshToken(userId);
|
||||
String logoutUrl = esiaConfig.getEsiaBaseUri() + esiaConfig.getEsiaLogoutUrl();
|
||||
String redirectUrl = esiaConfig.getRedirectUrl();
|
||||
URL url = new URL(logoutUrl);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.micord.ervu.security.esia.token;
|
||||
|
||||
/**
|
||||
* @author Eduard Tihomirov
|
||||
*/
|
||||
public class ExpiringToken {
|
||||
private String accessToken;
|
||||
private long expiryTime;
|
||||
|
||||
public ExpiringToken(String accessToken, long expiryTime) {
|
||||
this.accessToken = accessToken;
|
||||
this.expiryTime = expiryTime;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public long getExpiryTime() {
|
||||
return expiryTime;
|
||||
}
|
||||
|
||||
public void setExpiryTime(long expiryTime) {
|
||||
this.expiryTime = expiryTime;
|
||||
}
|
||||
|
||||
boolean isExpired() {
|
||||
return System.currentTimeMillis() > expiryTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package ru.micord.ervu.security.esia.token;
|
||||
|
||||
import net.javacrumbs.shedlock.core.SchedulerLock;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Eduard Tihomirov
|
||||
*/
|
||||
@Service
|
||||
public class TokensClearShedulerService {
|
||||
@Scheduled(cron = "${esia.token.clear.cron:0 0 */1 * * *}")
|
||||
@SchedulerLock(name = "clearToken")
|
||||
@Transactional
|
||||
public void load() {
|
||||
TokensStore.removeExpiredRefreshToken();
|
||||
TokensStore.removeExpiredAccessToken();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package ru.micord.ervu.security.esia.token;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Eduard Tihomirov
|
||||
*/
|
||||
public class TokensStore {
|
||||
private static final Map<String, ExpiringToken> accessTokensMap = new ConcurrentHashMap<>();
|
||||
private static final Map<String, ExpiringToken> refreshTokensMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static void addAccessToken(String prnOid, String token, long expiresIn) {
|
||||
if (token != null) {
|
||||
long expiryTime = System.currentTimeMillis() + 1000L * expiresIn;
|
||||
accessTokensMap.put(prnOid, new ExpiringToken(token, expiryTime));
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAccessToken(String prnOid) {
|
||||
return accessTokensMap.get(prnOid).getAccessToken();
|
||||
}
|
||||
|
||||
public static void removeExpiredAccessToken() {
|
||||
for (String key : accessTokensMap.keySet()) {
|
||||
ExpiringToken token = accessTokensMap.get(key);
|
||||
if (token != null && token.isExpired()) {
|
||||
accessTokensMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeExpiredRefreshToken() {
|
||||
for (String key : refreshTokensMap.keySet()) {
|
||||
ExpiringToken token = refreshTokensMap.get(key);
|
||||
if (token != null && token.isExpired()) {
|
||||
refreshTokensMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAccessToken(String prnOid) {
|
||||
accessTokensMap.remove(prnOid);
|
||||
}
|
||||
|
||||
public static void addRefreshToken(String prnOid, String token, long expiresIn) {
|
||||
if (token != null) {
|
||||
long expiryTime = System.currentTimeMillis() + 1000L * expiresIn;
|
||||
refreshTokensMap.put(prnOid, new ExpiringToken(token, expiryTime));
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRefreshToken(String prnOid) {
|
||||
return refreshTokensMap.get(prnOid).getAccessToken();
|
||||
}
|
||||
|
||||
public static void removeRefreshToken(String prnOid) {
|
||||
refreshTokensMap.remove(prnOid);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.micord.ervu.security.esia.Tokens;
|
||||
import ru.micord.ervu.security.esia.token.TokensStore;
|
||||
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
|
||||
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
||||
|
||||
|
|
@ -89,21 +89,29 @@ public class JwtTokenService {
|
|||
}
|
||||
|
||||
public String getAccessToken(HttpServletRequest request) {
|
||||
String authTokenStr = null;
|
||||
return TokensStore.getAccessToken(getUserAccountId(request));
|
||||
}
|
||||
|
||||
public String getRefreshToken(HttpServletRequest request) {
|
||||
return TokensStore.getRefreshToken(getUserAccountId(request));
|
||||
}
|
||||
|
||||
private String getUserAccountId(HttpServletRequest request) {
|
||||
String authToken = null;
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("auth_token")) {
|
||||
authTokenStr = cookie.getValue();
|
||||
authToken = cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (authTokenStr == null) {
|
||||
return null;
|
||||
if (authToken != null) {
|
||||
String[] ids = getToken(authToken).getUserAccountId().split(":");
|
||||
return ids[0];
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("Failed to get auth data. User unauthorized.");
|
||||
}
|
||||
Token authToken = getToken(authTokenStr);
|
||||
String[] split = authToken.getUserAccountId().split(":");
|
||||
String userId = split[0];
|
||||
return Tokens.getAccessToken(userId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,4 +32,6 @@ ERVU_KAFKA_SUBPOENA_EXTRACT_REPLY_TOPIC=ervu.subpoena.info.response
|
|||
ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC=ervu.extract.info.request
|
||||
ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC=ervu.extract.info.response
|
||||
ERVU_KAFKA_EXTRACT_HEADER_CLASS=Request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3
|
||||
ERVU_KAFKA_DOC_LOGIN_MODULE=org.apache.kafka.common.security.scram.ScramLoginModule
|
||||
ERVU_KAFKA_DOC_LOGIN_MODULE=org.apache.kafka.common.security.scram.ScramLoginModule
|
||||
|
||||
ESIA_TOKEN_CLEAR_CRON=0 0 */1 * * *
|
||||
|
|
@ -80,6 +80,7 @@
|
|||
<property name="ervu.kafka.registry.extract.request.topic" value="ervu.extract.info.request"/>
|
||||
<property name="ervu.kafka.registry.extract.reply.topic" value="ervu.extract.info.response"/>
|
||||
<property name="ervu.kafka.extract.header.class" value="request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3"/>
|
||||
<property name="esia.token.clear.cron" value="0 0 */1 * * *"/>
|
||||
</system-properties>
|
||||
<management>
|
||||
<audit-log>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue