first commit
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.mhd.common.security.config.ApplicationConfig;
|
||||
import com.mhd.system.api.feign.FeignAutoConfiguration;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
// 表示通过aop框架暴露该代理对象,AopContext能够访问
|
||||
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||
// 指定要扫描的Mapper类的包的路径
|
||||
@MapperScan("com.mhd.**.mapper")
|
||||
// 开启线程异步执行
|
||||
@EnableAsync
|
||||
// 自动加载类
|
||||
@Import({ ApplicationConfig.class, FeignAutoConfiguration.class })
|
||||
public @interface EnableCustomConfig
|
||||
{
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义feign注解
|
||||
* 添加basePackages路径
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@EnableFeignClients
|
||||
public @interface EnableMhdAuthFeignClients
|
||||
{
|
||||
String[] value() default {};
|
||||
|
||||
String[] basePackages() default { "com.mhd" };
|
||||
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
Class<?>[] clients() default {};
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义feign注解
|
||||
* 添加basePackages路径
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@EnableFeignClients
|
||||
public @interface EnableRyFeignClients
|
||||
{
|
||||
String[] value() default {};
|
||||
|
||||
String[] basePackages() default { "com.mhd" };
|
||||
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
Class<?>[] clients() default {};
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 内部认证注解
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface InnerAuth
|
||||
{
|
||||
/**
|
||||
* 是否校验用户信息
|
||||
*/
|
||||
boolean isUser() default false;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
/**
|
||||
* 权限注解的验证模式
|
||||
*
|
||||
* @author mhd
|
||||
*
|
||||
*/
|
||||
public enum Logical
|
||||
{
|
||||
/**
|
||||
* 必须具有所有的元素
|
||||
*/
|
||||
AND,
|
||||
|
||||
/**
|
||||
* 只需具有其中一个元素
|
||||
*/
|
||||
OR
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 自定义注解防止表单重复提交
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RepeatSubmit {
|
||||
|
||||
/**
|
||||
* 间隔时间(ms),小于此时间视为重复提交
|
||||
*/
|
||||
long interval() default 1000;
|
||||
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
/**
|
||||
* 提示消息
|
||||
*/
|
||||
String message() default "不允许重复提交!";
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 登录认证:只有登录之后才能进入该方法
|
||||
*
|
||||
* @author mhd
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
public @interface RequiresLogin
|
||||
{
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 权限认证:必须具有指定权限才能进入该方法
|
||||
*
|
||||
* @author mhd
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
public @interface RequiresPermissions
|
||||
{
|
||||
/**
|
||||
* 需要校验的权限码
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* 验证模式:AND | OR,默认AND
|
||||
*/
|
||||
Logical logical() default Logical.AND;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.mhd.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 角色认证:必须具有指定角色标识才能进入该方法
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
public @interface RequiresRoles
|
||||
{
|
||||
/**
|
||||
* 需要校验的角色标识
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* 验证逻辑:AND | OR,默认AND
|
||||
*/
|
||||
Logical logical() default Logical.AND;
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.mhd.common.security.aspect;
|
||||
|
||||
import com.mhd.common.security.annotation.InnerAuth;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.mhd.common.core.constant.SecurityConstants;
|
||||
import com.mhd.common.core.exception.InnerAuthException;
|
||||
import com.mhd.common.core.utils.ServletUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 内部服务调用验证处理
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class InnerAuthAspect implements Ordered
|
||||
{
|
||||
@Around("@annotation(innerAuth)")
|
||||
public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable
|
||||
{
|
||||
String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
|
||||
// 内部请求验证
|
||||
if (!StringUtils.equals(SecurityConstants.INNER, source))
|
||||
{
|
||||
throw new InnerAuthException("没有内部访问权限,不允许访问");
|
||||
}
|
||||
|
||||
String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID);
|
||||
String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);
|
||||
// 用户信息验证
|
||||
if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)))
|
||||
{
|
||||
throw new InnerAuthException("没有设置用户信息,不允许访问 ");
|
||||
}
|
||||
return point.proceed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保在权限认证aop执行前执行
|
||||
*/
|
||||
@Override
|
||||
public int getOrder()
|
||||
{
|
||||
return Ordered.HIGHEST_PRECEDENCE + 1;
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.mhd.common.security.aspect;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.mhd.common.security.annotation.RequiresLogin;
|
||||
import com.mhd.common.security.annotation.RequiresPermissions;
|
||||
import com.mhd.common.security.annotation.RequiresRoles;
|
||||
import com.mhd.common.security.auth.AuthUtil;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 基于 Spring Aop 的注解鉴权
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class PreAuthorizeAspect
|
||||
{
|
||||
/**
|
||||
* 构建
|
||||
*/
|
||||
public PreAuthorizeAspect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义AOP签名 (切入所有使用鉴权注解的方法)
|
||||
*/
|
||||
public static final String POINTCUT_SIGN = " @annotation(com.mhd.common.security.annotation.RequiresLogin) || "
|
||||
+ "@annotation(com.mhd.common.security.annotation.RequiresPermissions) || "
|
||||
+ "@annotation(com.mhd.common.security.annotation.RequiresRoles)";
|
||||
|
||||
/**
|
||||
* 声明AOP签名
|
||||
*/
|
||||
@Pointcut(POINTCUT_SIGN)
|
||||
public void pointcut()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 环绕切入
|
||||
*
|
||||
* @param joinPoint 切面对象
|
||||
* @return 底层方法执行后的返回值
|
||||
* @throws Throwable 底层方法抛出的异常
|
||||
*/
|
||||
@Around("pointcut()")
|
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable
|
||||
{
|
||||
// 注解鉴权
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
checkMethodAnnotation(signature.getMethod());
|
||||
try
|
||||
{
|
||||
// 执行原有逻辑
|
||||
Object obj = joinPoint.proceed();
|
||||
return obj;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对一个Method对象进行注解检查
|
||||
*/
|
||||
public void checkMethodAnnotation(Method method)
|
||||
{
|
||||
// 校验 @RequiresLogin 注解
|
||||
RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class);
|
||||
if (requiresLogin != null)
|
||||
{
|
||||
AuthUtil.checkLogin();
|
||||
}
|
||||
|
||||
// 校验 @RequiresRoles 注解
|
||||
RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class);
|
||||
if (requiresRoles != null)
|
||||
{
|
||||
AuthUtil.checkRole(requiresRoles);
|
||||
}
|
||||
|
||||
// 校验 @RequiresPermissions 注解
|
||||
RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
|
||||
if (requiresPermissions != null)
|
||||
{
|
||||
AuthUtil.checkPermi(requiresPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package com.mhd.common.security.aspect;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.mhd.common.security.annotation.RepeatSubmit;
|
||||
import com.mhd.common.core.constant.Constants;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.utils.ServletUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.redis.service.RedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* 基于 Spring Aop 的注解鉴权
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class RepeatSubmitAspect implements Ordered
|
||||
{
|
||||
|
||||
private final RedisService redisService;
|
||||
|
||||
/**
|
||||
* 环绕切入
|
||||
*
|
||||
* @param joinPoint 切面对象
|
||||
* @return 底层方法执行后的返回值
|
||||
* @throws Throwable 底层方法抛出的异常
|
||||
*/
|
||||
@Around("@annotation(repeatSubmit)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable
|
||||
{
|
||||
// 如果注解不为0 则使用注解数值
|
||||
long interval = 1000L;
|
||||
if (repeatSubmit.interval() > 0) {
|
||||
interval = repeatSubmit.timeUnit().toMillis(repeatSubmit.interval());
|
||||
}
|
||||
if (interval < 1000) {
|
||||
throw new ServiceException("重复提交间隔时间不能小于'1'秒");
|
||||
}
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
String nowParams = argsArrayToString(joinPoint.getArgs());
|
||||
|
||||
// 请求地址+请求ip(作为存放cache的key值)
|
||||
String submitKey = request.getRemoteAddr() + request.getRequestURI();
|
||||
|
||||
submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
|
||||
// 唯一标识(指定key + 消息头)
|
||||
String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
|
||||
String key = redisService.getCacheObject(cacheRepeatKey);
|
||||
if (key == null) {
|
||||
redisService.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
throw new ServiceException(repeatSubmit.message());
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置优先级
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数拼装
|
||||
*/
|
||||
private String argsArrayToString(Object[] paramsArray) {
|
||||
StringBuilder params = new StringBuilder();
|
||||
if (paramsArray != null && paramsArray.length > 0) {
|
||||
for (Object o : paramsArray) {
|
||||
if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
|
||||
try {
|
||||
params.append(JSON.toJSONString(o)).append(" ");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return params.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要过滤的对象。
|
||||
*
|
||||
* @param obj 对象信息。
|
||||
* @return 如果是需要过滤的对象,则返回true;否则返回false。
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public boolean isFilterObject(final Object obj) {
|
||||
Class<?> clazz = obj.getClass();
|
||||
if (clazz.isArray()) {
|
||||
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
|
||||
} else if (Collection.class.isAssignableFrom(clazz)) {
|
||||
Collection collection = (Collection) obj;
|
||||
for (Object value : collection) {
|
||||
return value instanceof MultipartFile;
|
||||
}
|
||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||
Map map = (Map) obj;
|
||||
for (Object value : map.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) value;
|
||||
return entry.getValue() instanceof MultipartFile;
|
||||
}
|
||||
}
|
||||
return obj instanceof MultipartFile || obj instanceof HttpServletRequest || obj instanceof HttpServletResponse
|
||||
|| obj instanceof BindingResult;
|
||||
}
|
||||
}
|
||||
+372
@@ -0,0 +1,372 @@
|
||||
package com.mhd.common.security.auth;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mhd.common.security.service.TokenService;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import com.mhd.common.core.exception.auth.NotLoginException;
|
||||
import com.mhd.common.core.exception.auth.NotPermissionException;
|
||||
import com.mhd.common.core.exception.auth.NotRoleException;
|
||||
import com.mhd.common.core.utils.SpringUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.security.annotation.Logical;
|
||||
import com.mhd.common.security.annotation.RequiresLogin;
|
||||
import com.mhd.common.security.annotation.RequiresPermissions;
|
||||
import com.mhd.common.security.annotation.RequiresRoles;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
|
||||
/**
|
||||
* Token 权限验证,逻辑实现类
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class AuthLogic
|
||||
{
|
||||
/** 所有权限标识 */
|
||||
private static final String ALL_PERMISSION = "*:*:*";
|
||||
|
||||
/** 管理员角色权限标识 */
|
||||
private static final String SUPER_ADMIN = "admin";
|
||||
|
||||
public TokenService tokenService = SpringUtils.getBean(TokenService.class);
|
||||
|
||||
/**
|
||||
* 会话注销
|
||||
*/
|
||||
public void logout()
|
||||
{
|
||||
String token = SecurityUtils.getToken();
|
||||
if (token == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
logoutByToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话注销,根据指定Token
|
||||
*/
|
||||
public void logoutByToken(String token)
|
||||
{
|
||||
tokenService.delLoginUser(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验用户是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
public void checkLogin()
|
||||
{
|
||||
getLoginUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户缓存信息, 如果未登录,则抛出异常
|
||||
*
|
||||
* @return 用户缓存信息
|
||||
*/
|
||||
public LoginUser getLoginUser()
|
||||
{
|
||||
String token = SecurityUtils.getToken();
|
||||
if (token == null)
|
||||
{
|
||||
throw new NotLoginException("未提供token");
|
||||
}
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (loginUser == null)
|
||||
{
|
||||
throw new NotLoginException("无效的token");
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户缓存信息, 如果未登录,则抛出异常
|
||||
*
|
||||
* @param token 前端传递的认证信息
|
||||
* @return 用户缓存信息
|
||||
*/
|
||||
public LoginUser getLoginUser(String token)
|
||||
{
|
||||
return tokenService.getLoginUser(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证当前用户有效期, 如果相差不足120分钟,自动刷新缓存
|
||||
*
|
||||
* @param loginUser 当前用户信息
|
||||
*/
|
||||
public void verifyLoginUserExpire(LoginUser loginUser)
|
||||
{
|
||||
tokenService.verifyToken(loginUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否具备某权限
|
||||
*
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
public boolean hasPermi(String permission)
|
||||
{
|
||||
return hasPermi(getPermiList(), permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException
|
||||
*
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
public void checkPermi(String permission)
|
||||
{
|
||||
if (!hasPermi(getPermiList(), permission))
|
||||
{
|
||||
throw new NotPermissionException(permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@RequiresPermissions)鉴权, 如果验证未通过,则抛出异常: NotPermissionException
|
||||
*
|
||||
* @param requiresPermissions 注解对象
|
||||
*/
|
||||
public void checkPermi(RequiresPermissions requiresPermissions)
|
||||
{
|
||||
if (requiresPermissions.logical() == Logical.AND)
|
||||
{
|
||||
checkPermiAnd(requiresPermissions.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
checkPermiOr(requiresPermissions.value());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否含有指定权限,必须全部拥有
|
||||
*
|
||||
* @param permissions 权限列表
|
||||
*/
|
||||
public void checkPermiAnd(String... permissions)
|
||||
{
|
||||
Set<String> permissionList = getPermiList();
|
||||
for (String permission : permissions)
|
||||
{
|
||||
if (!hasPermi(permissionList, permission))
|
||||
{
|
||||
throw new NotPermissionException(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否含有指定权限,只需包含其中一个
|
||||
*
|
||||
* @param permissions 权限码数组
|
||||
*/
|
||||
public void checkPermiOr(String... permissions)
|
||||
{
|
||||
Set<String> permissionList = getPermiList();
|
||||
for (String permission : permissions)
|
||||
{
|
||||
if (hasPermi(permissionList, permission))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (permissions.length > 0)
|
||||
{
|
||||
throw new NotPermissionException(permissions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否拥有某个角色
|
||||
*
|
||||
* @param role 角色标识
|
||||
* @return 用户是否具备某角色
|
||||
*/
|
||||
public boolean hasRole(String role)
|
||||
{
|
||||
return hasRole(getRoleList(), role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否拥有某个角色, 如果验证未通过,则抛出异常: NotRoleException
|
||||
*
|
||||
* @param role 角色标识
|
||||
*/
|
||||
public void checkRole(String role)
|
||||
{
|
||||
if (!hasRole(role))
|
||||
{
|
||||
throw new NotRoleException(role);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@RequiresRoles)鉴权
|
||||
*
|
||||
* @param requiresRoles 注解对象
|
||||
*/
|
||||
public void checkRole(RequiresRoles requiresRoles)
|
||||
{
|
||||
if (requiresRoles.logical() == Logical.AND)
|
||||
{
|
||||
checkRoleAnd(requiresRoles.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
checkRoleOr(requiresRoles.value());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否含有指定角色,必须全部拥有
|
||||
*
|
||||
* @param roles 角色标识数组
|
||||
*/
|
||||
public void checkRoleAnd(String... roles)
|
||||
{
|
||||
Set<String> roleList = getRoleList();
|
||||
for (String role : roles)
|
||||
{
|
||||
if (!hasRole(roleList, role))
|
||||
{
|
||||
throw new NotRoleException(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否含有指定角色,只需包含其中一个
|
||||
*
|
||||
* @param roles 角色标识数组
|
||||
*/
|
||||
public void checkRoleOr(String... roles)
|
||||
{
|
||||
Set<String> roleList = getRoleList();
|
||||
for (String role : roles)
|
||||
{
|
||||
if (hasRole(roleList, role))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (roles.length > 0)
|
||||
{
|
||||
throw new NotRoleException(roles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@RequiresLogin)鉴权
|
||||
*
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkByAnnotation(RequiresLogin at)
|
||||
{
|
||||
this.checkLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@RequiresRoles)鉴权
|
||||
*
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkByAnnotation(RequiresRoles at)
|
||||
{
|
||||
String[] roleArray = at.value();
|
||||
if (at.logical() == Logical.AND)
|
||||
{
|
||||
this.checkRoleAnd(roleArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.checkRoleOr(roleArray);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解(@RequiresPermissions)鉴权
|
||||
*
|
||||
* @param at 注解对象
|
||||
*/
|
||||
public void checkByAnnotation(RequiresPermissions at)
|
||||
{
|
||||
String[] permissionArray = at.value();
|
||||
if (at.logical() == Logical.AND)
|
||||
{
|
||||
this.checkPermiAnd(permissionArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.checkPermiOr(permissionArray);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前账号的角色列表
|
||||
*
|
||||
* @return 角色列表
|
||||
*/
|
||||
public Set<String> getRoleList()
|
||||
{
|
||||
try
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
return loginUser.getRoles();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前账号的权限列表
|
||||
*
|
||||
* @return 权限列表
|
||||
*/
|
||||
public Set<String> getPermiList()
|
||||
{
|
||||
try
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
return loginUser.getPermissions();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含权限
|
||||
*
|
||||
* @param authorities 权限列表
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
public boolean hasPermi(Collection<String> authorities, String permission)
|
||||
{
|
||||
return authorities.stream().filter(StringUtils::hasText)
|
||||
.anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含角色
|
||||
*
|
||||
* @param roles 角色列表
|
||||
* @param role 角色
|
||||
* @return 用户是否具备某角色权限
|
||||
*/
|
||||
public boolean hasRole(Collection<String> roles, String role)
|
||||
{
|
||||
return roles.stream().filter(StringUtils::hasText)
|
||||
.anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role));
|
||||
}
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
package com.mhd.common.security.auth;
|
||||
|
||||
import com.mhd.common.security.annotation.RequiresPermissions;
|
||||
import com.mhd.common.security.annotation.RequiresRoles;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
|
||||
/**
|
||||
* Token 权限验证工具类
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class AuthUtil
|
||||
{
|
||||
/**
|
||||
* 底层的 AuthLogic 对象
|
||||
*/
|
||||
public static AuthLogic authLogic = new AuthLogic();
|
||||
|
||||
/**
|
||||
* 会话注销
|
||||
*/
|
||||
public static void logout()
|
||||
{
|
||||
authLogic.logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话注销,根据指定Token
|
||||
*
|
||||
* @param tokenValue 指定token
|
||||
*/
|
||||
public static void logoutByToken(String token)
|
||||
{
|
||||
authLogic.logoutByToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
public static void checkLogin()
|
||||
{
|
||||
authLogic.checkLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户信息
|
||||
*/
|
||||
public static LoginUser getLoginUser(String token)
|
||||
{
|
||||
return authLogic.getLoginUser(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证当前用户有效期
|
||||
*/
|
||||
public static void verifyLoginUserExpire(LoginUser loginUser)
|
||||
{
|
||||
authLogic.verifyLoginUserExpire(loginUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定角色标识, 返回true或false
|
||||
*
|
||||
* @param role 角色标识
|
||||
* @return 是否含有指定角色标识
|
||||
*/
|
||||
public static boolean hasRole(String role)
|
||||
{
|
||||
return authLogic.hasRole(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
|
||||
*
|
||||
* @param role 角色标识
|
||||
*/
|
||||
public static void checkRole(String role)
|
||||
{
|
||||
authLogic.checkRole(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotRoleException
|
||||
*
|
||||
* @param requiresRoles 角色权限注解
|
||||
*/
|
||||
public static void checkRole(RequiresRoles requiresRoles)
|
||||
{
|
||||
authLogic.checkRole(requiresRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
|
||||
*
|
||||
* @param roles 角色标识数组
|
||||
*/
|
||||
public static void checkRoleAnd(String... roles)
|
||||
{
|
||||
authLogic.checkRoleAnd(roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可]
|
||||
*
|
||||
* @param roles 角色标识数组
|
||||
*/
|
||||
public static void checkRoleOr(String... roles)
|
||||
{
|
||||
authLogic.checkRoleOr(roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限, 返回true或false
|
||||
*
|
||||
* @param permission 权限码
|
||||
* @return 是否含有指定权限
|
||||
*/
|
||||
public static boolean hasPermi(String permission)
|
||||
{
|
||||
return authLogic.hasPermi(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
|
||||
*
|
||||
* @param permission 权限码
|
||||
*/
|
||||
public static void checkPermi(String permission)
|
||||
{
|
||||
authLogic.checkPermi(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotPermissionException
|
||||
*
|
||||
* @param requiresPermissions 权限注解
|
||||
*/
|
||||
public static void checkPermi(RequiresPermissions requiresPermissions)
|
||||
{
|
||||
authLogic.checkPermi(requiresPermissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 [指定多个,必须全部验证通过]
|
||||
*
|
||||
* @param permissions 权限码数组
|
||||
*/
|
||||
public static void checkPermiAnd(String... permissions)
|
||||
{
|
||||
authLogic.checkPermiAnd(permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
|
||||
*
|
||||
* @param permissions 权限码数组
|
||||
*/
|
||||
public static void checkPermiOr(String... permissions)
|
||||
{
|
||||
authLogic.checkPermiOr(permissions);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.mhd.common.security.config;
|
||||
|
||||
import java.util.TimeZone;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class ApplicationConfig
|
||||
{
|
||||
/**
|
||||
* 时区配置
|
||||
*/
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
|
||||
{
|
||||
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.mhd.common.security.config;
|
||||
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import com.mhd.common.security.interceptor.HeaderInterceptor;
|
||||
|
||||
/**
|
||||
* 拦截器配置
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
/**
|
||||
* 不需要拦截地址
|
||||
*/
|
||||
public static final String[] excludeUrls = {"/login", "/loginApi","/dingloginApi", "/logout", "/refresh", "/basicApi/findAgreement","/approvalDocumentApi/dingdingHuiDiao"};
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(getHeaderInterceptor())
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns(excludeUrls)
|
||||
.order(-10);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义请求头拦截器
|
||||
*/
|
||||
public HeaderInterceptor getHeaderInterceptor() {
|
||||
return new HeaderInterceptor();
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
package com.mhd.common.security.handler;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import com.mhd.common.core.constant.HttpStatus;
|
||||
import com.mhd.common.core.exception.DemoModeException;
|
||||
import com.mhd.common.core.exception.InnerAuthException;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.exception.auth.NotPermissionException;
|
||||
import com.mhd.common.core.exception.auth.NotRoleException;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
|
||||
/**
|
||||
* 权限码异常
|
||||
*/
|
||||
@ExceptionHandler(NotPermissionException.class)
|
||||
public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
|
||||
return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限异常
|
||||
*/
|
||||
@ExceptionHandler(NotRoleException.class)
|
||||
public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
|
||||
return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求方式不支持
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
|
||||
HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@ExceptionHandler(ServiceException.class)
|
||||
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
Integer code = e.getCode();
|
||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未知的运行时异常
|
||||
*/
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public AjaxResult handleException(Exception e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生系统异常.", requestURI, e);
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public AjaxResult handleBindException(BindException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
String message = e.getAllErrors().get(0).getDefaultMessage();
|
||||
return AjaxResult.error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public String handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生参数校验异常.", requestURI);
|
||||
BindingResult bindingResult = e.getBindingResult();
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
if (bindingResult.hasErrors()) {
|
||||
List<ObjectError> errors = bindingResult.getAllErrors();
|
||||
for (ObjectError objectError : errors) {
|
||||
FieldError fieldError = (FieldError) objectError;
|
||||
log.error("Data check failure : object: {},field: {},errorMessage: {}",
|
||||
fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
|
||||
errorMsg.append(objectError.getDefaultMessage());
|
||||
errorMsg.append(",");
|
||||
}
|
||||
errorMsg = new StringBuilder(errorMsg.substring(0, errorMsg.length() - 1));
|
||||
}
|
||||
return JSONUtil.toJsonStr(AjaxResult.error(HttpStatus.BAD_REQUEST,errorMsg.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部认证异常
|
||||
*/
|
||||
@ExceptionHandler(InnerAuthException.class)
|
||||
public AjaxResult handleInnerAuthException(InnerAuthException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生内部认证异常.", requestURI, e);
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 演示模式异常
|
||||
*/
|
||||
@ExceptionHandler(DemoModeException.class)
|
||||
public AjaxResult handleDemoModeException(DemoModeException e)
|
||||
{
|
||||
return AjaxResult.error("演示模式,不允许操作");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DigitalLogisticsException.class)
|
||||
public AjaxResult<?> BusinessException(DigitalLogisticsException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生 DigitalLogisticsException 异常.", requestURI, e);
|
||||
return AjaxResult.error(e.getErrno(),e.getDetailMessage());
|
||||
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.mhd.common.security.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.mhd.common.security.auth.AuthUtil;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
import com.mhd.common.core.constant.SecurityConstants;
|
||||
import com.mhd.common.core.context.SecurityContextHolder;
|
||||
import com.mhd.common.core.utils.ServletUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
|
||||
/**
|
||||
* 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
|
||||
* 注意:此拦截器会同时验证当前用户有效期自动刷新有效期
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class HeaderInterceptor implements AsyncHandlerInterceptor
|
||||
{
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
|
||||
{
|
||||
if (!(handler instanceof HandlerMethod))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
|
||||
SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
|
||||
SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));
|
||||
|
||||
String token = SecurityUtils.getToken();
|
||||
if (StringUtils.isNotEmpty(token))
|
||||
{
|
||||
LoginUser loginUser = AuthUtil.getLoginUser(token);
|
||||
if (StringUtils.isNotNull(loginUser))
|
||||
{
|
||||
AuthUtil.verifyLoginUserExpire(loginUser);
|
||||
SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||
throws Exception
|
||||
{
|
||||
SecurityContextHolder.remove();
|
||||
}
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
package com.mhd.common.security.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.mhd.common.core.domain.po.UserConfigSwitchPo;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.utils.JwtUtils;
|
||||
import com.mhd.common.core.utils.RequestHeaderUtil;
|
||||
import com.mhd.common.core.utils.ServletUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.core.utils.ip.IpUtil;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.system.api.SystemServiceFeign;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.mhd.common.core.constant.CacheConstants;
|
||||
import com.mhd.common.core.constant.SecurityConstants;
|
||||
import com.mhd.common.core.utils.ip.IpUtils;
|
||||
import com.mhd.common.core.utils.uuid.IdUtils;
|
||||
import com.mhd.common.redis.service.RedisService;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
|
||||
/**
|
||||
* token验证处理
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Component
|
||||
public class TokenService
|
||||
{
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Resource
|
||||
private SystemServiceFeign systemServiceFeign;
|
||||
|
||||
protected static final long MILLIS_SECOND = 1000;
|
||||
|
||||
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
||||
|
||||
private static ThreadLocal<Long> expireTime = new ThreadLocal<Long>(){
|
||||
@Override
|
||||
protected Long initialValue() {
|
||||
return CacheConstants.EXPIRATION;
|
||||
}
|
||||
};
|
||||
// private final static long expireTime = CacheConstants.EXPIRATION;
|
||||
|
||||
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
|
||||
|
||||
private final static String USER_LOGIN_TOKENS = CacheConstants.USER_LOGIN_TOKENS;
|
||||
|
||||
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser()
|
||||
{
|
||||
return getLoginUser(ServletUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser(HttpServletRequest request)
|
||||
{
|
||||
// 获取请求携带的令牌
|
||||
String token = SecurityUtils.getToken(request);
|
||||
return getLoginUser(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser(String token)
|
||||
{
|
||||
LoginUser user = null;
|
||||
try
|
||||
{
|
||||
if (StringUtils.isNotEmpty(token))
|
||||
{
|
||||
String userkey = JwtUtils.getUserKey(token);
|
||||
user = redisService.getCacheObject(getTokenKey(userkey));
|
||||
return user;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户身份信息
|
||||
*/
|
||||
public void setLoginUser(LoginUser loginUser)
|
||||
{
|
||||
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
|
||||
{
|
||||
refreshToken(loginUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户缓存信息
|
||||
*/
|
||||
public void delLoginUser(String token)
|
||||
{
|
||||
if (StringUtils.isNotEmpty(token))
|
||||
{
|
||||
String userkey = JwtUtils.getUserKey(token);
|
||||
redisService.deleteObject(getTokenKey(userkey));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证令牌有效期,相差不足120分钟,自动刷新缓存
|
||||
*
|
||||
* @param loginUser
|
||||
*/
|
||||
public void verifyToken(LoginUser loginUser)
|
||||
{
|
||||
long expireTime = loginUser.getExpireTime();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
|
||||
{
|
||||
refreshToken(loginUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
* 过期时间720分钟
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void refreshToken(LoginUser loginUser)
|
||||
{
|
||||
String expireTimeKey = CacheConstants.TOKEN_EXPIRE_TIME+loginUser.getUserPo().getTopOrganizationId();
|
||||
Object cacheObject = redisService.getCacheObject(expireTimeKey);
|
||||
if (cacheObject != null){
|
||||
long l = Long.parseLong(cacheObject.toString());
|
||||
expireTime.set(l);
|
||||
}
|
||||
loginUser.setLoginTime(System.currentTimeMillis());
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime.get() * MILLIS_MINUTE);
|
||||
// 根据uuid将loginUser缓存
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
redisService.setCacheObject(userKey, loginUser, expireTime.get(), TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private String getTokenKey(String token)
|
||||
{
|
||||
return ACCESS_TOKEN + token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description 创建令牌方法新
|
||||
* @Author Alex
|
||||
* @Date 2022/12/6 23:09
|
||||
*/
|
||||
public Map<String, Object> createTokenApi(LoginUser loginUser)
|
||||
{
|
||||
String token = IdUtils.fastUUID();
|
||||
Long userId = loginUser.getUserPo().getUserId();
|
||||
String userAccount = loginUser.getUserPo().getUserAccount();
|
||||
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
|
||||
loginUser.setToken(token);
|
||||
loginUser.setUserid(userId);
|
||||
loginUser.setUsername(userAccount);
|
||||
loginUser.setOs("1");
|
||||
loginUser.setTerminal(RequestHeaderUtil.getTerminal());
|
||||
loginUser.setTerminalLogo(RequestHeaderUtil.getTerminalOS());
|
||||
loginUser.setInitialLoginTime(System.currentTimeMillis());
|
||||
loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
||||
loginUser.setIpRegion(StrUtil.isNotEmpty(loginUser.getIpaddr()) ? IpUtil.getLocationSplicing(loginUser.getIpaddr()) : "");
|
||||
refreshToken(loginUser);
|
||||
|
||||
//是否单点登录
|
||||
AjaxResult<?> ajaxResult = systemServiceFeign.getUserConfigSwitchInfoByOrgId(topOrganizationId);
|
||||
if (!"200".equals(String.valueOf(ajaxResult.get("code"))) || ObjUtil.isNull(JSONObject.toJSONString(ajaxResult.get("data")))) {
|
||||
throw new ServiceException("获取开关配置信息失败");
|
||||
}
|
||||
|
||||
UserConfigSwitchPo userConfigSwitchPo = JSONUtil.toBean(JSONUtil.toJsonStr(ajaxResult.get("data")), UserConfigSwitchPo.class);
|
||||
Integer isSingleSign = userConfigSwitchPo.getIsSingleSign();//单点登录:0-否,1-是
|
||||
if (ObjUtil.isNotNull(isSingleSign) && isSingleSign == 1) {
|
||||
String key = CacheConstants.USER_LOGIN_TOKENS + userId;
|
||||
String tokenStr = redisService.getCacheObject(key);
|
||||
if (StrUtil.isNotEmpty(tokenStr)) {
|
||||
redisService.deleteObject(tokenStr);
|
||||
}
|
||||
redisService.setCacheObject(key, CacheConstants.LOGIN_TOKEN_KEY + token, expireTime.get(), TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
// Jwt存储信息
|
||||
Map<String, Object> claimsMap = new HashMap<String, Object>();
|
||||
claimsMap.put(SecurityConstants.USER_KEY, token);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userAccount);
|
||||
claimsMap.put(SecurityConstants.TOP_ORGANIZATION_ID, topOrganizationId);
|
||||
|
||||
// 接口返回信息
|
||||
Map<String, Object> rspMap = new HashMap<String, Object>();
|
||||
rspMap.put("access_token", JwtUtils.createToken(claimsMap));
|
||||
rspMap.put("expires_in", expireTime.get());
|
||||
return rspMap;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> createTokenApiDingDing(LoginUser loginUser)
|
||||
{
|
||||
String token = IdUtils.fastUUID();
|
||||
Long userId = loginUser.getUserPo().getUserId();
|
||||
String userAccount = loginUser.getUserPo().getUserAccount();
|
||||
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
|
||||
loginUser.setToken(token);
|
||||
loginUser.setUserid(userId);
|
||||
loginUser.setUsername(userAccount);
|
||||
loginUser.setOs("1");
|
||||
loginUser.setTerminal(RequestHeaderUtil.getTerminal());
|
||||
loginUser.setTerminalLogo(RequestHeaderUtil.getTerminalOS());
|
||||
loginUser.setInitialLoginTime(System.currentTimeMillis());
|
||||
loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
||||
loginUser.setIpRegion(StrUtil.isNotEmpty(loginUser.getIpaddr()) ? IpUtil.getLocationSplicing(loginUser.getIpaddr()) : "");
|
||||
refreshToken(loginUser);
|
||||
|
||||
/* //是否单点登录
|
||||
AjaxResult<?> ajaxResult = systemServiceFeign.getUserConfigSwitchInfoByOrgId(topOrganizationId);
|
||||
if (!"200".equals(String.valueOf(ajaxResult.get("code"))) || ObjUtil.isNull(JSONObject.toJSONString(ajaxResult.get("data")))) {
|
||||
throw new ServiceException("获取开关配置信息失败");
|
||||
}*/
|
||||
|
||||
/* UserConfigSwitchPo userConfigSwitchPo = JSONUtil.toBean(JSONUtil.toJsonStr(ajaxResult.get("data")), UserConfigSwitchPo.class);
|
||||
Integer isSingleSign = userConfigSwitchPo.getIsSingleSign();//单点登录:0-否,1-是
|
||||
if (ObjUtil.isNotNull(isSingleSign) && isSingleSign == 1) {
|
||||
String key = CacheConstants.USER_LOGIN_TOKENS + userId;
|
||||
String tokenStr = redisService.getCacheObject(key);
|
||||
if (StrUtil.isNotEmpty(tokenStr)) {
|
||||
redisService.deleteObject(tokenStr);
|
||||
}
|
||||
redisService.setCacheObject(key, CacheConstants.LOGIN_TOKEN_KEY + token, expireTime.get(), TimeUnit.MINUTES);
|
||||
}*/
|
||||
|
||||
// Jwt存储信息
|
||||
Map<String, Object> claimsMap = new HashMap<String, Object>();
|
||||
claimsMap.put(SecurityConstants.USER_KEY, token);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userAccount);
|
||||
claimsMap.put(SecurityConstants.TOP_ORGANIZATION_ID, topOrganizationId);
|
||||
|
||||
// 接口返回信息
|
||||
Map<String, Object> rspMap = new HashMap<String, Object>();
|
||||
rspMap.put("access_token", JwtUtils.createToken(claimsMap));
|
||||
rspMap.put("expires_in", expireTime.get());
|
||||
rspMap.put("userId",userId);
|
||||
return rspMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser refreshData(HttpServletRequest request)
|
||||
{
|
||||
// 获取请求携带的令牌
|
||||
String token = SecurityUtils.getToken(request);
|
||||
LoginUser loginUser = getLoginUser(token);
|
||||
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
* 过期时间720分钟
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void refreshTokenData(LoginUser loginUser) {
|
||||
loginUser.setLoginTime(System.currentTimeMillis());
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime.get() * MILLIS_MINUTE);
|
||||
// 根据uuid将loginUser缓存
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
redisService.setCacheObject(userKey, loginUser, expireTime.get(), TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
package com.mhd.common.security.service.report;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.mhd.common.core.constant.CacheConstants;
|
||||
import com.mhd.common.core.domain.dto.wlhy.report.CapitalFlowReport;
|
||||
import com.mhd.common.core.domain.dto.wlhy.report.DriverReport;
|
||||
import com.mhd.common.core.domain.dto.wlhy.report.TransportNoteReport;
|
||||
import com.mhd.common.core.domain.dto.wlhy.report.VehicleReport;
|
||||
import com.mhd.common.core.domain.entity.OrgProductConfig;
|
||||
import com.mhd.common.core.domain.po.UserConfigSwitchPo;
|
||||
import com.mhd.common.core.domain.po.UserDriverPo;
|
||||
import com.mhd.common.core.domain.po.UserPo;
|
||||
import com.mhd.common.core.domain.po.VehiclePo;
|
||||
import com.mhd.common.core.domain.po.report.UserDriverReportPo;
|
||||
import com.mhd.common.core.domain.po.report.VehicleReportPo;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
|
||||
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.common.redis.service.RedisService;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.system.api.ReportServiceFeign;
|
||||
import com.mhd.system.api.SystemServiceFeign;
|
||||
import com.mhd.system.api.domain.WlhyLoginUser;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 上报通用服务类
|
||||
*/
|
||||
@Service
|
||||
public class ReportDomainService {
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Resource
|
||||
private ReportServiceFeign reportServiceFeign;
|
||||
|
||||
@Resource
|
||||
private SystemServiceFeign systemServiceFeign;
|
||||
|
||||
|
||||
/**
|
||||
* 数字物流网货司机 - 数据上送
|
||||
*/
|
||||
public boolean driverReport(UserDriverReportPo driverReportPo) {
|
||||
if (ObjectUtil.isNull(driverReportPo)) {
|
||||
throw new ServiceException("上送数据不能为空");
|
||||
}
|
||||
//检查是否开启网货
|
||||
boolean flag = checkSwitch();
|
||||
if (!flag) {
|
||||
//如果未配置网货产品,返回跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
//检查是否开始数据保存
|
||||
Integer isPushReportData = getUserConfigSwitch().getIsPushReportData();
|
||||
if (isPushReportData != 1){
|
||||
return true;
|
||||
}
|
||||
|
||||
DriverReport driverReport = driverEntityConvertReport(driverReportPo);
|
||||
return aa(reportServiceFeign.receive(driverReport));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数字物流网货车辆 - 数据上送
|
||||
*/
|
||||
public boolean vehicleReport(VehicleReportPo vehicleReportPo) {
|
||||
|
||||
if (ObjectUtil.isNull(vehicleReportPo)) {
|
||||
throw new ServiceException("上送数据不能为空");
|
||||
}
|
||||
//检查是否开启网货
|
||||
boolean flag = checkSwitch();
|
||||
if (!flag) {
|
||||
//如果未配置网货产品,返回跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
//检查是否开始数据保存
|
||||
Integer isPushReportData = getUserConfigSwitch().getIsPushReportData();
|
||||
if (isPushReportData != 1){
|
||||
return true;
|
||||
}
|
||||
|
||||
VehicleReport vehicleReport = vehicleEntityConvertReport(vehicleReportPo);
|
||||
return aa(reportServiceFeign.receive(vehicleReport));
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字物流网货流水 - 数据上送
|
||||
*/
|
||||
public boolean capitalFlowReport(List<CapitalFlowReport> capitalFlowReports) {
|
||||
|
||||
if (ObjectUtil.isNull(capitalFlowReports)) {
|
||||
throw new ServiceException("上送数据不能为空");
|
||||
}
|
||||
//检查是否开启网货
|
||||
boolean flag = checkSwitch();
|
||||
if (!flag) {
|
||||
//如果未配置网货产品,返回跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
//检查是否开始数据保存
|
||||
Integer isPushReportData = getUserConfigSwitch().getIsPushReportData();
|
||||
if (isPushReportData != 1){
|
||||
return true;
|
||||
}
|
||||
|
||||
return aa(reportServiceFeign.receive(capitalFlowReports));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 数字物流网货运单 - 数据上送
|
||||
// */
|
||||
// public boolean transportNoteReport(VehicleReportPo vehicleReportPo) {
|
||||
//
|
||||
// if (ObjectUtil.isNull(vehicleReportPo)) {
|
||||
// throw new ServiceException("上送数据不能为空");
|
||||
// }
|
||||
// //检查是否开启网货
|
||||
// boolean flag = checkSwitch();
|
||||
// if (!flag) {
|
||||
// //如果未配置网货产品,返回跳过
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// TransportNoteReport vehicleReport = transportNoteEntityConvertReport(vehicleReportPo);
|
||||
// return aa(reportServiceFeign.receive(vehicleReport));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 数字物流网货运单 - 数据拼装
|
||||
// */
|
||||
// private TransportNoteReport transportNoteEntityConvertReport(TransportNoteReport transportNoteReport) {
|
||||
// WlhyLoginUser wlhyLoginUser = SecurityUtils.getLoginUser().getWlhyLoginUser();
|
||||
//
|
||||
//
|
||||
// return TransportNoteReport.builder()
|
||||
// .build();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 数字物流网货流水 - 数据拼装
|
||||
// */
|
||||
// private TransportNoteReport capitalFlowEntityConvertReport(TransportNoteReport transportNoteReport) {
|
||||
// WlhyLoginUser wlhyLoginUser = SecurityUtils.getLoginUser().getWlhyLoginUser();
|
||||
//
|
||||
//
|
||||
// return TransportNoteReport.builder()
|
||||
// .build();
|
||||
// }
|
||||
|
||||
/**
|
||||
* 数字物流网货司机 - 数据拼装
|
||||
*/
|
||||
private DriverReport driverEntityConvertReport(UserDriverReportPo driver) {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
throw new DigitalLogisticsException(UserError.TIMEOUT);
|
||||
}
|
||||
int isCheckWorkCertificate = 0;
|
||||
switch (driver.getDriverWorkLicenseAuthStatus()) {
|
||||
case 2:
|
||||
isCheckWorkCertificate = 1;
|
||||
break;
|
||||
case 3:
|
||||
isCheckWorkCertificate = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return DriverReport
|
||||
.builder()
|
||||
.driverId(driver.getUserId().toString())
|
||||
.driverName(driver.getUserName())
|
||||
.drivingLicense(driver.getUserIdcardNumber())
|
||||
.vehicleClass(driver.getDriverAllowDrivingTypeName())
|
||||
.issuingOrganizations(driver.getDriverCertificationAuthority())
|
||||
.qualificationCertificate(driver.getDriverWorkLicenseNumber())
|
||||
.telephone(driver.getUserPhone())
|
||||
.remark(driver.getUserRemark())
|
||||
.validPeriodFrom(StrUtil.isNotEmpty(driver.getDriverLicenseDateFrom()) ? DateUtil.parseDate(driver.getDriverLicenseDateFrom()) : null)
|
||||
.validPeriodTo(StrUtil.isNotEmpty(driver.getDriverLicenseDateTo()) ? DateUtil.parseDate(driver.getDriverLicenseDateTo()) : null)
|
||||
.idCardPeriodFrom(StrUtil.isNotEmpty(driver.getUserIdcardDateFrom()) ? DateUtil.parseDate(driver.getUserIdcardDateFrom()) : null)
|
||||
.idCardPeriodTo(StrUtil.isNotEmpty(driver.getUserIdcardDateTo()) ? DateUtil.parseDate(driver.getUserIdcardDateTo()) : null)
|
||||
.idCardIsEndless(driver.getUserIdcardLong() == 1 ? 1 : 0)
|
||||
.icenseFirstGetDate(StrUtil.isNotEmpty(driver.getDriverLicenseFirstDate()) ? DateUtil.parseDate(driver.getDriverLicenseFirstDate()) : null)
|
||||
.identificationNumber(driver.getUserIdcardNumber())
|
||||
.vehicleId(driver.getVehicleId().toString())
|
||||
.vehicleNumber(driver.getVehicleLicensePlateNumber())
|
||||
.grossMass(driver.getVehicleApprovedLoadQuantity())
|
||||
.isCheckWorkCertificate(isCheckWorkCertificate)
|
||||
.typeFlag(driver.getTypeFlag())
|
||||
.organizationId(driver.getOrganizationId())
|
||||
.organizationName(driver.getOrganizationName())
|
||||
.topOrganizationId(driver.getTopOrganizationId())
|
||||
.belongSystem("wlhy")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数字物流网货车辆 - 数据拼装
|
||||
*/
|
||||
private VehicleReport vehicleEntityConvertReport(VehicleReportPo vehicle) {
|
||||
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
throw new DigitalLogisticsException(UserError.TIMEOUT);
|
||||
}
|
||||
|
||||
int checkRtcNo = 0;
|
||||
switch (vehicle.getRoadTransportCertificateCheckoutStatus()) {
|
||||
case 1:
|
||||
checkRtcNo = 0;
|
||||
break;
|
||||
case 2:
|
||||
checkRtcNo = 1;
|
||||
break;
|
||||
default:
|
||||
checkRtcNo = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return VehicleReport
|
||||
.builder()
|
||||
.vehicleId(vehicle.getVehicleId().toString())
|
||||
.vehicleNumber(vehicle.getVehicleLicensePlateNumber())
|
||||
.vehiclePlateColorCode(vehicle.getOtherLicensePlateColorId())
|
||||
.vehiclePlateColor(vehicle.getOtherLicensePlateColorName())
|
||||
.vehicleTypeId(vehicle.getVehicleTypeId())
|
||||
.vehicleType(vehicle.getVehicleTypeName())
|
||||
.owner(vehicle.getVehicleUsePerson())
|
||||
.useCharacter(vehicle.getVehicleUseNature())
|
||||
.vin(vehicle.getVehicleIdentificationNumber())
|
||||
.issuingOrganizations(vehicle.getVehicleLicenceIssuingAuthority())
|
||||
.brand(vehicle.getVehicleBrandType())
|
||||
.engineNumber(vehicle.getVehicleEngineNumber())
|
||||
.registerDate(vehicle.getVehicleRegistrationDate())
|
||||
.issueDate(vehicle.getVehicleIssueDate())
|
||||
.transportLicenseExpireDate(vehicle.getRoadTransportCertificateExpireDate())
|
||||
.vehicleEnergyTypeId(vehicle.getVehicleEnergyTypeId())
|
||||
.vehicleEnergyType(vehicle.getVehicleEnergyTypeName())
|
||||
.vehicleTonnage(vehicle.getVehicleApprovedLoadQuantity())
|
||||
.grossMass(vehicle.getVehicleTotalMass())
|
||||
.roadTransportCertificateNumber(vehicle.getRoadTransportCertificateNo())
|
||||
.trailerVehiclePlateNumber(vehicle.getTrailerLicensePlateNumber())
|
||||
.remark(vehicle.getVehicleRemark())
|
||||
.driverId(vehicle.getUserId().toString())
|
||||
.driverName(vehicle.getUserName())
|
||||
.phone(vehicle.getUserPhone())
|
||||
.checkRtcNo(checkRtcNo)
|
||||
.checkEnterpriseRoadLicense(vehicle.getCheckEnterpriseRoadLicense())
|
||||
.checkTruckExist(vehicle.getNetInStatus())
|
||||
.organizationId(vehicle.getOrganizationId())
|
||||
.organizationName(vehicle.getOrganizationName())
|
||||
.topOrganizationId(vehicle.getTopOrganizationId())
|
||||
.belongSystem("wlhy")
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否配置网货产品
|
||||
*
|
||||
* @return true-开启,false-关闭
|
||||
*/
|
||||
private boolean checkSwitch() {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
throw new DigitalLogisticsException(UserError.TIMEOUT);
|
||||
}
|
||||
String key = CacheConstants.ORG_PRODUCT_KEY + loginUser.getUserPo().getTopOrganizationId();
|
||||
OrgProductConfig orgProductConfig = redisService.getCacheObject(key);
|
||||
if (null == orgProductConfig) {
|
||||
return false;
|
||||
}
|
||||
//配置网货
|
||||
return orgProductConfig.getWlhyFlag() == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所在组织的开关配置信息
|
||||
* @return
|
||||
*/
|
||||
public UserConfigSwitchPo getUserConfigSwitch() {
|
||||
//获取登录人信息
|
||||
UserConfigSwitchPo userConfigSwitchPo;
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
UserPo userPo = loginUser.getUserPo();
|
||||
Long organizationId = userPo.getOrganizationId();
|
||||
userConfigSwitchPo = redisService.getCacheObject(CacheConstants.USER_COMFIG_SWITCH_KEY + organizationId);
|
||||
if(null == userConfigSwitchPo || userConfigSwitchPo.getUserConfigSwitchId() == null){
|
||||
//查询数据库,并且存到redis中
|
||||
AjaxResult ajaxResult = systemServiceFeign.getUserConfigSwitchInfo();
|
||||
if("200".equals(String.valueOf(ajaxResult.get("code")))){
|
||||
userConfigSwitchPo = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserConfigSwitchPo.class);
|
||||
if(null != userConfigSwitchPo){
|
||||
//存入redis中
|
||||
redisService.setCacheObject(CacheConstants.USER_COMFIG_SWITCH_KEY + organizationId ,userConfigSwitchPo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return userConfigSwitchPo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理响应结果
|
||||
*/
|
||||
private boolean aa(AjaxResult receive) {
|
||||
if (null != receive && "200".equals(String.valueOf(receive.get("code")))) {
|
||||
return true;
|
||||
} else if (null != receive && !"200".equals(String.valueOf(receive.get("code")))) {
|
||||
throw new ServiceException("数据上送失败:" + receive.get("msg"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.mhd.common.security.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.mhd.common.core.constant.Constants;
|
||||
import com.mhd.common.core.utils.SpringUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.common.redis.service.RedisService;
|
||||
import com.mhd.system.api.domain.SysDictData;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class DictUtils
|
||||
{
|
||||
/**
|
||||
* 设置字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @param dictDatas 字典数据列表
|
||||
*/
|
||||
public static void setDictCache(String key, List<SysDictData> dictDatas)
|
||||
{
|
||||
SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @return dictDatas 字典数据列表
|
||||
*/
|
||||
public static List<SysDictData> getDictCache(String key)
|
||||
{
|
||||
JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNotNull(arrayCache))
|
||||
{
|
||||
return arrayCache.toList(SysDictData.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定字典缓存
|
||||
*
|
||||
* @param key 字典键
|
||||
*/
|
||||
public static void removeDictCache(String key)
|
||||
{
|
||||
SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
public static void clearDictCache()
|
||||
{
|
||||
Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(Constants.SYS_DICT_KEY + "*");
|
||||
SpringUtils.getBean(RedisService.class).deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
public static String getCacheKey(String configKey)
|
||||
{
|
||||
return Constants.SYS_DICT_KEY + configKey;
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.mhd.common.security.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import com.mhd.common.core.constant.SecurityConstants;
|
||||
import com.mhd.common.core.constant.TokenConstants;
|
||||
import com.mhd.common.core.context.SecurityContextHolder;
|
||||
import com.mhd.common.core.utils.ServletUtils;
|
||||
import com.mhd.common.core.utils.StringUtils;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
|
||||
/**
|
||||
* 权限获取工具类
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class SecurityUtils
|
||||
{
|
||||
/**
|
||||
* 获取用户ID
|
||||
*/
|
||||
public static Long getUserId()
|
||||
{
|
||||
return SecurityContextHolder.getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户名称
|
||||
*/
|
||||
public static String getUsername()
|
||||
{
|
||||
return SecurityContextHolder.getUserName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户key
|
||||
*/
|
||||
public static String getUserKey()
|
||||
{
|
||||
return SecurityContextHolder.getUserKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户信息
|
||||
*/
|
||||
public static LoginUser getLoginUser()
|
||||
{
|
||||
return SecurityContextHolder.get(SecurityConstants.LOGIN_USER, LoginUser.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求token
|
||||
*/
|
||||
public static String getToken()
|
||||
{
|
||||
return getToken(ServletUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据request获取请求token
|
||||
*/
|
||||
public static String getToken(HttpServletRequest request)
|
||||
{
|
||||
// 从header获取token标识
|
||||
String token = request.getHeader(TokenConstants.AUTHENTICATION);
|
||||
return replaceTokenPrefix(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁剪token前缀
|
||||
*/
|
||||
public static String replaceTokenPrefix(String token)
|
||||
{
|
||||
// 如果前端设置了令牌前缀,则裁剪掉前缀
|
||||
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
|
||||
{
|
||||
token = token.replaceFirst(TokenConstants.PREFIX, "");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为管理员
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isAdmin(Long userId)
|
||||
{
|
||||
return userId != null && 1L == userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成BCryptPasswordEncoder密码
|
||||
*
|
||||
* @param password 密码
|
||||
* @return 加密字符串
|
||||
*/
|
||||
public static String encryptPassword(String password)
|
||||
{
|
||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
return passwordEncoder.encode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断密码是否相同
|
||||
*
|
||||
* @param rawPassword 真实密码
|
||||
* @param encodedPassword 加密后字符
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean matchesPassword(String rawPassword, String encodedPassword)
|
||||
{
|
||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
return passwordEncoder.matches(rawPassword, encodedPassword);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.mhd.common.security.utils.password;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.mhd.common.core.domain.po.UserPo;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.utils.AESUtil;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.system.api.UserServiceFeign;
|
||||
import com.mhd.system.api.model.LoginUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
|
||||
/**
|
||||
* @Description 密码校验工具类
|
||||
* @Author zg
|
||||
* @Version 1.0
|
||||
* @Date 2023/11/8 8:55
|
||||
*/
|
||||
//@Component
|
||||
public class PasswordCheckUtils {
|
||||
|
||||
// @Autowired
|
||||
// private UserServiceFeign userServiceFeign;
|
||||
//
|
||||
// private static PasswordCheckUtils utils;
|
||||
//
|
||||
// public PasswordCheckUtils(UserServiceFeign userServiceFeign) {
|
||||
// this.userServiceFeign = userServiceFeign;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @PostConstruct
|
||||
// public void init(){
|
||||
// utils = this;
|
||||
// utils.userServiceFeign= userServiceFeign;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param payPassword 支付密码
|
||||
* @param userPo 用户信息
|
||||
* @return
|
||||
*/
|
||||
public static boolean payPasswordCheck(String payPassword, UserPo userPo) {
|
||||
//解密支付密码
|
||||
payPassword = AESUtil.decrypt(payPassword);
|
||||
if (StrUtil.isEmpty(payPassword)){
|
||||
throw new ServiceException("解密失败");
|
||||
}
|
||||
|
||||
if (ObjUtil.isEmpty(userPo)){
|
||||
throw new ServiceException("用户信息不能为空");
|
||||
}
|
||||
|
||||
if (StrUtil.isEmpty(userPo.getUserPayPassword())) {
|
||||
throw new ServiceException("请设置支付密码");
|
||||
}
|
||||
|
||||
//校验用户支付密码是否正确
|
||||
return PasswordUtil.matchesPassword(userPo.getUserAccount(), payPassword, userPo.getUserSalt(), userPo.getUserPayPassword());
|
||||
}
|
||||
|
||||
// public static boolean payPasswordCheck1(String payPassword) {
|
||||
// //解密支付密码
|
||||
// payPassword = AESUtil.decrypt(payPassword);
|
||||
// if (StrUtil.isEmpty(payPassword)){
|
||||
// throw new ServiceException("密码解密失败");
|
||||
// }
|
||||
//
|
||||
// //获取当前登录人
|
||||
// LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
// UserPo userPo = loginUser.getUserPo();
|
||||
// //临时方案,用户修改密码后,用token获取用户信息,数据不一致,需要重新获取用户信息
|
||||
// AjaxResult ajaxResult = utils.userServiceFeign.getInfo(userPo.getUserId());
|
||||
// if("200".equals(String.valueOf(ajaxResult.get("code")))){
|
||||
// userPo = JSONUtil.toBean(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
||||
// }else {
|
||||
// throw new ServiceException("用户信息获取失败");
|
||||
// }
|
||||
// if (StrUtil.isEmpty(userPo.getUserPayPassword())) {
|
||||
// throw new ServiceException("请设置支付密码");
|
||||
// }
|
||||
//
|
||||
// //校验用户支付密码是否正确
|
||||
// return PasswordUtil.matchesPassword(userPo.getUserAccount(), payPassword, userPo.getUserSalt(), userPo.getUserPayPassword());
|
||||
// }
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
package com.mhd.common.security.utils.password;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
import java.security.Key;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class PasswordUtil {
|
||||
|
||||
/**
|
||||
* JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
|
||||
* PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
|
||||
* */
|
||||
|
||||
/**
|
||||
* 定义使用的算法为:PBEWITHMD5andDES算法
|
||||
*/
|
||||
public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
|
||||
public static final String Salt = "26847931";//密钥
|
||||
|
||||
/**
|
||||
* 定义迭代次数为1000次
|
||||
*/
|
||||
private static final int ITERATIONCOUNT = 1000;
|
||||
|
||||
/**
|
||||
* 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
|
||||
*
|
||||
* @return byte[] 盐值
|
||||
*/
|
||||
public static byte[] getSalt() throws Exception {
|
||||
// 实例化安全随机数
|
||||
SecureRandom random = new SecureRandom();
|
||||
// 产出盐
|
||||
return random.generateSeed(8);
|
||||
}
|
||||
|
||||
public static byte[] getStaticSalt() {
|
||||
// 产出盐
|
||||
return Salt.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据PBE密码生成一把密钥
|
||||
*
|
||||
* @param password 生成密钥时所使用的密码
|
||||
* @return Key PBE算法密钥
|
||||
*/
|
||||
private static Key getPBEKey(String password) {
|
||||
// 实例化使用的算法
|
||||
SecretKeyFactory keyFactory;
|
||||
SecretKey secretKey = null;
|
||||
try {
|
||||
keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
|
||||
// 设置PBE密钥参数
|
||||
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
|
||||
// 生成密钥
|
||||
secretKey = keyFactory.generateSecret(keySpec);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密明文字符串
|
||||
*
|
||||
* @param plaintext 待加密的明文字符串
|
||||
* @param password 生成密钥时所使用的密码
|
||||
* @param salt 盐值
|
||||
* @return 加密后的密文字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String plaintext, String password, String salt) {
|
||||
|
||||
Key key = getPBEKey(password);
|
||||
byte[] encipheredData = null;
|
||||
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
|
||||
//update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
|
||||
encipheredData = cipher.doFinal(plaintext.getBytes("utf-8"));
|
||||
//update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return bytesToHexString(encipheredData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密密文字符串
|
||||
*
|
||||
* @param ciphertext 待解密的密文字符串
|
||||
* @param password 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
|
||||
* @param salt 盐值(如需解密,该参数需要与加密时使用的一致)
|
||||
* @return 解密后的明文字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decrypt(String ciphertext, String password, String salt) {
|
||||
|
||||
Key key = getPBEKey(password);
|
||||
byte[] passDec = null;
|
||||
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
|
||||
|
||||
passDec = cipher.doFinal(hexStringToBytes(ciphertext));
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
return new String(passDec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param src 字节数组
|
||||
* @return
|
||||
*/
|
||||
public static String bytesToHexString(byte[] src) {
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
if (src == null || src.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
int v = src[i] & 0xFF;
|
||||
String hv = Integer.toHexString(v);
|
||||
if (hv.length() < 2) {
|
||||
stringBuilder.append(0);
|
||||
}
|
||||
stringBuilder.append(hv);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符串转换为字节数组
|
||||
*
|
||||
* @param hexString 十六进制字符串
|
||||
* @return
|
||||
*/
|
||||
public static byte[] hexStringToBytes(String hexString) {
|
||||
if (hexString == null || hexString.equals("")) {
|
||||
return null;
|
||||
}
|
||||
hexString = hexString.toUpperCase();
|
||||
int length = hexString.length() / 2;
|
||||
char[] hexChars = hexString.toCharArray();
|
||||
byte[] d = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int pos = i * 2;
|
||||
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private static byte charToByte(char c) {
|
||||
return (byte) "0123456789ABCDEF".indexOf(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断密码是否相同
|
||||
*
|
||||
* @param userAccount 登录账号
|
||||
* @param rawPassword 真实密码
|
||||
* @param salt 盐
|
||||
* @param encodedPassword 加密后字符
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean matchesPassword(String userAccount,String rawPassword, String salt, String encodedPassword) {
|
||||
Boolean matches = false;
|
||||
String passwordEncode = encrypt(userAccount, rawPassword, salt);
|
||||
matches = passwordEncode.equals(encodedPassword);
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user