fix: response code error when unauthorized

This commit is contained in:
vran 2022-03-10 11:56:30 +08:00
parent 03c19588f2
commit 6a8972bc2b
2 changed files with 22 additions and 5 deletions

View File

@ -1,26 +1,39 @@
package com.databasir.api.config.security; package com.databasir.api.config.security;
import com.databasir.common.JsonData;
import com.databasir.core.domain.DomainErrors;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class DatabasirAuthenticationEntryPoint implements AuthenticationEntryPoint { public class DatabasirAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper;
@Override @Override
public void commence(javax.servlet.http.HttpServletRequest request, public void commence(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response, javax.servlet.http.HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException { AuthenticationException authException) throws IOException, ServletException {
log.warn("验证未通过. 提示信息 - {} - {}", request.getRequestURI(), authException.getMessage()); log.warn("验证未通过. 提示信息 - {} - {} {}", request.getRequestURI(),
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); authException.getClass().getName(),
authException.getMessage());
DomainErrors err = DomainErrors.INVALID_REFRESH_TOKEN_OPERATION;
JsonData<Void> data = JsonData.error(err.getErrCode(), err.getErrMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} }
} }

View File

@ -45,8 +45,8 @@ public class LoginService {
if (login.getRefreshTokenExpireAt().isBefore(LocalDateTime.now())) { if (login.getRefreshTokenExpireAt().isBefore(LocalDateTime.now())) {
throw DomainErrors.REFRESH_TOKEN_EXPIRED.exception(); throw DomainErrors.REFRESH_TOKEN_EXPIRED.exception();
} }
// access-token 未过期就开始刷新有可能是 refresh-token 泄露了删除 refresh-token // access-token 未过期允许一分钟的误差就开始刷新有可能是 refresh-token 泄露了删除 refresh-token
if (login.getAccessTokenExpireAt().isAfter(LocalDateTime.now())) { if (login.getAccessTokenExpireAt().isAfter(LocalDateTime.now().plusMinutes(1))) {
log.warn("invalid access token refresh operation: request = {}, login = {}", request, login); log.warn("invalid access token refresh operation: request = {}, login = {}", request, login);
loginDao.deleteByUserId(login.getUserId()); loginDao.deleteByUserId(login.getUserId());
throw DomainErrors.INVALID_REFRESH_TOKEN_OPERATION.exception(); throw DomainErrors.INVALID_REFRESH_TOKEN_OPERATION.exception();
@ -58,6 +58,10 @@ public class LoginService {
log.warn("user not exists but refresh token exists for " + login.getRefreshToken()); log.warn("user not exists but refresh token exists for " + login.getRefreshToken());
return DomainErrors.INVALID_REFRESH_TOKEN_OPERATION.exception(); return DomainErrors.INVALID_REFRESH_TOKEN_OPERATION.exception();
}); });
if (!user.getEnabled()) {
log.warn("user disabled but refresh token exists for " + login.getRefreshToken());
throw DomainErrors.INVALID_REFRESH_TOKEN_OPERATION.exception();
}
String accessToken = jwtTokens.accessToken(user.getEmail()); String accessToken = jwtTokens.accessToken(user.getEmail());
LocalDateTime accessTokenExpireAt = jwtTokens.expireAt(accessToken); LocalDateTime accessTokenExpireAt = jwtTokens.expireAt(accessToken);
loginDao.updateAccessToken(accessToken, accessTokenExpireAt, user.getId()); loginDao.updateAccessToken(accessToken, accessTokenExpireAt, user.getId());