oauth-重写-Oauth异常
This commit is contained in:
@@ -640,7 +640,7 @@ public enum BusiStatus {
|
||||
|
||||
DEVICE_ERROR(500, "设备为空"),
|
||||
|
||||
|
||||
REGISTER_NETEASE_FAIL(500, "注册云信IM账号失败"),
|
||||
UPDATE_NETEASE_ROOM_FAIL(500, "云信聊天室信息更新失败"),
|
||||
|
||||
|
||||
|
@@ -1,84 +0,0 @@
|
||||
package com.accompany.oauth.constant;
|
||||
|
||||
/**
|
||||
* OAuth常量类
|
||||
*
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class OAuthConstants {
|
||||
|
||||
/**
|
||||
* Token相关常量
|
||||
*/
|
||||
public static final class Token {
|
||||
public static final String BEARER_PREFIX = "Bearer ";
|
||||
public static final String ACCESS_TOKEN = "access_token";
|
||||
public static final String REFRESH_TOKEN = "refresh_token";
|
||||
public static final String TOKEN_TYPE = "token_type";
|
||||
public static final String EXPIRES_IN = "expires_in";
|
||||
public static final String SCOPE = "scope";
|
||||
|
||||
// Redis Key前缀
|
||||
public static final String ACCESS_TOKEN_PREFIX = "oauth:access_token:";
|
||||
public static final String REFRESH_TOKEN_PREFIX = "oauth:refresh_token:";
|
||||
public static final String USER_TOKEN_PREFIX = "oauth:user_token:";
|
||||
|
||||
private Token() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权类型常量
|
||||
*/
|
||||
public static final class GrantType {
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String VERIFY_CODE = "verify_code";
|
||||
public static final String EMAIL = "email";
|
||||
public static final String OPENID = "openid";
|
||||
public static final String REFRESH_TOKEN = "refresh_token";
|
||||
|
||||
private GrantType() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP头常量
|
||||
*/
|
||||
public static final class Headers {
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
public static final String CLIENT_ID = "Client-Id";
|
||||
public static final String DEVICE_ID = "Device-Id";
|
||||
public static final String USER_AGENT = "User-Agent";
|
||||
|
||||
private Headers() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限范围常量
|
||||
*/
|
||||
public static final class Scope {
|
||||
public static final String READ = "read";
|
||||
public static final String WRITE = "write";
|
||||
public static final String ALL = "read write";
|
||||
|
||||
private Scope() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误码常量
|
||||
*/
|
||||
public static final class ErrorCode {
|
||||
public static final String INVALID_REQUEST = "invalid_request";
|
||||
public static final String INVALID_CLIENT = "invalid_client";
|
||||
public static final String INVALID_GRANT = "invalid_grant";
|
||||
public static final String UNAUTHORIZED_CLIENT = "unauthorized_client";
|
||||
public static final String UNSUPPORTED_GRANT_TYPE = "unsupported_grant_type";
|
||||
public static final String INVALID_SCOPE = "invalid_scope";
|
||||
public static final String ACCESS_DENIED = "access_denied";
|
||||
public static final String INVALID_TOKEN = "invalid_token";
|
||||
public static final String TOKEN_EXPIRED = "token_expired";
|
||||
|
||||
private ErrorCode() {}
|
||||
}
|
||||
|
||||
private OAuthConstants() {}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package com.accompany.oauth.exception;
|
||||
|
||||
import com.accompany.oauth.constant.OAuthConstants;
|
||||
|
||||
/**
|
||||
* 认证异常
|
||||
*
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class AuthenticationException extends OAuthException {
|
||||
|
||||
public AuthenticationException(String errorDescription) {
|
||||
super(OAuthConstants.ErrorCode.ACCESS_DENIED, errorDescription);
|
||||
}
|
||||
|
||||
public AuthenticationException(String errorDescription, Throwable cause) {
|
||||
super(OAuthConstants.ErrorCode.ACCESS_DENIED, errorDescription, cause);
|
||||
}
|
||||
|
||||
public static AuthenticationException invalidCredentials() {
|
||||
return new AuthenticationException("用户名或密码错误");
|
||||
}
|
||||
|
||||
public static AuthenticationException userNotFound() {
|
||||
return new AuthenticationException("用户不存在");
|
||||
}
|
||||
|
||||
public static AuthenticationException userFrozen() {
|
||||
return new AuthenticationException("用户已被冻结");
|
||||
}
|
||||
|
||||
public static AuthenticationException invalidVerifyCode() {
|
||||
return new AuthenticationException("验证码错误或已过期");
|
||||
}
|
||||
}
|
@@ -1,5 +1,9 @@
|
||||
package com.accompany.oauth.exception;
|
||||
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* OAuth认证异常基类
|
||||
*
|
||||
@@ -8,26 +12,39 @@ package com.accompany.oauth.exception;
|
||||
*/
|
||||
public class OAuthException extends RuntimeException {
|
||||
|
||||
private final String errorCode;
|
||||
private final String errorDescription;
|
||||
private BusiStatus busiStatus;
|
||||
private Map<String, String> additionalInformation;
|
||||
|
||||
public OAuthException(String errorCode, String errorDescription) {
|
||||
super(errorDescription);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDescription = errorDescription;
|
||||
public OAuthException(BusiStatus busiStatus) {
|
||||
super(busiStatus.getMessage());
|
||||
this.busiStatus = busiStatus;
|
||||
}
|
||||
|
||||
public OAuthException(String errorCode, String errorDescription, Throwable cause) {
|
||||
super(errorDescription, cause);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDescription = errorDescription;
|
||||
|
||||
public OAuthException(BusiStatus busiStatus, String message) {
|
||||
super(message);
|
||||
this.busiStatus = busiStatus;
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
|
||||
public OAuthException(BusiStatus busiStatus, Map<String, String> additionalInformation) {
|
||||
super(busiStatus.getMessage());
|
||||
this.busiStatus = busiStatus;
|
||||
this.additionalInformation = additionalInformation;
|
||||
}
|
||||
|
||||
public String getErrorDescription() {
|
||||
return errorDescription;
|
||||
|
||||
public BusiStatus getBusiStatus() {
|
||||
return busiStatus;
|
||||
}
|
||||
|
||||
public void setBusiStatus(BusiStatus busiStatus) {
|
||||
this.busiStatus = busiStatus;
|
||||
}
|
||||
|
||||
public Map<String, String> getAdditionalInformation() {
|
||||
return additionalInformation;
|
||||
}
|
||||
|
||||
public void setAdditionalInformation(Map<String, String> additionalInformation) {
|
||||
this.additionalInformation = additionalInformation;
|
||||
}
|
||||
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package com.accompany.oauth.exception;
|
||||
|
||||
import com.accompany.oauth.constant.OAuthConstants;
|
||||
|
||||
/**
|
||||
* Token异常
|
||||
*
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class TokenException extends OAuthException {
|
||||
|
||||
public TokenException(String errorCode, String errorDescription) {
|
||||
super(errorCode, errorDescription);
|
||||
}
|
||||
|
||||
public TokenException(String errorCode, String errorDescription, Throwable cause) {
|
||||
super(errorCode, errorDescription, cause);
|
||||
}
|
||||
|
||||
public static TokenException invalidToken() {
|
||||
return new TokenException(OAuthConstants.ErrorCode.INVALID_TOKEN, "无效的Token");
|
||||
}
|
||||
|
||||
public static TokenException tokenExpired() {
|
||||
return new TokenException(OAuthConstants.ErrorCode.TOKEN_EXPIRED, "Token已过期");
|
||||
}
|
||||
|
||||
public static TokenException invalidRefreshToken() {
|
||||
return new TokenException(OAuthConstants.ErrorCode.INVALID_GRANT, "无效的刷新Token");
|
||||
}
|
||||
|
||||
public static TokenException tokenGenerationFailed() {
|
||||
return new TokenException(OAuthConstants.ErrorCode.INVALID_REQUEST, "Token生成失败");
|
||||
}
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package com.accompany.oauth.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -9,6 +11,7 @@ import java.util.Set;
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class TokenValidation {
|
||||
|
||||
/**
|
||||
@@ -40,9 +43,7 @@ public class TokenValidation {
|
||||
* 错误信息
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
public TokenValidation() {
|
||||
}
|
||||
|
||||
|
||||
public TokenValidation(boolean valid) {
|
||||
this.valid = valid;
|
||||
@@ -55,70 +56,5 @@ public class TokenValidation {
|
||||
validation.setClientId(clientId);
|
||||
return validation;
|
||||
}
|
||||
|
||||
public static TokenValidation invalid(String errorMessage) {
|
||||
TokenValidation validation = new TokenValidation(false);
|
||||
validation.setErrorMessage(errorMessage);
|
||||
return validation;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Set<String> getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public void setScopes(Set<String> scopes) {
|
||||
this.scopes = scopes;
|
||||
}
|
||||
|
||||
public Date getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
public void setExpirationTime(Date expirationTime) {
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TokenValidation{" +
|
||||
"valid=" + valid +
|
||||
", userId=" + userId +
|
||||
", scopes=" + scopes +
|
||||
", expirationTime=" + expirationTime +
|
||||
", clientId='" + clientId + '\'' +
|
||||
", errorMessage='" + errorMessage + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
@@ -4,11 +4,11 @@ import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.device.DeviceInfo;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.enumeration.PartitionEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.model.Account;
|
||||
import com.accompany.core.model.AccountLoginRecord;
|
||||
import com.accompany.core.model.Users;
|
||||
import com.accompany.core.mybatismapper.PrettyNumberRecordMapper;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.core.service.account.AccountBlockCheckService;
|
||||
import com.accompany.core.service.account.AccountService;
|
||||
@@ -17,8 +17,10 @@ import com.accompany.core.service.account.UserAppService;
|
||||
import com.accompany.core.service.common.JedisService;
|
||||
import com.accompany.core.service.region.RegionNetworkService;
|
||||
import com.accompany.core.service.user.UsersBaseService;
|
||||
import com.accompany.core.util.I18NMessageSourceUtil;
|
||||
import com.accompany.email.service.EmailService;
|
||||
import com.accompany.oauth.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.sms.service.SmsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -28,6 +30,9 @@ import org.springframework.util.StringUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.accompany.core.enumeration.I18nAlertEnum.ACCOUNT_LOGIN_BLOCK_MSG;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -82,12 +87,9 @@ public class AccountLoginService {
|
||||
Long blockEndTime = accountBlockCheckService.checkReturnEndTime(account.getErbanNo(), account.getPhone(), account.getEmail(), deviceId, ip);
|
||||
//检查账号、设备号、号段是否封禁
|
||||
if (null != blockEndTime){
|
||||
//todo
|
||||
//CustomOAuth2Exception exception = new CustomOAuth2Exception(CustomOAuth2Exception.ACCOUNT_ERROR, "");
|
||||
//Integer partitionId = null != users? users.getPartitionId(): PartitionEnum.ENGLISH.getId();
|
||||
//exception.addAdditionalInformation("reason", I18NMessageSourceUtil.getMessage(ACCOUNT_LOGIN_BLOCK_MSG, new Object[]{account.getErbanNo()}, partitionId));
|
||||
//exception.addAdditionalInformation("date", String.valueOf(blockEndTime));
|
||||
//throw exception;
|
||||
Integer partitionId = null != users? users.getPartitionId(): PartitionEnum.ENGLISH.getId();
|
||||
Map<String, String> tipMap = Map.of("reason", I18NMessageSourceUtil.getMessage(ACCOUNT_LOGIN_BLOCK_MSG, new Object[]{users.getErbanNo()}, partitionId), "date", String.valueOf(blockEndTime));
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_ERROR, tipMap);
|
||||
}
|
||||
|
||||
accountManageService.checkAccountCancel(uid);
|
||||
@@ -158,18 +160,14 @@ public class AccountLoginService {
|
||||
return;
|
||||
}
|
||||
if (!StringUtils.hasText(code)) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.VERIFY_CODE_ERROR,
|
||||
// BusiStatus.VERIFY_CODE_ERROR.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.VERIFY_CODE_ERROR);
|
||||
}
|
||||
|
||||
boolean verifyResult = LoginTypeEnum.PHONE.getValue() == loginType.getValue()?
|
||||
smsService.verifySmsCode(account.getPhone(), code):
|
||||
emailService.verifyEmailCode(account.getEmail(), code);
|
||||
if (!verifyResult) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.VERIFY_CODE_ERROR,
|
||||
// BusiStatus.VERIFY_CODE_ERROR.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.VERIFY_CODE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,8 +187,7 @@ public class AccountLoginService {
|
||||
String countValue = jedisService.hget(cacheKey, username);
|
||||
Long currCount = StringUtils.isEmpty(countValue) ? 0L : Long.parseLong(countValue);
|
||||
if (currCount >= maxCount) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.PWD_WRONG_OVER_LIMIT, BusiStatus.PWD_WRONG_OVER_LIMIT.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.PWD_WRONG_OVER_LIMIT);
|
||||
}
|
||||
|
||||
if (!password.equals(accountPassword)) {
|
||||
@@ -200,12 +197,10 @@ public class AccountLoginService {
|
||||
}
|
||||
|
||||
if (currCount >= maxCount) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.PWD_WRONG_OVER_LIMIT, BusiStatus.PWD_WRONG_OVER_LIMIT.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.PWD_WRONG_OVER_LIMIT);
|
||||
} else {
|
||||
Long remainCount = maxCount - currCount;
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.PASSWORD_ERROR, String.format(BusiStatus.PASSWORD_ERROR_COUNT.getReasonPhrase(), remainCount));
|
||||
throw new OAuthException(BusiStatus.PASSWORD_ERROR_COUNT, String.format(BusiStatus.PASSWORD_ERROR_COUNT.getMessage(), remainCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -29,9 +29,9 @@ import com.accompany.email.service.EmailService;
|
||||
import com.accompany.oauth.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth.dto.DayIpMaxRegisterLimitConfig;
|
||||
import com.accompany.oauth.dto.RepeatedDeviceIpRegisterLimitConfig;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.sms.service.SmsService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -39,6 +39,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author liuguofu
|
||||
@@ -210,22 +211,19 @@ public class AccountManageService {
|
||||
|
||||
private void checkRegisterLimit(String deviceId, String ipAddress) {
|
||||
if (!StringUtils.hasText(deviceId)) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.DEVICE_ERROR.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.DEVICE_ERROR);
|
||||
}
|
||||
|
||||
RepeatedDeviceIpRegisterLimitConfig repeatedConfig = getRepeatedDeviceIpLimitConfig();
|
||||
if (repeatedConfig.isOpen()) {
|
||||
long repeatedDeviceNum = accountService.lambdaQuery().eq(Account::getDeviceId, deviceId).count();
|
||||
if (repeatedDeviceNum >= repeatedConfig.getRepeatedDeviceNumLimit()) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.REGISTER_FREQUENT);
|
||||
}
|
||||
|
||||
long repeatedIpNum = accountService.lambdaQuery().eq(Account::getRegisterIp, ipAddress).count();
|
||||
if (repeatedIpNum >= repeatedConfig.getRepeatedIpNumLimit()) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.REGISTER_FREQUENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,16 +232,11 @@ public class AccountManageService {
|
||||
if (config.getOpen()) {
|
||||
long count = accountService.getRegisterIpCountByOneDay(ipAddress);
|
||||
if (count >= config.getMax()) {
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.REGISTER_FREQUENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String encryptPassword(String password) {
|
||||
return MD5.getMD5(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过手机号码注册,独立账号系统,不掺杂业务
|
||||
*
|
||||
@@ -280,7 +273,7 @@ public class AccountManageService {
|
||||
if (tokenRet.getCode() != 200) {
|
||||
log.error("手机号码phone=" + phone + "注册异常,异常原因code=" + tokenRet.getCode());
|
||||
log.info("手机号码phone=" + phone + "注册异常,异常原因code=" + tokenRet.getCode());
|
||||
throw new ServiceException("手机号码phone=" + phone + "注册异常,异常原因code=" + tokenRet.getCode());
|
||||
throw new OAuthException(BusiStatus.REGISTER_NETEASE_FAIL);
|
||||
}
|
||||
|
||||
return account;
|
||||
@@ -294,7 +287,7 @@ public class AccountManageService {
|
||||
Account account = new Account();
|
||||
account.setEmail(email);
|
||||
if (StringUtils.hasText(password)) {
|
||||
account.setPassword(encryptPassword(password));
|
||||
account.setPassword(MD5.getMD5(password));
|
||||
}
|
||||
account.setNeteaseToken(UUIDUtil.get());
|
||||
account.setLastLoginTime(date);
|
||||
@@ -312,7 +305,7 @@ public class AccountManageService {
|
||||
TokenRet tokenRet = netEaseService.createNetEaseAcc(uidStr, account.getNeteaseToken(), "", "", null);
|
||||
if (tokenRet.getCode() != 200) {
|
||||
log.error("邮件email {} 注册异常,异常原因code {}", email, tokenRet.getCode());
|
||||
throw new ServiceException(BusiStatus.SERVERBUSY);
|
||||
throw new OAuthException(BusiStatus.REGISTER_NETEASE_FAIL);
|
||||
}
|
||||
|
||||
return account;
|
||||
@@ -350,27 +343,27 @@ public class AccountManageService {
|
||||
if (phone.contains("*")) {
|
||||
Account account = accountService.getById(uid);
|
||||
if (account == null) {
|
||||
throw new ServiceException(BusiStatus.USER_NOT_EXISTED);
|
||||
throw new OAuthException(BusiStatus.USER_NOT_EXISTED);
|
||||
}
|
||||
phone = account.getPhone();
|
||||
if (!CommonUtil.checkPhoneFormat(account.getPhoneAreaCode(), account.getPhone())) {
|
||||
throw new ServiceException(BusiStatus.ACCOUNT_NOT_BIND_PHONE);
|
||||
throw new OAuthException(BusiStatus.PHONE_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
long count = accountService.countByPhone(phone);
|
||||
if (count > 1L) {
|
||||
throw new ServiceException(BusiStatus.PHONE_BIND_TOO_MANY_ACCOUNT);
|
||||
throw new OAuthException(BusiStatus.PHONE_BIND_TOO_MANY_ACCOUNT);
|
||||
}
|
||||
|
||||
Account account = accountService.getAccountByPhone(phone);
|
||||
if (null == account || (uid != null && !account.getUid().equals(uid))) {
|
||||
throw new ServiceException(BusiStatus.PHONE_BIND_ERROR);
|
||||
throw new OAuthException(BusiStatus.PHONE_BIND_ERROR);
|
||||
}
|
||||
|
||||
//检验验证码
|
||||
if (!smsService.verifySmsCodeByCache(phone, resetCode)) {
|
||||
throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_CODE);
|
||||
throw new OAuthException(BusiStatus.INVALID_IDENTIFYING_CODE);
|
||||
}
|
||||
|
||||
accountService.resetAccountPwd(account.getUid(), password);
|
||||
@@ -397,19 +390,19 @@ public class AccountManageService {
|
||||
|
||||
long count = accountService.countByEmail(email);
|
||||
if (count > 1L) {
|
||||
throw new ServiceException(BusiStatus.EMAIL_BIND_TOO_MANY_ACCOUNT);
|
||||
throw new OAuthException(BusiStatus.EMAIL_BIND_TOO_MANY_ACCOUNT);
|
||||
}
|
||||
|
||||
Account account = accountService.getAccountByEmail(email);
|
||||
if (null == account) {
|
||||
throw new ServiceException(BusiStatus.ACCOUNT_NOT_BIND_EMAIL);
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_NOT_BIND_EMAIL);
|
||||
} else if (null != uid && !account.getUid().equals(uid)) {
|
||||
throw new ServiceException(BusiStatus.ACCOUNT_BIND_EMAIL_DIFF);
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_BIND_EMAIL_DIFF);
|
||||
}
|
||||
|
||||
//检验验证码
|
||||
if (!emailService.verifyCodeByCache(email, code)) {
|
||||
throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_EMAIL_CODE);
|
||||
throw new OAuthException(BusiStatus.INVALID_IDENTIFYING_EMAIL_CODE);
|
||||
}
|
||||
|
||||
accountService.resetAccountPwd(account.getUid(), password);
|
||||
@@ -429,7 +422,7 @@ public class AccountManageService {
|
||||
}
|
||||
|
||||
String oldPwd = account.getPassword();
|
||||
password = encryptPassword(password);
|
||||
password = MD5.getMD5(password);
|
||||
if (!StringUtils.hasText(password) || !password.equals(oldPwd)) {
|
||||
throw new ServiceException(BusiStatus.OLD_PASSWORD_ERROR);
|
||||
}
|
||||
@@ -480,29 +473,25 @@ public class AccountManageService {
|
||||
if (ObjectUtil.isNull(userCancelRecord)) {
|
||||
//获取不到注销账号信息
|
||||
log.info("获取不到用户{}注销信息", uid);
|
||||
//todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.ACCOUNT_CANCEL_INFO_NOT_EXIST, BusiStatus.ACCOUNT_CANCEL_INFO_NOT_EXIST.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_CANCEL_INFO_NOT_EXIST);
|
||||
}
|
||||
|
||||
|
||||
log.info("检测到注销账号{}昵称{}于{}尝试登录", users.getErbanNo(), userCancelRecord.getNick(), DateTimeUtil.convertDate(userCancelRecord.getUpdateTime()));
|
||||
//todo
|
||||
//CustomOAuth2Exception exception = new CustomOAuth2Exception(CustomOAuth2Exception.ACCOUNT_CANCEL, BusiStatus.ACCOUNT_CANCEL.getReasonPhrase());
|
||||
//exception.addAdditionalInformation("erbanNo", String.valueOf(users.getErbanNo()));
|
||||
//exception.addAdditionalInformation("cancelDate", String.valueOf(userCancelRecord.getUpdateTime().getTime()));
|
||||
//exception.addAdditionalInformation("nick", userCancelRecord.getNick());
|
||||
//exception.addAdditionalInformation("avatar", userCancelRecord.getAvatar());
|
||||
|
||||
Integer surviveTime = Integer.valueOf(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.USER_RECOVER_CREDENTIALS_SURVIVE_TIME, String.valueOf(3 * 60)));
|
||||
//写入凭证标识
|
||||
jedisService.setex(RedisKey.cancel_user_recover_credentials.getKey(String.valueOf(users.getErbanNo())), surviveTime, String.valueOf(uid));
|
||||
//throw exception;
|
||||
|
||||
Map<String, String> tipMap = Map.of("erbanNo", String.valueOf(users.getErbanNo()), "cancelDate", String.valueOf(userCancelRecord.getUpdateTime().getTime()),
|
||||
"nick", userCancelRecord.getNick(), "avatar", userCancelRecord.getAvatar());
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_CANCEL, tipMap);
|
||||
}
|
||||
|
||||
private DayIpMaxRegisterLimitConfig getIpMaxLimitConfig() {
|
||||
String config = sysConfService.getSysConfValueById(Constant.SysConfId.IP_MAX_REGISTER_LIMIT_CONFIG);
|
||||
if (!StringUtils.hasText(config)) {
|
||||
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
|
||||
throw new OAuthException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
|
||||
}
|
||||
return JSON.parseObject(config, DayIpMaxRegisterLimitConfig.class);
|
||||
}
|
||||
@@ -510,7 +499,7 @@ public class AccountManageService {
|
||||
private RepeatedDeviceIpRegisterLimitConfig getRepeatedDeviceIpLimitConfig() {
|
||||
String config = sysConfService.getSysConfValueById(Constant.SysConfId.REPEATED_DEVICE_IP_REGISTER_LIMIT_CONFIG);
|
||||
if (!StringUtils.hasText(config)) {
|
||||
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
|
||||
throw new OAuthException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
|
||||
}
|
||||
return JSON.parseObject(config, RepeatedDeviceIpRegisterLimitConfig.class);
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import com.accompany.core.model.Account;
|
||||
import com.accompany.core.util.KeyStore;
|
||||
import com.accompany.core.util.MD5;
|
||||
import com.accompany.oauth.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth.exception.AuthenticationException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -22,20 +22,20 @@ import org.springframework.stereotype.Service;
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
public class UserService {
|
||||
public class AuthenticateService {
|
||||
|
||||
@Autowired
|
||||
private AccountManageService accountManageService;
|
||||
@Autowired
|
||||
private AccountLoginService accountLoginService;
|
||||
|
||||
|
||||
/**
|
||||
* 通过密码认证用户
|
||||
*
|
||||
* @param username 手机号
|
||||
* @param password 密码
|
||||
* @return 用户详情
|
||||
* @throws AuthenticationException 认证失败
|
||||
* @throws OAuthException 认证失败
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Account authenticateByPassword(String username, String password) {
|
||||
@@ -45,9 +45,7 @@ public class UserService {
|
||||
|
||||
Account account = accountManageService.getAccountPyUsername(username, password);
|
||||
if (account == null) {
|
||||
// todo
|
||||
//throw new CustomOAuth2Exception(CustomOAuth2Exception.USER_NOT_EXISTED,
|
||||
// BusiStatus.USER_NOT_EXISTED.getReasonPhrase());
|
||||
throw new OAuthException(BusiStatus.USER_NOT_EXISTED);
|
||||
}
|
||||
|
||||
accountLoginService.validPwd(username, password, account.getPassword());
|
||||
@@ -75,7 +73,7 @@ public class UserService {
|
||||
* @param code 验证码
|
||||
* @param deviceInfo
|
||||
* @return 用户详情
|
||||
* @throws AuthenticationException 认证失败
|
||||
* @throws OAuthException 认证失败
|
||||
*/
|
||||
public Account authenticateByEmail(String email, String code, DeviceInfo deviceInfo) {
|
||||
Account account = accountManageService.getOrGenAccountByEmail(email, code, deviceInfo, deviceInfo.getClientIp());
|
||||
@@ -92,7 +90,7 @@ public class UserService {
|
||||
* @param openId OpenID
|
||||
* @param type 第三方类型 (1-微信, 2-Apple等)
|
||||
* @return 用户详情
|
||||
* @throws AuthenticationException 认证失败
|
||||
* @throws OAuthException 认证失败
|
||||
*/
|
||||
public Account authenticateByOpenId(Byte type, String openId, String unionId, String idToken, DeviceInfo deviceInfo) {
|
||||
return accountManageService.getOrGenAccountByOpenid(type, openId, unionId, idToken, deviceInfo);
|
||||
@@ -103,7 +101,7 @@ public class UserService {
|
||||
*
|
||||
* @param uid 用户ID
|
||||
* @return 用户详情
|
||||
* @throws AuthenticationException 用户不存在
|
||||
* @throws OAuthException 用户不存在
|
||||
*/
|
||||
public Account getUserByUid(Long uid) {
|
||||
return accountManageService.getAccountPyUid(uid);
|
||||
@@ -112,15 +110,15 @@ public class UserService {
|
||||
/**
|
||||
* 检查用户状态是否可用
|
||||
*
|
||||
* @throws AuthenticationException 用户不可用
|
||||
* @throws OAuthException 用户不可用
|
||||
*/
|
||||
public void checkUserStatus(Account account) {
|
||||
if (Constant.AccountState.block.equals(account.getState())) {
|
||||
throw AuthenticationException.userFrozen();
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_BLOCK_ERROR);
|
||||
}
|
||||
|
||||
if (Constant.AccountState.cancel.equals(account.getState())) {
|
||||
throw AuthenticationException.userNotFound();
|
||||
throw new OAuthException(BusiStatus.ACCOUNT_CANCEL);
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,11 @@
|
||||
package com.accompany.oauth.service;
|
||||
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.model.Account;
|
||||
import com.accompany.oauth.constant.GrantTypeEnum;
|
||||
import com.accompany.oauth.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth.dto.AuthResult;
|
||||
import com.accompany.oauth.exception.AuthenticationException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.oauth.token.TokenManager;
|
||||
import com.accompany.oauth.model.TokenPair;
|
||||
import com.accompany.common.device.DeviceInfo;
|
||||
@@ -21,7 +22,7 @@ import org.springframework.stereotype.Service;
|
||||
public class AuthenticationService {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
private AuthenticateService authenticateService;
|
||||
@Autowired
|
||||
private AccountLoginService accountLoginService;
|
||||
@Autowired
|
||||
@@ -35,7 +36,7 @@ public class AuthenticationService {
|
||||
* @param code 验证码
|
||||
* @param deviceInfo 设备信息
|
||||
* @return 认证结果
|
||||
* @throws AuthenticationException 认证失败
|
||||
* @throws OAuthException 认证失败
|
||||
*/
|
||||
public AuthResult authenticate(String grantType,
|
||||
String username, String password,
|
||||
@@ -50,22 +51,22 @@ public class AuthenticationService {
|
||||
switch (grantTypeEnum) {
|
||||
case PASSWORD:
|
||||
loginTypeEnum = LoginTypeEnum.ID;
|
||||
account = userService.authenticateByPassword(username, password);
|
||||
account = authenticateService.authenticateByPassword(username, password);
|
||||
break;
|
||||
case VERIFY_CODE:
|
||||
loginTypeEnum = LoginTypeEnum.PHONE;
|
||||
account = userService.authenticateByVerifyCode(phone, phoneAreaCode, code, deviceInfo);
|
||||
account = authenticateService.authenticateByVerifyCode(phone, phoneAreaCode, code, deviceInfo);
|
||||
break;
|
||||
case EMAIL:
|
||||
loginTypeEnum = LoginTypeEnum.EMAIL;
|
||||
account = userService.authenticateByEmail(email, code, deviceInfo);
|
||||
account = authenticateService.authenticateByEmail(email, code, deviceInfo);
|
||||
break;
|
||||
default:
|
||||
throw new AuthenticationException("不支持的认证类型: " + grantType);
|
||||
throw new OAuthException(BusiStatus.INVALID_GRANT);
|
||||
}
|
||||
|
||||
// 2. 检查用户状态
|
||||
userService.checkUserStatus(account);
|
||||
authenticateService.checkUserStatus(account);
|
||||
|
||||
accountLoginService.login(account, loginTypeEnum, deviceInfo, null);
|
||||
|
||||
@@ -77,22 +78,22 @@ public class AuthenticationService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录认证 (兼容OAuth2格式)
|
||||
* 第三方认证
|
||||
*
|
||||
* @param openId 第三方OpenID
|
||||
* @param unionId UnionID(可选)
|
||||
* @param idToken ID Token(可选)
|
||||
* @param type 第三方类型
|
||||
* @param openId OpenID
|
||||
* @param unionId UnionID
|
||||
* @param idToken ID Token
|
||||
* @param deviceInfo 设备信息
|
||||
* @return 认证结果
|
||||
* @throws AuthenticationException 认证失败
|
||||
* @throws OAuthException 认证失败
|
||||
*/
|
||||
|
||||
public AuthResult authenticateByThirdParty(Byte type, String openId, String unionId, String idToken, DeviceInfo deviceInfo) {
|
||||
// 1. 第三方认证
|
||||
Account account = userService.authenticateByOpenId(type, openId, unionId, idToken, deviceInfo);
|
||||
Account account = authenticateService.authenticateByOpenId(type, openId, unionId, idToken, deviceInfo);
|
||||
|
||||
// 2. 检查用户状态
|
||||
userService.checkUserStatus(account);
|
||||
authenticateService.checkUserStatus(account);
|
||||
|
||||
// 4. 生成Token
|
||||
TokenPair tokenPair = tokenManager.generateToken(account.getUid());
|
||||
|
@@ -2,6 +2,7 @@ package com.accompany.oauth.ticket;
|
||||
|
||||
import com.accompany.common.device.DeviceInfo;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.model.Account;
|
||||
import com.accompany.core.model.AccountLoginRecord;
|
||||
import com.accompany.core.service.account.AccountService;
|
||||
@@ -9,11 +10,11 @@ import com.accompany.core.service.account.LoginRecordService;
|
||||
import com.accompany.core.service.account.UserAppService;
|
||||
import com.accompany.oauth.constant.LoginTypeEnum;
|
||||
import com.accompany.oauth.dto.TicketResponseVO;
|
||||
import com.accompany.oauth.exception.TokenException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.oauth.token.TokenManager;
|
||||
import com.accompany.oauth.model.TokenValidation;
|
||||
import com.accompany.oauth.service.AccountLoginService;
|
||||
import com.accompany.oauth.service.UserService;
|
||||
import com.accompany.oauth.service.AuthenticateService;
|
||||
import com.accompany.oauth.util.JwtUtil;
|
||||
import org.redisson.api.RMapCache;
|
||||
import org.redisson.api.RedissonClient;
|
||||
@@ -39,7 +40,7 @@ public class TicketService implements InitializingBean {
|
||||
private TokenManager tokenManager;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
private AuthenticateService authenticateService;
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
@@ -67,12 +68,12 @@ public class TicketService implements InitializingBean {
|
||||
// 1. 验证访问令牌
|
||||
TokenValidation validation = tokenManager.validateToken(accessToken);
|
||||
if (!validation.isValid()) {
|
||||
throw TokenException.invalidToken();
|
||||
throw new OAuthException(BusiStatus.INVALID_TOKEN);
|
||||
}
|
||||
|
||||
// 2. 获取用户信息
|
||||
Account account = userService.getUserByUid(validation.getUserId());
|
||||
userService.checkUserStatus(account);
|
||||
Account account = authenticateService.getUserByUid(validation.getUserId());
|
||||
authenticateService.checkUserStatus(account);
|
||||
|
||||
Date expiration = validation.getExpirationTime();
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
package com.accompany.oauth.token;
|
||||
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.util.StringUtils;
|
||||
import com.accompany.oauth.exception.TokenException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.oauth.model.TokenPair;
|
||||
import com.accompany.oauth.model.TokenValidation;
|
||||
import com.accompany.oauth.util.JwtUtil;
|
||||
@@ -61,27 +62,21 @@ public class TokenManager implements InitializingBean {
|
||||
* @return 验证结果
|
||||
*/
|
||||
public TokenValidation validateToken(String token) {
|
||||
try {
|
||||
// 首先验证JWT格式和签名
|
||||
Claims claims = jwtUtil.validateAndParseToken(token);
|
||||
// 提取token信息
|
||||
Long uid = Long.valueOf(claims.getSubject());
|
||||
// 首先验证JWT格式和签名
|
||||
Claims claims = jwtUtil.validateAndParseToken(token);
|
||||
// 提取token信息
|
||||
Long uid = Long.valueOf(claims.getSubject());
|
||||
|
||||
// 检查Redis中是否存在该token
|
||||
String cacheToken = tokenCache.get(uid);
|
||||
if (StringUtils.isBlank(cacheToken) || !cacheToken.equals(token)) {
|
||||
return TokenValidation.invalid("Token不存在或已被撤销");
|
||||
}
|
||||
|
||||
String clientId = claims.get("client_id", String.class);
|
||||
Date expirationTime = claims.getExpiration();
|
||||
|
||||
return TokenValidation.valid(uid, expirationTime, clientId);
|
||||
} catch (TokenException e) {
|
||||
return TokenValidation.invalid(e.getErrorDescription());
|
||||
} catch (Exception e) {
|
||||
return TokenValidation.invalid("Token验证失败: " + e.getMessage());
|
||||
// 检查Redis中是否存在该token
|
||||
String cacheToken = tokenCache.get(uid);
|
||||
if (StringUtils.isBlank(cacheToken) || !cacheToken.equals(token)) {
|
||||
throw new OAuthException(BusiStatus.INVALID_TOKEN);
|
||||
}
|
||||
|
||||
String clientId = claims.get("client_id", String.class);
|
||||
Date expirationTime = claims.getExpiration();
|
||||
|
||||
return TokenValidation.valid(uid, expirationTime, clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,8 +1,9 @@
|
||||
package com.accompany.oauth.util;
|
||||
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.UUIDUtil;
|
||||
import com.accompany.oauth.config.OAuthConfig;
|
||||
import com.accompany.oauth.exception.TokenException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.oauth.ticket.Ticket;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
@@ -55,7 +56,7 @@ public class JwtUtil implements InitializingBean {
|
||||
.claim("uid", userId) // 兼容OAuth2
|
||||
.claim("user_name", userId.toString()) // 兼容OAuth2
|
||||
.claim("authorities", "oauth2") // 兼容OAuth2
|
||||
.claim("jti", generateJti()) // 兼容OAuth2
|
||||
.claim("jti", UUIDUtil.get()) // 兼容OAuth2
|
||||
.claim("scope", "read write")
|
||||
.signWith(secretKey, SignatureAlgorithm.HS256);
|
||||
|
||||
@@ -112,7 +113,7 @@ public class JwtUtil implements InitializingBean {
|
||||
*
|
||||
* @param token JWT令牌
|
||||
* @return Claims对象
|
||||
* @throws TokenException 令牌无效或过期
|
||||
* @throws OAuthException 令牌无效或过期
|
||||
*/
|
||||
public Claims validateAndParseToken(String token) {
|
||||
try {
|
||||
@@ -122,21 +123,12 @@ public class JwtUtil implements InitializingBean {
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
} catch (ExpiredJwtException e) {
|
||||
throw TokenException.tokenExpired();
|
||||
throw new OAuthException(BusiStatus.ACCESS_TOKEN_HAS_EXPIRED);
|
||||
} catch (JwtException e) {
|
||||
throw TokenException.invalidToken();
|
||||
throw new OAuthException(BusiStatus.INVALID_TOKEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成JWT Token ID (兼容OAuth2)
|
||||
*
|
||||
* @return JTI
|
||||
*/
|
||||
private String generateJti() {
|
||||
return UUIDUtil.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// 确保密钥长度足够
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package com.accompany.oauth;
|
||||
|
||||
import org.dromara.dynamictp.spring.annotation.EnableDynamicTp;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
@@ -10,12 +12,15 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@EnableDynamicTp
|
||||
@SpringBootApplication
|
||||
@ComponentScan("com.accompany")
|
||||
@ComponentScan(basePackages = {
|
||||
"com.accompany.oauth", // OAuth模块
|
||||
"com.accompany.common", // 公共模块
|
||||
"com.accompany.core" // 核心模块
|
||||
})
|
||||
@MapperScan({"com.accompany.*.mapper","com.accompany.*.mybatismapper"})
|
||||
public class OAuthApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
@@ -1,122 +0,0 @@
|
||||
package com.accompany.oauth.config;
|
||||
|
||||
import com.accompany.oauth.exception.AuthenticationException;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import com.accompany.oauth.exception.TokenException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
|
||||
/**
|
||||
* 处理OAuth异常
|
||||
*
|
||||
* @param e OAuth异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(OAuthException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleOAuthException(OAuthException e) {
|
||||
logger.warn("OAuth异常: {} - {}", e.getErrorCode(), e.getErrorDescription());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", e.getErrorCode());
|
||||
response.put("error_description", e.getErrorDescription());
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理认证异常
|
||||
*
|
||||
* @param e 认证异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(AuthenticationException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleAuthenticationException(AuthenticationException e) {
|
||||
logger.warn("认证异常: {}", e.getErrorDescription());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", e.getErrorCode());
|
||||
response.put("error_description", e.getErrorDescription());
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Token异常
|
||||
*
|
||||
* @param e Token异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(TokenException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleTokenException(TokenException e) {
|
||||
logger.warn("Token异常: {} - {}", e.getErrorCode(), e.getErrorDescription());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", e.getErrorCode());
|
||||
response.put("error_description", e.getErrorDescription());
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数异常
|
||||
*
|
||||
* @param e 参数异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleIllegalArgumentException(IllegalArgumentException e) {
|
||||
logger.warn("参数异常: {}", e.getMessage());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", "invalid_request");
|
||||
response.put("error_description", e.getMessage());
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他异常
|
||||
*
|
||||
* @param e 异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleException(Exception e) {
|
||||
logger.error("系统异常", e);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", "server_error");
|
||||
response.put("error_description", "系统内部错误");
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
|
||||
}
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
package com.accompany.oauth.config;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.base.SpringContextHolder;
|
||||
import com.accompany.oauth.exception.OAuthException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
* @author Accompany OAuth Team
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class OauthGlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理OAuth异常
|
||||
*
|
||||
* @param e OAuth异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(OAuthException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleOAuthException(OAuthException e) {
|
||||
|
||||
BusiStatus status = e.getBusiStatus();
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("code", status.getCode());
|
||||
|
||||
Locale locale = LocaleContextHolder.getLocale();
|
||||
String i18nId = BusiStatus.class.getSimpleName() + StrUtil.DOT + status.getName();
|
||||
String abc = SpringContextHolder.getBean(MessageSource.class).getMessage(i18nId, null, status.getMessage(), locale);
|
||||
map.put("message", abc);
|
||||
|
||||
Map<String, String> additionalInformation = e.getAdditionalInformation();
|
||||
if (CollectionUtils.isEmpty(additionalInformation)){
|
||||
return ResponseEntity.status(status.getCode()).body(map);
|
||||
}
|
||||
for (String key : additionalInformation.keySet()){
|
||||
map.put(key, additionalInformation.get(key));
|
||||
}
|
||||
|
||||
return ResponseEntity.status(status.getCode()).body(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数异常
|
||||
*
|
||||
* @param e 参数异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleIllegalArgumentException(IllegalArgumentException e) {
|
||||
log.warn("参数异常: {}", e.getMessage());
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", "invalid_request");
|
||||
response.put("error_description", e.getMessage());
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他异常
|
||||
*
|
||||
* @param e 异常
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> handleException(Exception e) {
|
||||
log.error("系统异常", e);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("error", "server_error");
|
||||
response.put("error_description", "系统内部错误");
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
|
||||
}
|
||||
}
|
@@ -61,14 +61,4 @@ oauth2:
|
||||
server:
|
||||
clientId: erban-client
|
||||
clientSecret: uyzjdhds
|
||||
jwtSignKey: dh293Hkdjf3G
|
||||
yidunSecretId: 53ac2fc2d00e3ffc4eafbfe6305aed03
|
||||
yidunSecretKey: 0b9cd0854bc6be2e5d709cc967f3fc38
|
||||
registerBusinessId: af43d0f8752147c48f8281800da6049e
|
||||
registerSwitch: false
|
||||
registerApiUrl: https://ac.dun.163yun.com/v2/register/check
|
||||
loginBusinessId: 67881c7a69764c058435ba93a51b1285
|
||||
loginSwitch: false
|
||||
logiApiUrl: https://ac.dun.163yun.com/v2/login/check
|
||||
registerOpened: false
|
||||
loginOpened: false
|
||||
jwtSignKey: ead18800082c5807806d8f54914f84f4fa360dd568f4784288a4439b5fee0f25
|
Reference in New Issue
Block a user