SUPPORT-8593: Fix

This commit is contained in:
Eduard Tihomirov 2024-10-09 07:51:33 +03:00
parent ff599fc138
commit c9a1e24c4b
7 changed files with 135 additions and 4 deletions

View file

@ -50,6 +50,9 @@ public class EsiaConfig {
@Value("${esia.token.url:aas/oauth2/v3/te}")
private String esiaTokenUrl;
@Value("${sign.verify.url}")
private String signVerifyUrl;
public String getEsiaOrgScopes() {
String[] scopeItems = esiaOrgScopes.split(",");
return String.join(" ", Arrays.stream(scopeItems).map(item -> orgScopeUrl + item.trim()).toArray(String[]::new));
@ -97,4 +100,8 @@ public class EsiaConfig {
public String getEsiaTokenUrl() {
return esiaTokenUrl;
}
public String getSignVerifyUrl() {
return signVerifyUrl;
}
}

View file

@ -0,0 +1,55 @@
package ru.micord.ervu.security.esia.model;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Eduard Tihomirov
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsiaHeader implements Serializable {
private static final long serialVersionUID = 1L;
private String alg;
private String ver;
private String sbt;
private String typ;
public String getAlg() {
return alg;
}
public void setAlg(String alg) {
this.alg = alg;
}
public String getVer() {
return ver;
}
public void setVer(String ver) {
this.ver = ver;
}
public String getSbt() {
return sbt;
}
public void setSbt(String sbt) {
this.sbt = sbt;
}
public String getTyp() {
return typ;
}
public void setTyp(String typ) {
this.typ = typ;
}
}

View file

@ -9,6 +9,9 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
@ -37,6 +40,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import ru.micord.ervu.security.esia.model.EmployeeModel;
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
import ru.micord.ervu.security.esia.model.EsiaHeader;
import ru.micord.ervu.security.esia.model.EsiaTokenResponse;
import ru.micord.ervu.security.esia.model.FormUrlencoded;
import ru.micord.ervu.security.esia.model.OrganizationModel;
@ -204,6 +208,10 @@ public class EsiaAuthService {
throw new RuntimeException(tokenResponse.getError_description());
}
String accessToken = tokenResponse.getAccess_token();
boolean verifyResult = verifyToken(accessToken);
if (!verifyResult) {
throw new RuntimeException("Token not valid");
}
boolean hasRole = ulDataService.checkRole(accessToken);
if (!hasRole) {
throw new RuntimeException("The user does not have the required role");
@ -311,6 +319,10 @@ public class EsiaAuthService {
throw new RuntimeException(tokenResponse.getError_description());
}
String accessToken = tokenResponse.getAccess_token();
boolean verifyResult = verifyToken(accessToken);
if (!verifyResult) {
throw new RuntimeException("Token not valid");
}
Cookie cookie = new Cookie("access_token", accessToken);
cookie.setHttpOnly(true);
String cookiePath = null;
@ -493,4 +505,41 @@ public class EsiaAuthService {
employee.setOrgOid(employeeModel.getOrgOid());
return employee;
}
private boolean verifyToken(String accessToken) {
EsiaAccessToken esiaAccessToken = ulDataService.readToken(accessToken);
EsiaHeader esiaHeader = ulDataService.readHeader(accessToken);
if (!esiaHeader.getSbt().equals("access") || !esiaHeader.getTyp().equals("JWT")) {
return false;
}
if (esiaAccessToken.getClient_id().equals(esiaConfig.getClientId()) && esiaAccessToken.getIss().equals(esiaConfig.getEsiaBaseUri())) {
LocalDateTime iatTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(esiaAccessToken.getIat()), ZoneId.systemDefault());
LocalDateTime expTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(esiaAccessToken.getExp()), ZoneId.systemDefault());
LocalDateTime currentTime = LocalDateTime.now();
if (currentTime.isAfter(iatTime) && expTime.isAfter(iatTime)) {
return signVerify(accessToken);
}
}
return false;
}
private boolean signVerify(String accessToken) {
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(esiaConfig.getSignVerifyUrl()))
.header("Content-Type", "text/plain")
.POST(HttpRequest.BodyPublishers.ofString(accessToken, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(esiaConfig.getConnectionTimeout()))
.build()
.send(request, HttpResponse.BodyHandlers.ofString());
errorHandler(response);
return true;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -1,9 +1,6 @@
package ru.micord.ervu.security.esia.service;
import ru.micord.ervu.security.esia.model.EmployeeModel;
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
import ru.micord.ervu.security.esia.model.OrganizationModel;
import ru.micord.ervu.security.esia.model.PersonModel;
import ru.micord.ervu.security.esia.model.*;
/**
* @author Eduard Tihomirov
@ -23,4 +20,6 @@ public interface UlDataService {
EsiaAccessToken readToken(String accessToken);
String getAllUserRoles(String accessToken);
EsiaHeader readHeader(String accessToken);
}

View file

@ -146,6 +146,25 @@ public class UlDataServiceImpl implements UlDataService {
}
}
@Override
public EsiaHeader readHeader(String accessToken) {
try {
byte[] decodedBytes = Base64.getDecoder()
.decode(
accessToken.substring(0, accessToken.indexOf('.'))
.replace('-', '+')
.replace('_', '/'));
String decodedString = new String(decodedBytes);
EsiaHeader esiaHeader = objectMapper.readValue(decodedString,
EsiaHeader.class
);
return esiaHeader;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private OrganizationModel getOrgModel(String orgOid, String accessToken) {
try {
String url = esiaConfig.getEsiaBaseUri() + "rs/orgs/" + orgOid;

View file

@ -28,6 +28,7 @@ ESIA_BASE_URI=https://esia-portal1.test.gosuslugi.ru/
ESIA_CLIENT_ID=MNSV89
ESIA_REDIRECT_URL=https://lkrp-dev.micord.ru/ul/
SIGN_URL=https://ervu-sign-dev.k8s.micord.ru/sign
SIGN_VERIFY_URL=https://ervu-sign-dev.k8s.micord.ru/verify
ESIA_CLIENT_CERT_HASH=04508B4B0B58776A954A0E15F574B4E58799D74C61EE020B3330716C203E3BDD
ERVU_KAFKA_BOOTSTRAP_SERVERS=10.10.31.11:32609
ERVU_KAFKA_ORG_REPLY_TOPIC=ervu.organization.response

View file

@ -94,6 +94,7 @@
<property name="s3.secret_key" value="NUmY0wwRIEyAd98GCKd1cOgJWvLQYAcMMul5Ulu0"/>
<property name="av.kafka.group.id" value="1"/>
<property name="av.kafka.download.response" value="ervu.lkrp.av-fileupload-status"/>
<property name="sign.verify.url" value="https://ervu-sign-dev.k8s.micord.ru/verify"/>
</system-properties>
<management>
<audit-log>