Merge branch 'feature/SUPPORT-8682_fix_exit' into develop

This commit is contained in:
Eduard Tihomirov 2024-11-26 10:53:43 +03:00
commit b2bac5ba3c
4 changed files with 75 additions and 45 deletions

View file

@ -32,8 +32,8 @@ public class EsiaController {
}
@GetMapping(value = "/esia/auth", params = "code")
public ResponseEntity<?> esiaAuth(@RequestParam("code") String code, HttpServletRequest request, HttpServletResponse response) {
return esiaAuthService.getEsiaTokensByCode(code, request, response);
public ResponseEntity<?> esiaAuth(@RequestParam("code") String code, @RequestParam("error") String error, HttpServletRequest request, HttpServletResponse response) {
return esiaAuthService.getEsiaTokensByCode(code, error, request, response);
}
@PostMapping(value = "/esia/refresh")

View file

@ -15,6 +15,7 @@ import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@ -52,12 +53,15 @@ 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.model.Token;
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUsername;
/**
* @author Eduard Tihomirov
*/
@Service
public class EsiaAuthService {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Long EXPIRES_IN = 3600L;
@Autowired
private ObjectMapper objectMapper;
@Autowired
@ -157,8 +161,16 @@ public class EsiaAuthService {
return uriBuilder.toString();
}
public ResponseEntity<?> getEsiaTokensByCode(String esiaAuthCode, HttpServletRequest request, HttpServletResponse response) {
public ResponseEntity<?> getEsiaTokensByCode(String esiaAuthCode, String error,
HttpServletRequest request, HttpServletResponse response) {
try {
if (error != null) {
createTokenAndAddCookie(response, null, null, false, EXPIRES_IN);
return new ResponseEntity<>(
"Произошла неизвестная ошибка. Обратитесь к системному администратору",
HttpStatus.FORBIDDEN
);
}
String clientId = esiaConfig.getClientId();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss xx");
ZonedDateTime dt = ZonedDateTime.now();
@ -223,20 +235,7 @@ public class EsiaAuthService {
Long expiresIn = tokenResponse.getExpires_in();
TokensStore.addAccessToken(prnOid, esiaAccessTokenStr, expiresIn);
TokensStore.addRefreshToken(prnOid, esiaRefreshTokenStr, expiresIn);
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId, hasRole);
int expiry = tokenResponse.getExpires_in().intValue();
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
response.addCookie(accessCookie);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthentication jwtAuthentication = new JwtAuthentication(usernamePasswordAuthenticationToken,
esiaAccessToken.getSbj_id(), token.getValue());
authenticationManager.authenticate(jwtAuthentication);
context.setAuthentication(jwtAuthentication);
SecurityContextHolder.setContext(context);
Cookie authMarkerCookie = securityHelper.createAuthMarkerCookie("true", expiry);
response.addCookie(authMarkerCookie);
createTokenAndAddCookie(response, esiaAccessToken.getSbj_id(), ervuId, hasRole, expiresIn);
if (!hasRole) {
LOGGER.error("The user with id = " + prnOid + " does not have the required role");
return new ResponseEntity<>(
@ -247,7 +246,14 @@ public class EsiaAuthService {
return ResponseEntity.ok("Authentication successful");
}
catch (Exception e) {
throw new RuntimeException(e);
createTokenAndAddCookie(response, null, null, false, EXPIRES_IN);
String messageId = getMessageId(e);
String messageWithId = String.format("[%s] %s", messageId, e.getMessage());
LOGGER.error(messageWithId, e);
return new ResponseEntity<>(
"Произошла ошибка " + messageId + ". Обратитесь к системному администратору",
HttpStatus.FORBIDDEN
);
}
}
@ -309,19 +315,7 @@ public class EsiaAuthService {
TokensStore.addAccessToken(prnOid, accessToken, expiresIn);
TokensStore.addRefreshToken(prnOid, newRefreshToken, expiresIn);
String ervuId = getErvuId(accessToken, prnOid);
Token token = jwtTokenService.createAccessToken(esiaAccessToken.getSbj_id(), expiresIn, ervuId, true);
int expiry = tokenResponse.getExpires_in().intValue();
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiry);
response.addCookie(accessCookie);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthentication authentication = new JwtAuthentication(usernamePasswordAuthenticationToken,
esiaAccessToken.getSbj_id(), token.getValue());
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
Cookie authMarkerCookie = securityHelper.createAuthMarkerCookie("true", expiry);
response.addCookie(authMarkerCookie);
createTokenAndAddCookie(response, esiaAccessToken.getSbj_id(), ervuId, true, expiresIn);
}
catch (Exception e) {
throw new RuntimeException(e);
@ -457,4 +451,28 @@ public class EsiaAuthService {
employee.setOrgOid(employeeModel.getOrgOid());
return employee;
}
private String getMessageId(Exception exception) {
return Integer.toUnsignedString(Objects
.hashCode(getCurrentUsername()), 36)
+ "-"
+ Integer.toUnsignedString(exception.hashCode(), 36);
}
private void createTokenAndAddCookie(HttpServletResponse response, String userId, String ervuId,
Boolean hasRole, Long expiresIn) {
Token token = jwtTokenService.createAccessToken(userId, expiresIn, ervuId, hasRole);
Cookie accessCookie = securityHelper.createAccessCookie(token.getValue(), expiresIn.intValue());
response.addCookie(accessCookie);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthentication authentication = new JwtAuthentication(usernamePasswordAuthenticationToken,
userId, token.getValue());
context.setAuthentication(authentication);
authenticationManager.authenticate(authentication);
SecurityContextHolder.setContext(context);
Cookie authMarkerCookie = securityHelper.createAuthMarkerCookie("true", expiresIn.intValue());
response.addCookie(authMarkerCookie);
}
}

View file

@ -5,6 +5,8 @@ import java.nio.charset.StandardCharsets;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.util.WebUtils;
@ -42,4 +44,12 @@ public final class SecurityUtil {
Cookie cookie = WebUtils.getCookie(httpRequest, AUTH_TOKEN);
return cookie != null ? cookie.getValue() : null;
}
public static String getCurrentUsername() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
return auth.getName();
}
return null;
}
}

View file

@ -34,18 +34,8 @@ export abstract class AuthGuard implements CanActivate {
if (isAccess) {
return true;
}
else if (error) {
let userErrorMessage = 'Произошла неизвестная ошибка. Обратитесь к системному администратору';
let errorCode = this.extractCode(errorDescription);
if (errorCode) {
userErrorMessage = EsiaErrorDetail.getDescription(errorCode);
}
let errorMessage = error + ', error description = ' + errorDescription;
this.messageService.error(userErrorMessage)
throw new Error(errorMessage);
}
else if (code) {
const params = new HttpParams().set('code', code);
if (code || error) {
const params = new HttpParams().set('code', code).set('error', error);
this.httpClient.get("esia/auth",
{
params: params, responseType: 'text', observe: 'response', headers: {
@ -61,8 +51,20 @@ export abstract class AuthGuard implements CanActivate {
let errorMessage = reason.error.messages != null
? reason.error.messages
: reason.error.replaceAll('\\', '');
this.messageService.error(errorMessage);
console.error(reason);
if (error) {
errorMessage = 'Произошла неизвестная ошибка. Обратитесь к системному администратору';
let errorCode = this.extractCode(errorDescription);
if (errorCode) {
errorMessage = EsiaErrorDetail.getDescription(errorCode);
}
let consoleError = error + ', error description = ' + errorDescription;
this.messageService.error(errorMessage);
console.error(consoleError);
}
else {
this.messageService.error(errorMessage);
console.error(reason);
}
});
return false;
}