feat: add custom authentication exception

This commit is contained in:
vran 2022-03-02 14:28:34 +08:00
parent e09dcfe37e
commit 7303d4d840
7 changed files with 45 additions and 5 deletions

View File

@ -6,10 +6,12 @@ import com.databasir.core.infrastructure.oauth2.OAuthAppService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
@ -32,9 +34,11 @@ public class DatabasirOauth2LoginFilter extends AbstractAuthenticationProcessing
private DatabasirUserDetailService databasirUserDetailService; private DatabasirUserDetailService databasirUserDetailService;
public DatabasirOauth2LoginFilter(AuthenticationManager authenticationManager, public DatabasirOauth2LoginFilter(AuthenticationManager authenticationManager,
OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler) { OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler,
AuthenticationFailureHandler authenticationFailureHandler) {
super(OAUTH_LOGIN_URI, authenticationManager); super(OAUTH_LOGIN_URI, authenticationManager);
this.setAuthenticationSuccessHandler(oAuth2AuthenticationSuccessHandler); this.setAuthenticationSuccessHandler(oAuth2AuthenticationSuccessHandler);
this.setAuthenticationFailureHandler(authenticationFailureHandler);
} }
@Override @Override
@ -45,6 +49,9 @@ public class DatabasirOauth2LoginFilter extends AbstractAuthenticationProcessing
UserDetailResponse userDetailResponse = oAuthAppService.oauthCallback(registrationId, params); UserDetailResponse userDetailResponse = oAuthAppService.oauthCallback(registrationId, params);
UserDetails details = databasirUserDetailService.loadUserByUsername(userDetailResponse.getUsername()); UserDetails details = databasirUserDetailService.loadUserByUsername(userDetailResponse.getUsername());
DatabasirOAuth2Authentication authentication = new DatabasirOAuth2Authentication(details); DatabasirOAuth2Authentication authentication = new DatabasirOAuth2Authentication(details);
if (!userDetailResponse.getEnabled()) {
throw new DisabledException("账号已禁用");
}
authentication.setAuthenticated(true); authentication.setAuthenticated(true);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("login {} success", registrationId); log.debug("login {} success", registrationId);

View File

@ -1,5 +1,6 @@
package com.databasir.api.config.security; package com.databasir.api.config.security;
import com.databasir.core.infrastructure.oauth2.exception.DatabasirAuthenticationException;
import com.databasir.common.JsonData; import com.databasir.common.JsonData;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -39,6 +40,12 @@ public class DatabasirAuthenticationFailureHandler implements AuthenticationFail
String jsonString = objectMapper.writeValueAsString(data); String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value()); response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8)); response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else if (exception instanceof DatabasirAuthenticationException) {
DatabasirAuthenticationException bizException = (DatabasirAuthenticationException) exception;
JsonData<Void> data = JsonData.error("-1", bizException.getMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else { } else {
JsonData<Void> data = JsonData.error("-1", "未登录或未授权用户"); JsonData<Void> data = JsonData.error("-1", "未登录或未授权用户");
String jsonString = objectMapper.writeValueAsString(data); String jsonString = objectMapper.writeValueAsString(data);

View File

@ -10,6 +10,7 @@ import lombok.RequiredArgsConstructor;
public enum DomainErrors implements DatabasirErrors { public enum DomainErrors implements DatabasirErrors {
REFRESH_TOKEN_EXPIRED("X_0001", "refresh token expired"), REFRESH_TOKEN_EXPIRED("X_0001", "refresh token expired"),
INVALID_REFRESH_TOKEN_OPERATION("X_0002", "invalid refresh token operation"), INVALID_REFRESH_TOKEN_OPERATION("X_0002", "invalid refresh token operation"),
NETWORK_ERROR("X_0003", "网络似乎不稳定,请稍后再试"),
NOT_SUPPORT_DATABASE_TYPE("A_10000", "不支持的数据库类型, 请检查项目配置"), NOT_SUPPORT_DATABASE_TYPE("A_10000", "不支持的数据库类型, 请检查项目配置"),
PROJECT_NOT_FOUND("A_10001", "项目不存在"), PROJECT_NOT_FOUND("A_10001", "项目不存在"),

View File

@ -1,6 +1,8 @@
package com.databasir.core.infrastructure.oauth2; package com.databasir.core.infrastructure.oauth2;
import com.databasir.core.domain.DomainErrors;
import com.databasir.core.infrastructure.oauth2.exception.DatabasirAuthenticationException;
import com.databasir.core.infrastructure.remote.github.GithubRemoteService; import com.databasir.core.infrastructure.remote.github.GithubRemoteService;
import com.databasir.dao.enums.OAuthAppType; import com.databasir.dao.enums.OAuthAppType;
import com.databasir.dao.impl.OAuthAppDao; import com.databasir.dao.impl.OAuthAppDao;
@ -51,9 +53,12 @@ public class GithubOauthHandler implements OAuthHandler {
Map<String, String[]> params = context.getCallbackParameters(); Map<String, String[]> params = context.getCallbackParameters();
String code = params.get("code")[0]; String code = params.get("code")[0];
String accessToken = githubRemoteService.getToken(baseUrl, clientId, clientSecret, code) JsonNode tokenNode = githubRemoteService.getToken(baseUrl, clientId, clientSecret, code)
.get("access_token") .get("access_token");
.asText(); if (tokenNode == null) {
throw new DatabasirAuthenticationException(DomainErrors.NETWORK_ERROR.exception());
}
String accessToken = tokenNode.asText();
if (StringUtils.isBlank(accessToken)) { if (StringUtils.isBlank(accessToken)) {
throw new CredentialsExpiredException("授权失效,请重新登陆"); throw new CredentialsExpiredException("授权失效,请重新登陆");
} }

View File

@ -52,6 +52,7 @@ public class OAuthAppService {
user.setNickname(result.getNickname()); user.setNickname(result.getNickname());
user.setEmail(result.getEmail()); user.setEmail(result.getEmail());
user.setAvatar(result.getAvatar()); user.setAvatar(result.getAvatar());
user.setEnabled(true);
user.setPassword(UUID.randomUUID().toString().substring(0, 6)); user.setPassword(UUID.randomUUID().toString().substring(0, 6));
Integer id = userService.create(user); Integer id = userService.create(user);
return userService.get(id); return userService.get(id);

View File

@ -0,0 +1,19 @@
package com.databasir.core.infrastructure.oauth2.exception;
import com.databasir.common.DatabasirException;
import org.springframework.security.core.AuthenticationException;
public class DatabasirAuthenticationException extends AuthenticationException {
public DatabasirAuthenticationException(DatabasirException databasirException) {
super(databasirException.getErrMessage(), databasirException);
}
public DatabasirAuthenticationException(String msg) {
super(msg);
}
public DatabasirAuthenticationException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -61,7 +61,7 @@ public class GithubRemoteService {
try { try {
Response<T> response = call.execute(); Response<T> response = call.execute();
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
log.error("request error: " + call.request()); log.error("request error: " + call.request() + ", response = " + response);
throw new SystemException("Call Remote Error"); throw new SystemException("Call Remote Error");
} else { } else {
T body = response.body(); T body = response.body();