review code.
This commit is contained in:
@@ -16,4 +16,12 @@ public class Const implements com.orion.lang.constant.Const {
|
||||
|
||||
public static final Integer IS_DELETED = 1;
|
||||
|
||||
public static final int BEARER_PREFIX_LEN = 7;
|
||||
|
||||
public static final int MD5_LEN = 32;
|
||||
|
||||
public static final String UNKNOWN = "未知";
|
||||
|
||||
public static final String INTRANET_IP = "内网IP";
|
||||
|
||||
}
|
||||
|
||||
@@ -13,10 +13,16 @@ public interface ErrorMessage {
|
||||
|
||||
String ID_MISSING = "id 不能为空";
|
||||
|
||||
String USERNAME_PASSWORD_ERROR = "用户名或密码错误";
|
||||
|
||||
String DATA_PRESENT = "数据已存在";
|
||||
|
||||
String DATA_ABSENT = "数据不存在";
|
||||
|
||||
String USERNAME_PASSWORD_ERROR = "用户名或密码错误";
|
||||
|
||||
String MAX_LOGIN_FAILED = "登陆失败次数已上限";
|
||||
|
||||
String USER_DISABLED = "用户已被禁用";
|
||||
|
||||
String USER_LOCKED = "用户已被锁定";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.ops.framework.common.crypto;
|
||||
|
||||
import com.orion.lang.utils.codec.Base62s;
|
||||
import com.orion.lang.utils.crypto.symmetric.SymmetricCrypto;
|
||||
|
||||
/**
|
||||
@@ -16,4 +17,24 @@ public interface ValueCrypto extends SymmetricCrypto {
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* 加密后 base62 编码
|
||||
*
|
||||
* @param plain 明文
|
||||
* @return 密文
|
||||
*/
|
||||
default String encryptBase62(String plain) {
|
||||
return new String(Base62s.encode(this.encrypt(plain)));
|
||||
}
|
||||
|
||||
/**
|
||||
* base62 解码后解密
|
||||
*
|
||||
* @param text 密文
|
||||
* @return 明文
|
||||
*/
|
||||
default String decryptBase62(String text) {
|
||||
return new String(this.decrypt(Base62s.decode(text)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.ops.framework.common.security;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@@ -12,26 +13,25 @@ import java.util.List;
|
||||
* @since 2023/7/6 18:36
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "LoginUser", description = "当前登录用户对象")
|
||||
public class LoginUser {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 花名
|
||||
*/
|
||||
@Schema(description = "花名")
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*/
|
||||
@Schema(description = "用户状态")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "头像地址")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "角色")
|
||||
private List<String> roles;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.orion.ops.framework.common.utils;
|
||||
|
||||
import com.orion.lang.utils.crypto.symmetric.SymmetricCrypto;
|
||||
import com.orion.ops.framework.common.crypto.ValueCrypto;
|
||||
|
||||
/**
|
||||
* 加密工具类
|
||||
@@ -11,10 +11,7 @@ import com.orion.lang.utils.crypto.symmetric.SymmetricCrypto;
|
||||
*/
|
||||
public class CryptoUtils {
|
||||
|
||||
/**
|
||||
* 加密器 供 framework 赋值
|
||||
*/
|
||||
public static SymmetricCrypto delegate;
|
||||
private static ValueCrypto delegate;
|
||||
|
||||
/**
|
||||
* 加密
|
||||
@@ -118,4 +115,28 @@ public class CryptoUtils {
|
||||
return delegate.verify(plain, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密后 base62 编码
|
||||
*
|
||||
* @param plain 明文
|
||||
* @return 密文
|
||||
*/
|
||||
public static String encryptBase62(String plain) {
|
||||
return delegate.encryptBase62(plain);
|
||||
}
|
||||
|
||||
/**
|
||||
* base62 解码后解密
|
||||
*
|
||||
* @param text 密文
|
||||
* @return 明文
|
||||
*/
|
||||
public static String decryptBase62(String text) {
|
||||
return delegate.decryptBase62(text);
|
||||
}
|
||||
|
||||
public static void setDelegate(ValueCrypto delegate) {
|
||||
CryptoUtils.delegate = delegate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.orion.ops.framework.common.utils;
|
||||
|
||||
import com.orion.ext.location.Region;
|
||||
import com.orion.ext.location.region.LocationRegions;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
|
||||
/**
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/14 16:26
|
||||
*/
|
||||
public class IpUtils {
|
||||
|
||||
private IpUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ip 位置
|
||||
*
|
||||
* @param ip ip
|
||||
* @return ip 位置
|
||||
*/
|
||||
public static String getLocation(String ip) {
|
||||
if (ip == null) {
|
||||
return Const.UNKNOWN;
|
||||
}
|
||||
Region region;
|
||||
try {
|
||||
region = LocationRegions.getRegion(ip, 3);
|
||||
} catch (Exception e) {
|
||||
return Const.UNKNOWN;
|
||||
}
|
||||
if (region != null) {
|
||||
String net = region.getNet();
|
||||
String province = region.getProvince();
|
||||
if (net.equals(Const.INTRANET_IP)) {
|
||||
return net;
|
||||
}
|
||||
if (province.equals(Const.UNKNOWN)) {
|
||||
return province;
|
||||
}
|
||||
StringBuilder location = new StringBuilder()
|
||||
.append(region.getCountry())
|
||||
.append(Const.DASHED)
|
||||
.append(province)
|
||||
.append(Const.DASHED)
|
||||
.append(region.getCity());
|
||||
location.append(" (").append(net).append(')');
|
||||
return location.toString();
|
||||
}
|
||||
return Const.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.orion.ops.framework.common.utils;
|
||||
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
|
||||
/**
|
||||
* 工具类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/14 16:34
|
||||
*/
|
||||
public class Kits {
|
||||
|
||||
private Kits() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登陆凭证
|
||||
*
|
||||
* @param authorization authorization
|
||||
* @return token
|
||||
*/
|
||||
public static String getAuthorization(String authorization) {
|
||||
if (Strings.isEmpty(authorization)) {
|
||||
return null;
|
||||
}
|
||||
if (!authorization.contains(Const.BEARER) || authorization.length() <= Const.BEARER_PREFIX_LEN) {
|
||||
return null;
|
||||
}
|
||||
return authorization.substring(Const.BEARER_PREFIX_LEN).trim();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -64,21 +64,29 @@ public class DataQuery<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<T> get() {
|
||||
public T get() {
|
||||
return dao.selectOne(wrapper);
|
||||
}
|
||||
|
||||
public Optional<T> optional() {
|
||||
return Optional.ofNullable(dao.selectOne(wrapper));
|
||||
}
|
||||
|
||||
public <R> Optional<R> get(Function<T, R> mapper) {
|
||||
public <R> Optional<R> optional(Function<T, R> mapper) {
|
||||
Valid.notNull(mapper, "convert function is null");
|
||||
return Optional.ofNullable(dao.selectOne(wrapper))
|
||||
.map(mapper);
|
||||
}
|
||||
|
||||
public Stream<T> list() {
|
||||
public List<T> list() {
|
||||
return dao.selectList(wrapper);
|
||||
}
|
||||
|
||||
public Stream<T> stream() {
|
||||
return dao.selectList(wrapper).stream();
|
||||
}
|
||||
|
||||
public <R> List<R> list(Function<T, R> mapper) {
|
||||
public <R> List<R> stream(Function<T, R> mapper) {
|
||||
Valid.notNull(mapper, "convert function is null");
|
||||
return Lists.map(dao.selectList(wrapper), mapper);
|
||||
}
|
||||
|
||||
@@ -16,14 +16,13 @@ import java.util.List;
|
||||
* @since ${date}
|
||||
*/
|
||||
@Mapper
|
||||
@SuppressWarnings("ALL")
|
||||
public interface ${type}ProviderConvert {
|
||||
|
||||
${type}ProviderConvert MAPPER = Mappers.getMapper(${type}ProviderConvert.class);
|
||||
|
||||
${type}DO to(${type}DTO dto);
|
||||
|
||||
${type}DTO to(${type}DO dto);
|
||||
${type}DTO to(${type}DO domain);
|
||||
|
||||
List<${type}DO> toDO(List<${type}DTO> list);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.util.List;
|
||||
* @since ${date}
|
||||
*/
|
||||
@Mapper
|
||||
@SuppressWarnings("ALL")
|
||||
public interface ${type}Convert {
|
||||
|
||||
${type}Convert MAPPER = Mappers.getMapper(${type}Convert.class);
|
||||
@@ -27,7 +26,7 @@ public interface ${type}Convert {
|
||||
|
||||
${type}DO to(${type}QueryRequest request);
|
||||
|
||||
${type}VO to(${type}DO request);
|
||||
${type}VO to(${type}DO domain);
|
||||
|
||||
List<${type}VO> to(List<${type}DO> list);
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ public class OrionRedisAutoConfiguration {
|
||||
RedisTemplate<String, T> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.setKeySerializer(RedisSerializer.string());
|
||||
redisTemplate.setValueSerializer(RedisSerializer.json());
|
||||
redisTemplate.setValueSerializer(RedisSerializer.string());
|
||||
redisTemplate.setHashKeySerializer(RedisSerializer.string());
|
||||
redisTemplate.setHashValueSerializer(RedisSerializer.json());
|
||||
redisTemplate.setHashValueSerializer(RedisSerializer.string());
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ package com.orion.ops.framework.security.config;
|
||||
|
||||
import com.orion.ops.framework.common.constant.AutoConfigureOrderConst;
|
||||
import com.orion.ops.framework.common.crypto.ValueCrypto;
|
||||
import com.orion.ops.framework.common.utils.CryptoUtils;
|
||||
import com.orion.ops.framework.security.core.crypto.aes.AesCryptoProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@@ -31,14 +29,10 @@ public class OrionCryptoAutoConfiguration {
|
||||
/**
|
||||
* @return aes 加密器
|
||||
*/
|
||||
@Primary
|
||||
@Bean(initMethod = "init")
|
||||
@ConditionalOnProperty(value = "orion.crypto.aes.enabled", havingValue = "true")
|
||||
public ValueCrypto aes() {
|
||||
ValueCrypto processor = new AesCryptoProcessor(config.getAes());
|
||||
// 设置工具委托类 委托需要与 @Primary 相同, 否则会导致工具类和bean的结果不同
|
||||
CryptoUtils.delegate = processor;
|
||||
return processor;
|
||||
return new AesCryptoProcessor(config.getAes());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ import lombok.Data;
|
||||
@Data
|
||||
public class CryptoConfig {
|
||||
|
||||
/**
|
||||
* 是否为默认加密器
|
||||
*/
|
||||
protected boolean primary;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.orion.ops.framework.security.core.crypto;
|
||||
|
||||
import com.orion.ops.framework.common.crypto.ValueCrypto;
|
||||
import com.orion.ops.framework.common.utils.CryptoUtils;
|
||||
|
||||
/**
|
||||
* 数据加密器
|
||||
@@ -15,6 +16,10 @@ public abstract class CryptoProcessor<Config extends CryptoConfig> implements Va
|
||||
|
||||
protected CryptoProcessor(Config config) {
|
||||
this.config = config;
|
||||
// 设置为默认加密器
|
||||
if (config.isPrimary()) {
|
||||
CryptoUtils.setDelegate(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -88,6 +88,8 @@ public class PermitAllAnnotationAuthorizeRequestsCustomizer extends AuthorizeReq
|
||||
case DELETE:
|
||||
deleteList.addAll(urls);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.orion.ops.framework.security.core.utils;
|
||||
|
||||
import com.orion.lang.constant.StandardHttpHeader;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
import com.orion.ops.framework.common.security.LoginUser;
|
||||
import com.orion.ops.framework.common.utils.Kits;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@@ -22,8 +21,6 @@ import java.util.Collections;
|
||||
*/
|
||||
public class SecurityUtils {
|
||||
|
||||
private static final int BEARER_PREFIX_LEN = 7;
|
||||
|
||||
private SecurityUtils() {
|
||||
}
|
||||
|
||||
@@ -34,14 +31,7 @@ public class SecurityUtils {
|
||||
* @return token
|
||||
*/
|
||||
public static String obtainAuthorization(HttpServletRequest request) {
|
||||
String authorization = request.getHeader(StandardHttpHeader.AUTHORIZATION);
|
||||
if (Strings.isEmpty(authorization)) {
|
||||
return null;
|
||||
}
|
||||
if (!authorization.contains(Const.BEARER) || authorization.length() <= BEARER_PREFIX_LEN) {
|
||||
return null;
|
||||
}
|
||||
return authorization.substring(BEARER_PREFIX_LEN).trim();
|
||||
return Kits.getAuthorization(request.getHeader(StandardHttpHeader.AUTHORIZATION));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
"type": "java.util.List",
|
||||
"description": "匿名接口."
|
||||
},
|
||||
{
|
||||
"name": "orion.crypto.primary.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "是否为默认加密器.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
{
|
||||
"name": "orion.crypto.aes.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
|
||||
@@ -67,27 +67,30 @@ public class GlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = MissingServletRequestParameterException.class)
|
||||
public HttpWrapper<?> missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException ex) {
|
||||
log.error("missingServletRequestParameterExceptionHandler", ex);
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(Strings.format(ErrorMessage.PARAM_MISSING, ex.getParameterName()));
|
||||
String message = Strings.format(ErrorMessage.PARAM_MISSING, ex.getParameterName());
|
||||
log.error("missingServletRequestParameterExceptionHandler {}", message);
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = BindException.class)
|
||||
public HttpWrapper<?> paramBindExceptionHandler(BindException ex) {
|
||||
log.error("paramBindExceptionHandler", ex);
|
||||
FieldError error = Objects.requireNonNull(ex.getFieldError());
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(error.getField() + " " + error.getDefaultMessage());
|
||||
String message = error.getField() + " " + error.getDefaultMessage();
|
||||
log.error("paramBindExceptionHandler {}", message);
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = ConstraintViolationException.class)
|
||||
public HttpWrapper<?> constraintViolationExceptionHandler(ConstraintViolationException ex) {
|
||||
log.error("constraintViolationExceptionHandler", ex);
|
||||
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(Objects.requireNonNull(constraintViolation).getMessage());
|
||||
String message = Objects.requireNonNull(constraintViolation).getMessage();
|
||||
log.error("constraintViolationExceptionHandler {}", message);
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = {HttpRequestMethodNotSupportedException.class})
|
||||
public HttpWrapper<?> httpRequestMethodNotSupportedExceptionHandler(Exception ex) {
|
||||
log.error("httpRequestMethodNotSupportedExceptionHandler", ex);
|
||||
log.error("httpRequestMethodNotSupportedExceptionHandler {}", ex.getMessage());
|
||||
return ErrorCode.METHOD_NOT_ALLOWED.getWrapper();
|
||||
}
|
||||
|
||||
@@ -118,7 +121,7 @@ public class GlobalExceptionHandler {
|
||||
IllegalArgumentException.class
|
||||
})
|
||||
public HttpWrapper<?> invalidArgumentExceptionHandler(Exception ex) {
|
||||
log.error("invalidArgumentExceptionHandler", ex);
|
||||
log.error("invalidArgumentExceptionHandler {}", ex.getMessage());
|
||||
return ErrorCode.BAD_REQUEST.wrapper().msg(ex.getMessage());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user