fix logout
This commit is contained in:
parent
f44ef36459
commit
ae6b1f19fe
8 changed files with 61 additions and 43 deletions
|
|
@ -25,9 +25,7 @@ public class LogoutSuccessHandler
|
||||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||||
Authentication authentication) throws IOException {
|
Authentication authentication) throws IOException {
|
||||||
String url = esiaAuthService.logout(request, response);
|
String url = esiaAuthService.logout(request, response);
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.sendRedirect(url);
|
||||||
response.getWriter().write(url);
|
|
||||||
response.getWriter().flush();
|
|
||||||
CsrfToken csrfToken = this.csrfTokenRepository.generateToken(request);
|
CsrfToken csrfToken = this.csrfTokenRepository.generateToken(request);
|
||||||
this.csrfTokenRepository.saveToken(csrfToken, request, response);
|
this.csrfTokenRepository.saveToken(csrfToken, request, response);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import ru.micord.ervu.security.webbpm.jwt.JwtMatcher;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.UnauthorizedEntryPoint;
|
import ru.micord.ervu.security.webbpm.jwt.UnauthorizedEntryPoint;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.filter.JwtAuthenticationFilter;
|
import ru.micord.ervu.security.webbpm.jwt.filter.JwtAuthenticationFilter;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
||||||
|
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
||||||
|
|
||||||
import static ru.micord.ervu.security.SecurityConstants.ESIA_LOGOUT;
|
import static ru.micord.ervu.security.SecurityConstants.ESIA_LOGOUT;
|
||||||
|
|
||||||
|
|
@ -97,9 +98,10 @@ public class SecurityConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JwtAuthenticationFilter jwtAuthenticationFilter(SecurityHelper securityHelper,
|
public JwtAuthenticationFilter jwtAuthenticationFilter(SecurityHelper securityHelper,
|
||||||
AuthenticationManager manager) {
|
AuthenticationManager manager,
|
||||||
|
JwtTokenService jwtTokenService) {
|
||||||
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(
|
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(
|
||||||
new JwtMatcher("/**", PERMIT_ALL), entryPoint(), securityHelper);
|
new JwtMatcher("/**", PERMIT_ALL), entryPoint(), securityHelper, jwtTokenService);
|
||||||
jwtAuthenticationFilter.setAuthenticationManager(manager);
|
jwtAuthenticationFilter.setAuthenticationManager(manager);
|
||||||
return jwtAuthenticationFilter;
|
return jwtAuthenticationFilter;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import ru.micord.ervu.kafka.model.Document;
|
import ru.micord.ervu.kafka.model.Document;
|
||||||
|
|
@ -43,7 +44,6 @@ import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Eduard Tihomirov
|
* @author Eduard Tihomirov
|
||||||
|
|
@ -201,17 +201,13 @@ public class EsiaAuthService {
|
||||||
}
|
}
|
||||||
String accessToken = tokenResponse.getAccess_token();
|
String accessToken = tokenResponse.getAccess_token();
|
||||||
String refreshToken = tokenResponse.getRefresh_token();
|
String refreshToken = tokenResponse.getRefresh_token();
|
||||||
byte[] decodedBytes = Base64.getDecoder()
|
EsiaAccessToken esiaAccessToken = personalDataService.readToken(accessToken);
|
||||||
.decode(
|
|
||||||
accessToken.substring(accessToken.indexOf('.') + 1, accessToken.lastIndexOf('.')));
|
|
||||||
String decodedString = new String(decodedBytes);
|
|
||||||
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString, EsiaAccessToken.class);
|
|
||||||
String prnOid = esiaAccessToken.getSbj_id();
|
String prnOid = esiaAccessToken.getSbj_id();
|
||||||
Long expiresIn = tokenResponse.getExpires_in();
|
Long expiresIn = tokenResponse.getExpires_in();
|
||||||
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
||||||
TokensStore.addRefreshToken(prnOid, refreshToken, expiresIn);
|
TokensStore.addRefreshToken(prnOid, refreshToken, expiresIn);
|
||||||
String ervuId = getErvuId(accessToken);
|
Response ervuIdResponse = getErvuIdResponse(accessToken);
|
||||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId);
|
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuIdResponse.getErvuId());
|
||||||
int expiry = tokenResponse.getExpires_in().intValue();
|
int expiry = tokenResponse.getExpires_in().intValue();
|
||||||
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
|
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
|
||||||
response.addCookie(accessCookie);
|
response.addCookie(accessCookie);
|
||||||
|
|
@ -224,6 +220,12 @@ public class EsiaAuthService {
|
||||||
SecurityContextHolder.setContext(context);
|
SecurityContextHolder.setContext(context);
|
||||||
Cookie authMarkerCookie = securityHelper.createAuthMarkerCookie("true", expiry);
|
Cookie authMarkerCookie = securityHelper.createAuthMarkerCookie("true", expiry);
|
||||||
response.addCookie(authMarkerCookie);
|
response.addCookie(authMarkerCookie);
|
||||||
|
if (ervuIdResponse.getErrorData() != null) {
|
||||||
|
return new ResponseEntity<>(
|
||||||
|
"Доступ запрещен. " + ervuIdResponse.getErrorData().getName(),
|
||||||
|
HttpStatus.FORBIDDEN
|
||||||
|
);
|
||||||
|
}
|
||||||
return ResponseEntity.ok("Authentication successful");
|
return ResponseEntity.ok("Authentication successful");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
@ -279,18 +281,13 @@ public class EsiaAuthService {
|
||||||
}
|
}
|
||||||
String accessToken = tokenResponse.getAccess_token();
|
String accessToken = tokenResponse.getAccess_token();
|
||||||
String newRefreshToken = tokenResponse.getRefresh_token();
|
String newRefreshToken = tokenResponse.getRefresh_token();
|
||||||
|
EsiaAccessToken esiaAccessToken = personalDataService.readToken(accessToken);
|
||||||
byte[] decodedBytes = Base64.getDecoder()
|
|
||||||
.decode(
|
|
||||||
accessToken.substring(accessToken.indexOf('.') + 1, accessToken.lastIndexOf('.')));
|
|
||||||
String decodedString = new String(decodedBytes);
|
|
||||||
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString, EsiaAccessToken.class);
|
|
||||||
String prnOid = esiaAccessToken.getSbj_id();
|
String prnOid = esiaAccessToken.getSbj_id();
|
||||||
Long expiresIn = tokenResponse.getExpires_in();
|
Long expiresIn = tokenResponse.getExpires_in();
|
||||||
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
|
||||||
TokensStore.addRefreshToken(prnOid, newRefreshToken, expiresIn);
|
TokensStore.addRefreshToken(prnOid, newRefreshToken, expiresIn);
|
||||||
String ervuId = getErvuId(accessToken);
|
Response ervuIdResponse = getErvuIdResponse(accessToken);
|
||||||
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId);
|
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuIdResponse.getErvuId());
|
||||||
int expiry = tokenResponse.getExpires_in().intValue();
|
int expiry = tokenResponse.getExpires_in().intValue();
|
||||||
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
|
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
|
||||||
response.addCookie(accessCookie);
|
response.addCookie(accessCookie);
|
||||||
|
|
@ -360,22 +357,14 @@ public class EsiaAuthService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErvuId(String accessToken) {
|
public Response getErvuIdResponse(String accessToken) {
|
||||||
try {
|
try {
|
||||||
PersonModel personModel = personalDataService.getPersonModel(accessToken);
|
PersonModel personModel = personalDataService.getPersonModel(accessToken);
|
||||||
Person person = copyToPerson(personModel);
|
Person person = copyToPerson(personModel);
|
||||||
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
||||||
requestReplyTopic, objectMapper.writeValueAsString(person)
|
requestReplyTopic, objectMapper.writeValueAsString(person)
|
||||||
);
|
);
|
||||||
Response response = objectMapper.readValue(kafkaResponse, Response.class);
|
return objectMapper.readValue(kafkaResponse, Response.class);
|
||||||
if (response.getErrorData() != null) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Error code = " + response.getErrorData().getCode() + ", error name = "
|
|
||||||
+ response.getErrorData().getName());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return response.getErvuId();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,7 @@ public class EsiaPersonalDataService implements PersonalDataService {
|
||||||
@Override
|
@Override
|
||||||
public PersonModel getPersonModel(String accessToken) {
|
public PersonModel getPersonModel(String accessToken) {
|
||||||
try {
|
try {
|
||||||
byte[] decodedBytes = Base64.getDecoder()
|
EsiaAccessToken esiaAccessToken = readToken(accessToken);
|
||||||
.decode(
|
|
||||||
accessToken.substring(accessToken.indexOf('.') + 1, accessToken.lastIndexOf('.')));
|
|
||||||
String decodedString = new String(decodedBytes);
|
|
||||||
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString, EsiaAccessToken.class);
|
|
||||||
String prnsId = esiaAccessToken.getSbj_id();
|
String prnsId = esiaAccessToken.getSbj_id();
|
||||||
PersonModel personModel = getPersonData(prnsId, accessToken);
|
PersonModel personModel = getPersonData(prnsId, accessToken);
|
||||||
personModel.setPassportModel(
|
personModel.setPassportModel(
|
||||||
|
|
@ -88,4 +84,23 @@ public class EsiaPersonalDataService implements PersonalDataService {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EsiaAccessToken readToken(String accessToken) {
|
||||||
|
try {
|
||||||
|
byte[] decodedBytes = Base64.getDecoder()
|
||||||
|
.decode(
|
||||||
|
accessToken.substring(accessToken.indexOf('.') + 1, accessToken.lastIndexOf('.'))
|
||||||
|
.replace('-', '+')
|
||||||
|
.replace('_', '/'));
|
||||||
|
String decodedString = new String(decodedBytes);
|
||||||
|
EsiaAccessToken esiaAccessToken = objectMapper.readValue(decodedString,
|
||||||
|
EsiaAccessToken.class
|
||||||
|
);
|
||||||
|
return esiaAccessToken;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.micord.ervu.security.esia.service;
|
package ru.micord.ervu.security.esia.service;
|
||||||
|
|
||||||
|
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
|
||||||
import ru.micord.ervu.security.esia.model.PersonModel;
|
import ru.micord.ervu.security.esia.model.PersonModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -8,4 +9,5 @@ import ru.micord.ervu.security.esia.model.PersonModel;
|
||||||
public interface PersonalDataService {
|
public interface PersonalDataService {
|
||||||
|
|
||||||
PersonModel getPersonModel(String accessToken);
|
PersonModel getPersonModel(String accessToken);
|
||||||
|
EsiaAccessToken readToken(String accessToken);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import org.springframework.security.web.authentication.AbstractAuthenticationPro
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
|
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
|
||||||
|
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
||||||
|
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
||||||
|
|
||||||
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.extractAuthToken;
|
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.extractAuthToken;
|
||||||
|
|
||||||
|
|
@ -33,25 +35,36 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
|
||||||
|
|
||||||
private final SecurityHelper securityHelper;
|
private final SecurityHelper securityHelper;
|
||||||
|
|
||||||
|
private final JwtTokenService jwtTokenService;
|
||||||
|
|
||||||
public JwtAuthenticationFilter(RequestMatcher requestMatcher,
|
public JwtAuthenticationFilter(RequestMatcher requestMatcher,
|
||||||
AuthenticationEntryPoint entryPoint,
|
AuthenticationEntryPoint entryPoint,
|
||||||
SecurityHelper securityHelper) {
|
SecurityHelper securityHelper,
|
||||||
|
JwtTokenService jwtTokenService) {
|
||||||
super(requestMatcher);
|
super(requestMatcher);
|
||||||
this.entryPoint = entryPoint;
|
this.entryPoint = entryPoint;
|
||||||
this.securityHelper = securityHelper;
|
this.securityHelper = securityHelper;
|
||||||
|
this.jwtTokenService = jwtTokenService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
|
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
|
||||||
HttpServletResponse httpServletResponse)
|
HttpServletResponse httpServletResponse)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
String token = extractAuthToken(httpServletRequest);
|
String tokenStr = extractAuthToken(httpServletRequest);
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (authentication == null) {
|
if (authentication == null) {
|
||||||
authentication = new JwtAuthentication(null, null, token);
|
authentication = new JwtAuthentication(null, null, tokenStr);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
authentication = getAuthenticationManager().authenticate(authentication);
|
authentication = getAuthenticationManager().authenticate(authentication);
|
||||||
|
if (!httpServletRequest.getRequestURI().endsWith("esia/logout")) {
|
||||||
|
Token token = jwtTokenService.getToken(tokenStr);
|
||||||
|
String[] ids = token.getUserAccountId().split(":");
|
||||||
|
if (ids.length != 2) {
|
||||||
|
throw new CredentialsExpiredException("Invalid token. User has no ervuId");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (CredentialsExpiredException e) {
|
catch (CredentialsExpiredException e) {
|
||||||
securityHelper.clearAccessCookies(httpServletResponse);
|
securityHelper.clearAccessCookies(httpServletResponse);
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
<div ngbDropdownMenu *ngIf="getIsAuth()">
|
<div ngbDropdownMenu *ngIf="getIsAuth()">
|
||||||
<a routerLink="/mydata" class="data">Мои данные</a>
|
<a routerLink="/mydata" class="data">Мои данные</a>
|
||||||
<button ngbDropdownItem class="exit" (click)="logout()">Выйти</button>
|
<button ngbDropdownItem class="exit" (click)="logout()">Выйти</button>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="exit" *ngIf="!getIsAuth()" (click)="logout()">Выйти</button>
|
||||||
|
|
@ -28,9 +28,7 @@ export class LogOutComponent implements OnInit{
|
||||||
}
|
}
|
||||||
|
|
||||||
public logout(): void {
|
public logout(): void {
|
||||||
this.httpClient.get<string>("esia/logout").toPromise().then(url => {
|
this.httpClient.get<any>("esia/logout").toPromise();
|
||||||
window.open(url, "_self");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUserFullname(): string {
|
public getUserFullname(): string {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue