SUPPORT-8593: Fix
This commit is contained in:
parent
ff599fc138
commit
c9a1e24c4b
7 changed files with 135 additions and 4 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue