SUPPORT-9164: Patch from fl

This commit is contained in:
Eduard Tihomirov 2025-05-13 10:18:37 +03:00
parent 5a696e94dd
commit 0004f45403
4 changed files with 32 additions and 19 deletions

View file

@ -105,19 +105,24 @@ public class EsiaAuthInfoStore {
});
}
public static boolean containsState(String prnsUUID, String state) {
public static String getNotContainsStateErrorMessage(String prnsUUID, String state) {
List<ExpiringState> states = PRNS_UUID_STATE_MAP.get(prnsUUID);
if (states == null) {
return false;
return "State invalid. No state found for prnsUUID: " + prnsUUID;
}
long currentTime = System.currentTimeMillis();
states.removeIf(expiringState -> expiringState.getExpiryTime() < currentTime);
StringBuilder statesStringBuilder = new StringBuilder();
for (ExpiringState expiringState : states) {
if (expiringState.getState().equals(state)) {
return true;
if (expiringState.getExpiryTime() < currentTime) {
return "State invalid. State : " + state + " expired at : " + expiringState.getExpiryTime();
}
return null;
}
statesStringBuilder.append(expiringState.getState(), 0, 8).append(", ");
}
return false;
return "State invalid. Backend states :" + statesStringBuilder + " cookie state :" + state;
}
public static void removeState(String prnsUUID) {

View file

@ -124,7 +124,7 @@ public class EsiaAuthService {
String clientSecret = signMap(parameters);
EsiaAuthInfoStore.addState(prnsUUID, state, esiaConfig.getEsiaStateCookieLifeTime(), esiaConfig.getEsiaLoginAttemptsCount());
ResponseCookie prnsCookie = securityHelper.createCookie(PRNS_UUID, prnsUUID, "/")
ResponseCookie prnsCookie = securityHelper.createAccessCookie(PRNS_UUID, prnsUUID)
.maxAge(esiaConfig.getEsiaStateCookieLifeTime())
.build();
securityHelper.addResponseCookie(response, prnsCookie);
@ -607,11 +607,9 @@ public class EsiaAuthService {
return "State invalid. Cookie not found";
}
String prnsUUID = cookie.getValue();
if (!EsiaAuthInfoStore.containsState(prnsUUID, state)) {
return "State invalid. State from ESIA not equals with state before";
}
String errorMessage = EsiaAuthInfoStore.getNotContainsStateErrorMessage(prnsUUID, state);
EsiaAuthInfoStore.removeState(prnsUUID);
securityHelper.clearCookie(response, PRNS_UUID, "/");
return null;
securityHelper.clearAccessCookie(response, PRNS_UUID);
return errorMessage;
}
}

View file

@ -26,6 +26,7 @@ public final class SecurityHelper {
private boolean accessCookieSecure;
@Value("${cookie.same.site:Lax}")
private String accessCookieSameSite;
private static final String PRNS_UUID = "prns_uuid";
@PostConstruct
private void init() {
@ -36,9 +37,7 @@ public final class SecurityHelper {
}
public void clearAccessCookies(HttpServletResponse response) {
ResponseCookie emptyAuthToken = createCookie(AUTH_TOKEN, null, accessCookiePath)
.maxAge(0).build();
addResponseCookie(response, emptyAuthToken);
clearCookie(response, AUTH_TOKEN, accessCookiePath);
ResponseCookie emptyAuthMarker = createCookie(AUTH_MARKER, null, "/")
.maxAge(0)
@ -46,6 +45,7 @@ public final class SecurityHelper {
.httpOnly(false)
.build();
addResponseCookie(response, emptyAuthMarker);
clearCookie(response, PRNS_UUID, accessCookiePath);
}
public void addResponseCookie(HttpServletResponse response, ResponseCookie cookie) {
@ -92,4 +92,12 @@ public final class SecurityHelper {
.maxAge(0).build();
addResponseCookie(response, emptyCookie);
}
public ResponseCookie.ResponseCookieBuilder createAccessCookie(String name, String value) {
return createCookie(name, value, accessCookiePath);
}
public void clearAccessCookie(HttpServletResponse response, String name) {
clearCookie(response, name, accessCookiePath);
}
}

View file

@ -7,7 +7,7 @@ import {AuthenticationService} from "../authentication.service";
import {EsiaErrorDetail} from "../EsiaErrorDetail";
import {AccessChecker} from "../AccessChecker";
@Injectable({providedIn:'root'})
@Injectable({providedIn: 'root'})
export abstract class AuthGuard implements CanActivate {
private cspTimeout: number;
@ -61,6 +61,7 @@ export abstract class AuthGuard implements CanActivate {
return false;
}
if (code && state) {
this.progressIndicationService.showProgressBar();
const params = new HttpParams().set('code', code).set('state', state);
this.httpClient.get("esia/auth",
{
@ -68,12 +69,13 @@ export abstract class AuthGuard implements CanActivate {
responseType: 'text',
observe: 'response',
headers: {
"Error-intercept-skip":"true"
"Error-intercept-skip": "true"
}
})
.toPromise()
.then(
() => {
this.progressIndicationService.hideProgressBar();
window.open(url.origin + url.pathname, "_self");
})
.catch(reason => {
@ -81,7 +83,8 @@ export abstract class AuthGuard implements CanActivate {
json.messages.forEach((errorMessage) => {
this.messageService.error(errorMessage, json);
})
});
})
.finally(() => this.progressIndicationService.hideProgressBar());
return false;
}
else {
@ -95,8 +98,7 @@ export abstract class AuthGuard implements CanActivate {
console.error(reason);
}
return false
})
.finally(() => this.progressIndicationService.hideProgressBar());
});
}
private checkAccess(): boolean {