Merge branch 'feature/SUPPORT-9164' into develop

This commit is contained in:
Eduard Tihomirov 2025-05-15 12:49:43 +03:00
commit 02353b75d0
4 changed files with 28 additions and 7 deletions

View file

@ -5,4 +5,5 @@ public class SecurityConstants {
public static final String AUTH_TOKEN = "auth_token";
public static final String AUTH_MARKER = "webbpm.ervu-lkrp-fl";
public static final String PRNS_UUID = "prns_uuid_fl";
public static final String STICKY_SESSION = "stickysession";
}

View file

@ -106,10 +106,12 @@ public class EsiaAuthInfoStore {
});
}
public static void validateState(String prnsUUID, String state) {
public static void validateState(String prnsUUID, String state, String stickySession) {
List<ExpiringState> states = PRNS_UUID_STATE_MAP.get(prnsUUID);
if (states == null) {
throw new EsiaException("State invalid. No state found");
throw new EsiaException(
"State invalid. No state found. PrnsUUID: " + prnsUUID + ". State: " + state
+ ". Sticky session:" + stickySession);
}
long currentTime = System.currentTimeMillis();
@ -117,13 +119,17 @@ public class EsiaAuthInfoStore {
for (ExpiringState expiringState : states) {
if (expiringState.getState().equals(state)) {
if (expiringState.getExpiryTime() < currentTime) {
throw new EsiaException("State invalid. State : " + state + " expired at : " + expiringState.getExpiryTime());
throw new EsiaException(
"State invalid. PrnsUUID: " + prnsUUID + ". Sticky session:" + stickySession
+ ". State : " + state + " expired at : " + expiringState.getExpiryTime());
}
return;
}
statesStringBuilder.append(expiringState.getState(), 0, 8).append(", ");
statesStringBuilder.append(expiringState.getState()).append(", ");
}
throw new EsiaException("State invalid. Backend states :" + statesStringBuilder + " cookie state :" + state);
throw new EsiaException(
"State invalid. PrnsUUID: " + prnsUUID + ". Sticky session:" + stickySession
+ ". Backend states :" + statesStringBuilder + " cookie state :" + state);
}
public static void removeState(String prnsUUID) {

View file

@ -60,6 +60,7 @@ import ru.micord.ervu.security.webbpm.jwt.model.Token;
import ru.cg.webbpm.modules.core.runtime.api.MessageBundleUtils;
import static ru.micord.ervu.security.SecurityConstants.PRNS_UUID;
import static ru.micord.ervu.security.SecurityConstants.STICKY_SESSION;
/**
* @author Eduard Tihomirov
@ -124,6 +125,10 @@ public class EsiaAuthService {
String state = signResponse.getState();
String clientSecret = signResponse.getSignature();
EsiaAuthInfoStore.addState(prnsUUID, state, esiaConfig.getEsiaStateCookieLifeTime(), esiaConfig.getEsiaLoginAttemptsCount());
Cookie stickySession = WebUtils.getCookie(request, STICKY_SESSION);
LOGGER.info("Auth states initialized: PrnsUUID: {}; State: {}; StickySession: {}", prnsUUID, state,
stickySession != null ? stickySession.getValue() : "is null"
);
ResponseCookie prnsCookie = securityHelper.createAccessCookie(PRNS_UUID, prnsUUID)
.maxAge(esiaConfig.getEsiaStateCookieLifeTime())
.build();
@ -519,15 +524,21 @@ public class EsiaAuthService {
private void verifyStateFromCookie(HttpServletRequest request, String state, HttpServletResponse response) {
Cookie cookie = WebUtils.getCookie(request, PRNS_UUID);
Cookie stickySessionCookie = WebUtils.getCookie(request, STICKY_SESSION);
String stickySession = stickySessionCookie != null ? stickySessionCookie.getValue() : "is null";
if (cookie == null) {
throw new EsiaException("State invalid. Cookie not found");
throw new EsiaException(
"State invalid. Cookie not found. State: " + state + ". Sticky session: " + stickySession);
}
String prnsUUID = cookie.getValue();
try {
EsiaAuthInfoStore.validateState(prnsUUID, state);
EsiaAuthInfoStore.validateState(prnsUUID, state, stickySession);
}
finally {
EsiaAuthInfoStore.removeState(prnsUUID);
LOGGER.info(
"Remove all states for prnsUUID: " + prnsUUID + ". State: " + state + ". Sticky session: "
+ stickySession);
securityHelper.clearAccessCookie(response, PRNS_UUID);
}
}

View file

@ -29,6 +29,9 @@ export abstract class AuthGuard implements CanActivate {
let state = params.get('state');
let error = params.get('error');
let errorDescription = params.get('error_description');
if (code || state || error || errorDescription) {
window.history.replaceState({}, document.title, url.pathname);
}
if (isAccess) {
return true;
}