diff --git a/backend/src/main/java/ru/micord/ervu/kafka/ReplyingKafkaConfig.java b/backend/src/main/java/ru/micord/ervu/kafka/ReplyingKafkaConfig.java index 766b4b05..48ded83a 100644 --- a/backend/src/main/java/ru/micord/ervu/kafka/ReplyingKafkaConfig.java +++ b/backend/src/main/java/ru/micord/ervu/kafka/ReplyingKafkaConfig.java @@ -38,8 +38,8 @@ public class ReplyingKafkaConfig { @Value("${ervu-kafka.group-id}") private String groupId; - @Value("${ervu-kafka.reply-connection-timeout:30}") - private long connectionTimeout; + @Value("${ervu-kafka.reply-timeout:30}") + private long replyTimeout; @Bean public ProducerFactory producerFactory() { @@ -114,7 +114,7 @@ public class ReplyingKafkaConfig { ReplyingKafkaTemplate replyingKafkaTemplate = new ReplyingKafkaTemplate<>(pf, container); replyingKafkaTemplate.setCorrelationHeaderName("messageID"); - replyingKafkaTemplate.setDefaultReplyTimeout(Duration.ofSeconds(connectionTimeout)); + replyingKafkaTemplate.setDefaultReplyTimeout(Duration.ofSeconds(replyTimeout)); return replyingKafkaTemplate; } } diff --git a/backend/src/main/java/ru/micord/ervu/security/esia/config/EsiaConfig.java b/backend/src/main/java/ru/micord/ervu/security/esia/config/EsiaConfig.java index 1ed60af1..a97cdd00 100644 --- a/backend/src/main/java/ru/micord/ervu/security/esia/config/EsiaConfig.java +++ b/backend/src/main/java/ru/micord/ervu/security/esia/config/EsiaConfig.java @@ -23,12 +23,6 @@ public class EsiaConfig { @Value("${esia-uri.base-uri:#{null}}") private String esiaBaseUri; - @Value("${esia-uri.code-path:#{null}}") - private String esiaCodePath; - - @Value("${esia-uri.token-path:#{null}}") - private String esiaTokenPath; - @Value("${esia-client-id:#{null}}") private String clientId; @@ -38,9 +32,6 @@ public class EsiaConfig { @Value("${sign-url:#{null}}") private String signUrl; - @Value("${esia-uri.logout:#{null}}") - private String logoutUrl; - @Value("${client-cert-hash:#{null}}") private String clientCertHash; @@ -50,14 +41,6 @@ public class EsiaConfig { @Value("${esia.connection-timeout:30}") private long connectionTimeout; - public String getEsiaCodeUri() { - return esiaCodePath; - } - - public String getEsiaTokenUri() { - return esiaTokenPath; - } - public String getEsiaOrgScopes() { String[] scopeItems = esiaOrgScopes.split(","); return String.join(" ", Arrays.stream(scopeItems).map(item -> orgScopeUrl + item.trim()).toArray(String[]::new)); @@ -84,10 +67,6 @@ public class EsiaConfig { return signUrl; } - public String getLogoutUrl() { - return logoutUrl; - } - public String getClientCertHash() {return clientCertHash;} public long getRequestTimeout() { diff --git a/backend/src/main/java/ru/micord/ervu/security/esia/controller/EsiaController.java b/backend/src/main/java/ru/micord/ervu/security/esia/controller/EsiaController.java index 92197f85..d408ff4d 100644 --- a/backend/src/main/java/ru/micord/ervu/security/esia/controller/EsiaController.java +++ b/backend/src/main/java/ru/micord/ervu/security/esia/controller/EsiaController.java @@ -30,8 +30,8 @@ public class EsiaController { } @RequestMapping(value = "/esia/auth", params = "code", method = RequestMethod.GET) - public boolean esiaAuth(@RequestParam("code") String code, HttpServletResponse response) { - return esiaAuthService.getEsiaTokensByCode(code, response); + public boolean esiaAuth(@RequestParam("code") String code, HttpServletRequest request, HttpServletResponse response) { + return esiaAuthService.getEsiaTokensByCode(code, request, response); } @RequestMapping(value = "/esia/refresh") diff --git a/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java b/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java index 719f3933..7d732cb8 100644 --- a/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java +++ b/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java @@ -11,24 +11,36 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fasterxml.jackson.databind.ObjectMapper; +import ru.micord.ervu.security.esia.config.EsiaConfig; import ervu.service.classifier.RecordAttributesService; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import ru.micord.ervu.kafka.model.*; +import ru.micord.ervu.kafka.model.Brhs; +import ru.micord.ervu.kafka.model.Data; +import ru.micord.ervu.kafka.model.Employee; +import ru.micord.ervu.kafka.model.ErvuOrgResponse; +import ru.micord.ervu.kafka.model.OrgInfo; import ru.micord.ervu.kafka.service.ReplyingKafkaService; -import ru.micord.ervu.security.esia.config.EsiaConfig; -import ru.micord.ervu.security.esia.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 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.EsiaTokenResponse; +import ru.micord.ervu.security.esia.model.FormUrlencoded; +import ru.micord.ervu.security.esia.model.OrganizationModel; import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService; import ru.micord.ervu.security.webbpm.jwt.model.Token; @@ -38,6 +50,9 @@ import ru.micord.ervu.security.webbpm.jwt.model.Token; @Service public class EsiaAuthService { + @Value("${cookie-path:#{null}}") + private String path; + @Autowired private ObjectMapper objectMapper; @@ -88,7 +103,7 @@ public class EsiaAuthService { String responseType = "code"; - String authUrl = esiaConfig.getEsiaCodeUri(); + String authUrl = esiaConfig.getEsiaBaseUri() + "aas/oauth2/v2/ac"; URL url = new URL(authUrl); Map params = mapOf("scope", scope, @@ -139,7 +154,7 @@ public class EsiaAuthService { return uriBuilder.toString(); } - public boolean getEsiaTokensByCode(String esiaAuthCode, HttpServletResponse response) { + public boolean getEsiaTokensByCode(String esiaAuthCode, HttpServletRequest request, HttpServletResponse response) { try { String clientId = esiaConfig.getClientId(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss xx"); @@ -160,7 +175,7 @@ public class EsiaAuthService { parameters.put("code", esiaAuthCode); String clientSecret = signMap(parameters); - String authUrl = esiaConfig.getEsiaTokenUri(); + String authUrl = esiaConfig.getEsiaBaseUri() + "aas/oauth2/v3/te"; String postBody = new FormUrlencoded() .setParameter("client_id", clientId) .setParameter("code", esiaAuthCode) @@ -193,22 +208,29 @@ public class EsiaAuthService { if (!hasRole) { throw new RuntimeException("The user does not have the required role"); } + String cookiePath = null; + if (path != null) { + cookiePath = path; + } + else { + cookiePath = request.getContextPath(); + } Cookie cookie = new Cookie("access_token", accessToken); cookie.setHttpOnly(true); - cookie.setPath("/"); + cookie.setPath(cookiePath); response.addCookie(cookie); String refreshToken = tokenResponse.getRefresh_token(); Cookie cookieRefresh = new Cookie("refresh_token", refreshToken); cookieRefresh.setHttpOnly(true); - cookieRefresh.setPath("/"); + cookieRefresh.setPath(cookiePath); response.addCookie(cookieRefresh); EsiaAccessToken esiaAccessToken = ulDataService.readToken(accessToken); String ervuId = getErvuId(accessToken, esiaAccessToken.getSbj_id()); Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), tokenResponse.getExpires_in(), ervuId); Cookie authToken = new Cookie("auth_token", token.getValue()); - authToken.setPath("/"); + authToken.setPath(cookiePath); authToken.setHttpOnly(true); response.addCookie(authToken); SecurityContextHolder.getContext() @@ -216,7 +238,8 @@ public class EsiaAuthService { new UsernamePasswordAuthenticationToken(esiaAccessToken.getSbj_id(), null)); Cookie isAuth = new Cookie("is_auth", "true"); - isAuth.setPath("/"); + isAuth.setMaxAge(tokenResponse.getExpires_in().intValue()); + isAuth.setPath(cookiePath); response.addCookie(isAuth); return true; } @@ -255,7 +278,7 @@ public class EsiaAuthService { parameters.put("refresh_token", refreshToken); String clientSecret = signMap(parameters); - String authUrl = esiaConfig.getEsiaTokenUri(); + String authUrl = esiaConfig.getEsiaBaseUri() + "aas/oauth2/v3/te"; String postBody = new FormUrlencoded() .setParameter("client_id", clientId) .setParameter("refresh_token", refreshToken) @@ -286,19 +309,26 @@ public class EsiaAuthService { String accessToken = tokenResponse.getAccess_token(); Cookie cookie = new Cookie("access_token", accessToken); cookie.setHttpOnly(true); - cookie.setPath("/"); + String cookiePath = null; + if (path != null) { + cookiePath = path; + } + else { + cookiePath = request.getContextPath(); + } + cookie.setPath(cookiePath); response.addCookie(cookie); String newRefreshToken = tokenResponse.getRefresh_token(); Cookie cookieRefresh = new Cookie("refresh_token", newRefreshToken); cookieRefresh.setHttpOnly(true); - cookieRefresh.setPath("/"); + cookieRefresh.setPath(cookiePath); response.addCookie(cookieRefresh); EsiaAccessToken esiaAccessToken = ulDataService.readToken(accessToken); String ervuId = getErvuId(accessToken, esiaAccessToken.getSbj_id()); Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), tokenResponse.getExpires_in(), ervuId); Cookie authToken = new Cookie("auth_token", token.getValue()); - authToken.setPath("/"); + authToken.setPath(cookiePath); authToken.setHttpOnly(true); response.addCookie(authToken); SecurityContextHolder.getContext() @@ -306,7 +336,8 @@ public class EsiaAuthService { new UsernamePasswordAuthenticationToken(esiaAccessToken.getSbj_id(), null)); Cookie isAuth = new Cookie("is_auth", "true"); - isAuth.setPath("/"); + isAuth.setMaxAge(tokenResponse.getExpires_in().intValue()); + isAuth.setPath(cookiePath); response.addCookie(isAuth); } catch (Exception e) { @@ -354,19 +385,16 @@ public class EsiaAuthService { if (cookie.getName().equals("auth_token") || cookie.getName().equals("refresh_token") || cookie.getName().equals("access_token") || cookie.getName().equals("is_auth")) { cookie.setValue(""); - cookie.setPath("/"); cookie.setMaxAge(0); response.addCookie(cookie); } } - String logoutUrl = esiaConfig.getLogoutUrl(); + String logoutUrl = esiaConfig.getEsiaBaseUri() + "idp/ext/Logout"; String redirectUrl = esiaConfig.getRedirectUrl(); - String redirectUrlEncoded = redirectUrl.replaceAll(":", "%3A") - .replaceAll("/", "%2F"); URL url = new URL(logoutUrl); Map params = mapOf( "client_id", esiaConfig.getClientId(), - "redirect_uri", redirectUrlEncoded); + "redirect_url", redirectUrl); return makeRequest(url, params); } catch (Exception e) { @@ -385,10 +413,15 @@ public class EsiaAuthService { requestReplyTopic, objectMapper.writeValueAsString(orgInfo) ); ErvuOrgResponse ervuOrgResponse = objectMapper.readValue(kafkaResponse, ErvuOrgResponse.class); - Optional ervuIdOptional = Arrays.stream(ervuOrgResponse.getData()).filter(data -> data.getPrnOid().equals(prnOid)).map( - Data::getOrgId_ERVU).findAny(); - return ervuIdOptional.orElseThrow(() -> new RuntimeException( - "No ervuId for prnOid = " + prnOid)); + List listErvuId = Arrays.stream(ervuOrgResponse.getData()).filter(data -> data.getPrnOid().equals(prnOid)).map( + Data::getOrgId_ERVU).toList(); + if (listErvuId.size() > 1) { + throw new RuntimeException("More than one ervuId for prnOid = " + prnOid); + } + else if (listErvuId.isEmpty()) { + throw new RuntimeException("No ervuId for prnOid = " + prnOid); + } + return listErvuId.get(0); } catch (Exception e) { throw new RuntimeException(e); diff --git a/config/patches/default.cli b/config/patches/default.cli index d4a81189..1f7c444d 100644 --- a/config/patches/default.cli +++ b/config/patches/default.cli @@ -44,17 +44,15 @@ xa-data-source add \ /system-property=esia-org-scopes:add(value="org_fullname, org_shortname, org_brhs, org_brhs_ctts, org_brhs_addrs, org_type, org_ogrn, org_inn, org_leg, org_kpp, org_ctts, org_addrs, org_grps, org_emps") /system-property=esia-org-scope-url:add(value="http://esia.gosuslugi.ru/") /system-property=esia-uri.base-uri:add(value="https://esia-portal1.test.gosuslugi.ru/") -/system-property=esia-uri.code-path:add(value="https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v2/ac") -/system-property=esia-uri.token-path:add(value="https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v3/te") /system-property=esia-client-id:add(value="MNSV89") /system-property=esia-redirect-url:add(value="https://lkrp-dev.micord.ru/ul/") /system-property=sign-url:add(value="https://ervu-sign-dev.k8s.micord.ru/sign") -/system-property=esia-uri.logout:add(value="https://esia-portal1.test.gosuslugi.ru/idp/ext/Logout") /system-property=client-cert-hash:add(value="04508B4B0B58776A954A0E15F574B4E58799D74C61EE020B3330716C203E3BDD") /system-property=ervu-kafka.bootstrap-servers:add(value="localhost:9092") /system-property=ervu-kafka.org-reply-topic:add(value="ervu.organization.response") /system-property=ervu-kafka.group-id:add(value="1") /system-property=ervu-kafka.org-request-topic:add(value="ervu.organization.request") +/system-property=ervu-kafka.reply-timeout:add(value="30") /system-property=ervu.cron.load.enable(value="true") /system-property=ervu.cron.load.time(value="0 0 */1 * * *") /system-property=ervu.esnsi.classifier.url.load(value="https://esnsi.gosuslugi.ru/rest/ext/v1/classifiers/11465/file?extension=JSON&encoding=UTF_8"") diff --git a/config/standalone/dev/standalone.xml b/config/standalone/dev/standalone.xml index ea639dfa..e799540e 100644 --- a/config/standalone/dev/standalone.xml +++ b/config/standalone/dev/standalone.xml @@ -70,16 +70,14 @@ - - - + diff --git a/config/tomcat/tomee/conf/webbpm.properties b/config/tomcat/tomee/conf/webbpm.properties index 0fe1d606..d80384e1 100644 --- a/config/tomcat/tomee/conf/webbpm.properties +++ b/config/tomcat/tomee/conf/webbpm.properties @@ -13,3 +13,31 @@ webbpm.mode=production webbpm.jbpm.hibernate_statistics.enabled=false webbpm.cache.hazelcast.hosts=127.0.0.1 webbpm.cache.hazelcast.outbound_port_definitions=5801-5820 + + +file.webdav.upload.url=https://ervu-webdav.k8s.micord.ru +file.webdav.upload.username=test +file.webdav.upload.password=test +kafka.send.message.topic.name=file-upload-v2 +kafka.send.url=http://10.10.31.11:32609 +kafka.send.security.protocol=SASL_PLAINTEXT +kafka.sasl.mechanism=SCRAM-SHA-256 +kafka.send.username=user1 +kafka.send.password=Blfi9d2OFG +ervu.fileupload.max_file_size=5242880 +ervu.fileupload.max_request_size=6291456 +ervu.fileupload.file_size_threshold=0 + +esia-scopes=fullname, snils, id_doc, birthdate, usr_org, openid +esia-org-scopes=org_fullname, org_shortname, org_brhs, org_brhs_ctts, org_brhs_addrs, org_type, org_ogrn, org_inn, org_leg, org_kpp, org_ctts, org_addrs, org_grps, org_emps +esia-org-scope-url=http://esia.gosuslugi.ru/ +esia-uri.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 +client-cert-hash=04508B4B0B58776A954A0E15F574B4E58799D74C61EE020B3330716C203E3BDD +ervu-kafka.bootstrap-servers=localhost:9092 +ervu-kafka.org-reply-topic=ervu.organization.response +ervu-kafka.group-id=1 +ervu-kafka.org-request-topic=ervu.organization.request +ervu-kafka.reply-timeout=30 \ No newline at end of file diff --git a/frontend/src/resources/app-config.json b/frontend/src/resources/app-config.json index 5ebb1eea..5d83fdd5 100644 --- a/frontend/src/resources/app-config.json +++ b/frontend/src/resources/app-config.json @@ -4,8 +4,8 @@ "filter_cleanup_interval_hours": 720, "filter_cleanup_check_period_minutes": 30, "auth_method": "form", - "enable.version.in.url": "false", - "backend.context": "ul", + "enable.version.in.url": "%enable.version.in.url%", + "backend.context": "ul/ul", "guard.confirm_exit": false, "message_service_error_timeout": "", "message_service_warning_timeout": "", diff --git a/frontend/src/ts/modules/app/component/logout.component.ts b/frontend/src/ts/modules/app/component/logout.component.ts index 2c64a6bc..1d7671a6 100644 --- a/frontend/src/ts/modules/app/component/logout.component.ts +++ b/frontend/src/ts/modules/app/component/logout.component.ts @@ -1,8 +1,7 @@ -import {Component, OnInit} from "@angular/core"; +import {ChangeDetectorRef, Component, OnInit} from "@angular/core"; import {Router} from "@angular/router"; import {HttpClient} from "@angular/common/http"; import {CookieService} from "ngx-cookie"; -import {Deferred} from "@webbpm/base-package"; @Component({ moduleId: module.id, @@ -16,7 +15,7 @@ export class LogOutComponent implements OnInit{ constructor(private router: Router, private httpClient: HttpClient, - private cookieService: CookieService) { + private cookieService: CookieService, private cd: ChangeDetectorRef) { } ngOnInit(): void { @@ -28,6 +27,7 @@ export class LogOutComponent implements OnInit{ ]).then(([userFullname, orgUnitName]) => { this.userFullname = userFullname; this.orgUnitName = orgUnitName; + this.cd.markForCheck(); }); } }