Merge remote-tracking branch 'origin/develop_master' into develop_3
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package com.adc.da.FeignClient;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @author: super_liu
|
||||
* @date: 2021年10月11日 13:33
|
||||
*/
|
||||
|
||||
/**
|
||||
* Feign配置
|
||||
* 使用FeignClient进行服务间调用,传递headers信息
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignConfig implements RequestInterceptor {
|
||||
@Override
|
||||
public void apply(RequestTemplate requestTemplate) {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
|
||||
if(attributes != null){
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
//添加token
|
||||
requestTemplate.header("token", request.getHeader("token"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,11 @@ import java.util.Set;
|
||||
//@FeignClient(value = "shan6")
|
||||
public interface workFlowFeignClient {
|
||||
|
||||
@RequestMapping(value = "/bat-wkflow/oaTaskExec/execTask",method = RequestMethod.GET)
|
||||
Map<String,Object> execTask(@RequestParam("todoId") String todoId);
|
||||
|
||||
@RequestMapping(value = "/bat-wkflow/task/get_verify_by_instance",method = RequestMethod.GET)
|
||||
long get_verify_by_instance(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId);
|
||||
Map<String,Object> get_verify_by_instance(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId);
|
||||
|
||||
@RequestMapping(value = "/bat-wkflow/activiti_define_start_user",method = RequestMethod.GET)
|
||||
Wrapper<String> activiti_define_start(@RequestParam("id") String id, @RequestParam("userId") String userId, @RequestParam("bpnId") String bpnId);
|
||||
|
||||
+7
-2
@@ -25,8 +25,13 @@ public class workFlowFeignClientImpl {
|
||||
@Autowired
|
||||
private IUserEOService userEOService;
|
||||
|
||||
public long get_verify_by_instance(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId){
|
||||
long stringWrapper = workFlowFeignClient.get_verify_by_instance(taskId,pId);
|
||||
public Map<String,Object> execTask(@RequestParam("todoId") String todoId){
|
||||
Map<String,Object> stringWrapper = workFlowFeignClient.execTask(todoId);
|
||||
return stringWrapper;
|
||||
}
|
||||
|
||||
public Map<String,Object> get_verify_by_instance(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId){
|
||||
Map<String,Object> stringWrapper = workFlowFeignClient.get_verify_by_instance(taskId,pId);
|
||||
return stringWrapper;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,5 +44,7 @@ public class BusProcessNew {
|
||||
|
||||
private String finishFlag;
|
||||
|
||||
private long commitStatus;
|
||||
|
||||
|
||||
}
|
||||
|
||||
+13
-6
@@ -35,10 +35,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/${restPath}/lawss/activiti")
|
||||
@@ -51,9 +49,15 @@ public class WorkFlowController {
|
||||
// @Autowired
|
||||
// private ExportExcelMapper exportExcelMapper;
|
||||
|
||||
@ApiOperation(value = "干活流程接收待办")
|
||||
@GetMapping("/execTask")
|
||||
public Map<String,Object> execTask(@RequestParam("todoId") String todoId){
|
||||
return workFlowFeignClient.execTask(todoId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "流程实例明细验证是否完成")
|
||||
@GetMapping("/get_verify_by_instance")
|
||||
public long activiti_define_start1(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId){
|
||||
public Map<String,Object> activiti_define_start1(@RequestParam("taskId") String taskId, @RequestParam("pId") String pId){
|
||||
return workFlowFeignClient.get_verify_by_instance(taskId,pId);
|
||||
}
|
||||
|
||||
@@ -68,8 +72,11 @@ public class WorkFlowController {
|
||||
if(exportExcelEO.getFileName()==null||exportExcelEO.getFileName().trim().length()==0){
|
||||
exportExcelEO.setFileName(UUID.fastUUID().toString(true));
|
||||
}
|
||||
List<Map<String, Object>> dataList = exportExcelEO.getDataList().stream()
|
||||
.sorted(Comparator.comparing(a -> String.valueOf(a.get("chapterNumber").toString())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Workbook excel = TableToExcel.createExcel(exportExcelEO.getColumnName(), exportExcelEO.getDataList(), null, exportExcelEO.getFileName());
|
||||
Workbook excel = TableToExcel.createExcel(exportExcelEO.getColumnName(), dataList, null, exportExcelEO.getFileName());
|
||||
|
||||
response.reset();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.adc.da.http;
|
||||
public enum ResponseMessageCodeEnum {
|
||||
SUCCESS("0"),
|
||||
ERROR("-1"),
|
||||
ERROR_TOKEN("LE505"),
|
||||
VALID_ERROR("1000"),
|
||||
SAVE_SUCCESS("r0001"),
|
||||
UPDATE_SUCCESS("r0002"),
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.adc.da.login.exception;
|
||||
|
||||
import com.adc.da.http.ResponseMessage;
|
||||
import com.adc.da.http.Result;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* 全局异常处理
|
||||
*
|
||||
* @author ch
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
* <p>
|
||||
* Created at 2020/8/6 5:03 下午
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class SysRuntimeExceptionHandler {
|
||||
|
||||
@ExceptionHandler(TokenRuntimeException.class)
|
||||
public ResponseMessage tokenRuntimeException(TokenRuntimeException e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(e.getCode(), e.getMsg());
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseMessage handlerException(Exception e){
|
||||
e.printStackTrace();
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.adc.da.login.exception;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 自定义 token 异常
|
||||
*
|
||||
* @author ch
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
* <p>
|
||||
* Created at 2020/8/6 4:58 下午
|
||||
*/
|
||||
@Data
|
||||
public class TokenRuntimeException extends RuntimeException{
|
||||
|
||||
private String code = "401";
|
||||
private String msg;
|
||||
|
||||
public TokenRuntimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,14 +3,11 @@ package com.adc.da.login.rest;
|
||||
|
||||
import com.adc.da.http.ResponseMessage;
|
||||
import com.adc.da.http.Result;
|
||||
import com.adc.da.login.util.JWTUtil;
|
||||
import com.adc.da.login.util.UserUtils;
|
||||
import com.adc.da.login.vo.LoginVO;
|
||||
import com.adc.da.sys.entity.MenuEO;
|
||||
import com.adc.da.login.exception.TokenRuntimeException;
|
||||
import com.adc.da.login.util.IDMUtil;
|
||||
import com.adc.da.login.util.JwtUtils;
|
||||
import com.adc.da.sys.entity.UserEO;
|
||||
import com.adc.da.sys.service.IUserEOService;
|
||||
import com.adc.da.sys.vo.UserVO;
|
||||
import com.adc.da.util.Encodes;
|
||||
import com.adc.da.util.PasswordUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -18,20 +15,20 @@ import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Validated
|
||||
@@ -43,84 +40,10 @@ public class LoginRestController {
|
||||
|
||||
@Autowired
|
||||
private IUserEOService userService;
|
||||
|
||||
|
||||
/**
|
||||
* 读取配置文件判断是否需要开启Base64加密,默认值为false
|
||||
*/
|
||||
@Value("${isPassEncrypted:false}")
|
||||
private boolean isPassEncrypted;
|
||||
|
||||
/**
|
||||
* 无缓存,用于校验
|
||||
*/
|
||||
private static final String NO_CACHE = "no-cache";
|
||||
|
||||
/**
|
||||
* 登录失败Map字段
|
||||
*/
|
||||
private static final String LOGIN_FAIL_MAP = "loginFailMap";
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private static final Object VERIFY_CODE = "VerifyCode";
|
||||
|
||||
/**
|
||||
* 10分钟内最大错误次数
|
||||
*/
|
||||
@Value("${maxLoginErrorCount:3}")
|
||||
private int maxLoginErrorCount;
|
||||
|
||||
|
||||
/**
|
||||
* 读取验证码模式配置,
|
||||
* 1为不开启,2为开启,3为三次输错用户名或密码才开启,
|
||||
* 默认为1
|
||||
* <p>
|
||||
* 若配置文件缺少该参数,将设置为1
|
||||
*/
|
||||
@Value("${verifyCodeMode:1}")
|
||||
private int verifyCodeMode;
|
||||
|
||||
|
||||
// @ApiOperation(value = "登录")
|
||||
// @PostMapping(value = "/login")
|
||||
// @ResponseBody
|
||||
// public ResponseMessage<String> loginWithVerifyCode(HttpServletResponse response, @RequestBody LoginVO loginVO) {
|
||||
// String username = loginVO.getUsername();
|
||||
// String password = loginVO.getPassword();
|
||||
// String key = loginVO.getKey();
|
||||
//
|
||||
// if (StringUtils.isBlank(username)) {
|
||||
// return Result.error("r0014", "登录名不能为空");
|
||||
// }
|
||||
// if (StringUtils.isBlank(password)) {
|
||||
// return Result.error("r0016", "密码不能为空");
|
||||
// }
|
||||
// if (StringUtils.isBlank(key)) {
|
||||
// return Result.error("key不能为空");
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// UserEO userEO = userService.getUserByLoginNameNotDeleted(username);
|
||||
// if (null == userEO) {
|
||||
// log.info("用户[{}]身份验证失败", username);
|
||||
// return Result.error("r0011", "您输入的帐号或密码有误");
|
||||
// }
|
||||
// if (PasswordUtils.validatePassword(password, userEO.getPassword())) {
|
||||
// String token = JWTUtil.sign(username, userEO.getPassword(), userEO.getUsid());
|
||||
// response.setHeader("Authorization", token);
|
||||
// response.addHeader("Access-Control-Allow-Headers", "Authorization");
|
||||
// return Result.success(token);
|
||||
// } else {
|
||||
// log.info("用户[{}]密码验证失败", username);
|
||||
// return Result.error("r0011", "您输入的帐号或密码有误");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
@Autowired
|
||||
private IDMUtil idmUtil;
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
|
||||
@ApiOperation(value = "登录")
|
||||
// @GetMapping(value = "/login")
|
||||
@@ -140,11 +63,10 @@ public class LoginRestController {
|
||||
return Result.error("r0011", "您输入的帐号已禁用");
|
||||
}
|
||||
if (PasswordUtils.validatePassword(password, userEO.getPassword())) {
|
||||
String token = JWTUtil.sign(username, userEO.getUsid(),userEO.getPassword());
|
||||
response.setHeader("Authorization", token);
|
||||
response.addHeader("Access-Control-Allow-Headers", "Authorization");
|
||||
String token = jwtUtils.generateToken(userEO.getUsid());
|
||||
// 加密重要信息
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
userEO.setToken(token);
|
||||
String userStr = JSON.toJSONString(userEO);
|
||||
String userStr2 = URLEncoder.encode(userStr,"UTF-8");
|
||||
userStr = encoder.encode(userStr2.getBytes());
|
||||
@@ -156,69 +78,50 @@ public class LoginRestController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 退出登录,客户端把Token丢弃就可以
|
||||
*/
|
||||
@ApiOperation(value = "退出登录")
|
||||
@GetMapping("/logout")
|
||||
@ApiOperation(value = "登录")
|
||||
@PostMapping(value = "/loginIdm")
|
||||
@ResponseBody
|
||||
public ResponseMessage logout(HttpServletResponse response,String ticket) {
|
||||
UserUtils.logout();
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "未授权访问")
|
||||
@RequestMapping(path = "/401")
|
||||
@ResponseBody
|
||||
public ResponseMessage unauthorized() {
|
||||
return Result.error("401", "Unauthorized");
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录成功之后获取当前登录用户信息的接口
|
||||
*/
|
||||
@ApiOperation(value = "获取登录用户信息")
|
||||
@GetMapping("/userInfo")
|
||||
@ResponseBody
|
||||
public ResponseMessage<UserEO> userInfo(HttpServletResponse response) throws NumberFormatException {
|
||||
UserEO user = UserUtils.getUser();
|
||||
if (user != null) {
|
||||
return Result.success(user);
|
||||
public ResponseMessage<String> loginRest(String code) throws UnsupportedEncodingException {
|
||||
String account = idmUtil.idmLogin(code);
|
||||
if(StringUtils.isBlank(account)){
|
||||
return Result.error("r0011", "用户不存在");
|
||||
}
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return Result.error();
|
||||
/**
|
||||
* TODO OA 用户不全 待同步
|
||||
*/
|
||||
UserEO userEO = userService.getUserByLoginNameNotDeleted("admin");
|
||||
if (null == userEO) {
|
||||
return Result.error("r0011", "用户不存在");
|
||||
}
|
||||
if(userEO.getDisableFlag()==1){
|
||||
return Result.error("r0011", "帐号已禁用");
|
||||
}
|
||||
String token = jwtUtils.generateToken(account);
|
||||
userEO.setToken(token);
|
||||
// 加密重要信息
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
String userStr = JSON.toJSONString(userEO);
|
||||
String userStr2 = URLEncoder.encode(userStr,"UTF-8");
|
||||
userStr = encoder.encode(userStr2.getBytes());
|
||||
return Result.success(userStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户菜单,已用菜单管理实现
|
||||
*/
|
||||
@ApiOperation(value = "获取登录用户菜单权限")
|
||||
@GetMapping("/userMenu")
|
||||
@ResponseBody
|
||||
public ResponseMessage<List<MenuEO>> userMenu(){
|
||||
return Result.success(UserUtils.getMenuList());
|
||||
@ApiOperation(value = "登出")
|
||||
@PostMapping(value = "/logout")
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response){
|
||||
Cookie[] cookies = request.getCookies();
|
||||
try {
|
||||
for(int i=0;i < cookies.length;i++) {
|
||||
Cookie cookie = new Cookie(cookies[i].getName(), null);
|
||||
cookie.setMaxAge(0);
|
||||
cookie.setPath("testsso1.foton.com.cn");//根据你创建cookie的路径进行填写
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
}catch(Exception ex) {
|
||||
System.out.println("清空Cookies发生异常!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前登录用户密码
|
||||
*/
|
||||
@ApiOperation(value = "修改密码")
|
||||
@PutMapping("/updatePassword")
|
||||
@ResponseBody
|
||||
public ResponseMessage updatePassword(@NotNull(message = "请输入旧密码") @RequestParam String oldPassword,
|
||||
@NotNull(message = "请输入新密码") @RequestParam String newPassword) {
|
||||
// 前台如果base64传输密文,则需要解码
|
||||
if (isPassEncrypted) {
|
||||
oldPassword = new String(Encodes.decodeBase64(oldPassword), StandardCharsets.UTF_8);
|
||||
newPassword = new String(Encodes.decodeBase64(newPassword), StandardCharsets.UTF_8);
|
||||
}
|
||||
if (!newPassword.matches("^(?![0-9]*$)[a-zA-Z0-9]{6,10}$")) {
|
||||
return Result.error("r0018", "新密码必须6-10位且不能纯数字");
|
||||
}
|
||||
userService.updatePassword(UserUtils.getUserId(), oldPassword, newPassword);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
package com.adc.da.login.security;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* JWT过滤器,针对请求进行拦截过滤
|
||||
*/
|
||||
@Slf4j
|
||||
public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
//10分钟后刷新token
|
||||
private static final int tokenRefreshInterval = 60 * 10;
|
||||
|
||||
/**
|
||||
* 这里我们详细说明下为什么最终返回的都是true,即允许访问
|
||||
*例如我们提供一个地址 GET /article
|
||||
*登入用户和游客看到的内容是不同的
|
||||
*如果在这里返回了false,请求会被直接拦截,用户看不到任何东西
|
||||
*所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入
|
||||
*如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可
|
||||
*但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大
|
||||
*/
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||
if (isLoginAttempt(request, response)) {
|
||||
try {
|
||||
return executeLogin(request, response);
|
||||
} catch (Exception e) {
|
||||
responseError(request, response);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测header里面是否包含Authorization字段
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
String authorization = req.getHeader("Authorization");
|
||||
log.debug("判断用户是否想要登录:{}",authorization);
|
||||
return authorization != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 认证失败后调用的方法
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
|
||||
this.responseError(request,response);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception{
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
String authorization = httpServletRequest.getHeader("Authorization");
|
||||
log.debug("用户开始认证x:{}",authorization);
|
||||
JWTToken token = new JWTToken(authorization);
|
||||
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
||||
getSubject(request, response).login(token);
|
||||
// 如果没有抛出异常则代表登入成功,返回true
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
|
||||
if(token instanceof JWTToken){
|
||||
JWTToken jwtToken= (JWTToken) token;
|
||||
//TODO 此处需要设置token自动续期功能
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
|
||||
httpServletResponse.addHeader("Access-Control-Allow-Headers", "Authorization");
|
||||
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
|
||||
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
||||
httpServletResponse.setStatus(HttpStatus.OK.value());
|
||||
return false;
|
||||
}
|
||||
return super.preHandle(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将非法请求跳转到 /401
|
||||
*/
|
||||
private void responseError(ServletRequest req, ServletResponse resp) {
|
||||
try {
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
|
||||
if(httpServletResponse.isCommitted()){
|
||||
return;
|
||||
}
|
||||
//此处需要返回统一的错误对象 以便应对统一的异常处理
|
||||
JSONObject result=new JSONObject();
|
||||
result.put("respCode","A404");
|
||||
result.put("ok",false);
|
||||
result.put("message","认证失败");
|
||||
result.put("data",null);
|
||||
httpServletResponse.setHeader("Content-Type", "application/json");
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST");
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
|
||||
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
|
||||
// response.setHeader("Content-type", "application/json;charset=UTF-8");
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
httpServletResponse.setContentType("application/json;charset=UTF-8");
|
||||
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||
PrintWriter printWriter = httpServletResponse.getWriter();
|
||||
printWriter.append(result.toString(SerializerFeature.WriteMapNullValue));
|
||||
printWriter.flush();
|
||||
// httpServletResponse.sendRedirect("/401");
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean shouldTokenRefresh(JWTToken jwtToken) {
|
||||
// LocalDateTime issueTime = LocalDateTime.ofInstant(issueAt.toInstant(), ZoneId.systemDefault());
|
||||
// return LocalDateTime.now().minusSeconds(tokenRefreshInterval).isAfter(issueTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package com.adc.da.login.security;
|
||||
|
||||
import com.adc.da.login.util.JWTUtil;
|
||||
import com.adc.da.login.util.UserUtils;
|
||||
import com.adc.da.sys.entity.UserEO;
|
||||
import com.adc.da.sys.service.IUserEOService;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.realm.AuthorizingRealm;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class JWTRealm extends AuthorizingRealm {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JWTRealm.class);
|
||||
|
||||
private IUserEOService userEOService;
|
||||
|
||||
/**
|
||||
* JWT签名密钥
|
||||
*/
|
||||
public static final String SECRET = "AyX3TWpHIkPfE9rqaDiYV416d0nguURLQ8vhNzBlK7MGcOJjmoZ2w5stSeCFxb16";
|
||||
|
||||
@Autowired
|
||||
public void setUserEOService(IUserEOService userEOService) {
|
||||
this.userEOService = userEOService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 必须重写此方法,不然Shiro会报错
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
return token instanceof JWTToken;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 此方法调用hasRole,hasPermission的时候才会进行回调.
|
||||
* <p>
|
||||
* 权限信息.(授权):
|
||||
* 1、如果用户正常退出,缓存自动清空;
|
||||
* 2、如果用户非正常退出,缓存自动清空;
|
||||
* 3、如果我们修改了用户的权限,而用户不退出系统,修改的权限无法立即生效。
|
||||
* (需要手动编程进行实现;放在service进行调用)
|
||||
* 在权限修改后调用realm中的方法,realm已经由spring管理,所以从spring中获取realm实例,调用clearCached方法;
|
||||
* :Authorization 是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
|
||||
*
|
||||
* @param principalCollection
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
|
||||
String username = JWTUtil.getUsername(principalCollection.toString());
|
||||
if (username == null) {
|
||||
return null;
|
||||
}
|
||||
UserEO user = userEOService.getUserByLoginNameNotDeleted(username);
|
||||
if (user != null) {
|
||||
try {
|
||||
return UserUtils.getAuthInfo();
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("AuthorizationInfo NumberFormatException", e);
|
||||
} catch (Exception e) {
|
||||
logger.error("AuthorizationInfo Exception", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证信息(身份验证)
|
||||
* Authentication 是用来验证用户身份
|
||||
*
|
||||
* @param authenticationToken
|
||||
* @return
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
|
||||
String token = (String) authenticationToken.getCredentials();
|
||||
// 解密获得username,用于和数据库进行对比
|
||||
String username = JWTUtil.getUsername(token);
|
||||
if (username == null) {
|
||||
throw new AuthenticationException("token 无效!");
|
||||
}
|
||||
|
||||
UserEO user = userEOService.getUserByLoginNameNotDeleted(username);
|
||||
if (user == null) {
|
||||
throw new AuthenticationException("用户"+username+"不存在") ;
|
||||
}
|
||||
|
||||
if (!JWTUtil.verify(token, username,user.getUsid(),user.getPassword())) {
|
||||
throw new AuthenticationException("账户密码错误!");
|
||||
}
|
||||
return new SimpleAuthenticationInfo(token, token, "jwtRealm");
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权用户信息
|
||||
*/
|
||||
public static class Principal implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String id;
|
||||
|
||||
private String loginName;
|
||||
|
||||
private transient Map<String, Object> cacheMap;
|
||||
|
||||
public Principal(UserEO user) {
|
||||
this.id = user.getUsid() == null ? "" : String.valueOf(user.getUsid());
|
||||
this.loginName = user.getAccount();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLoginName() {
|
||||
return loginName;
|
||||
}
|
||||
|
||||
public Map<String, Object> getCacheMap() {
|
||||
if (cacheMap == null) {
|
||||
cacheMap = new HashMap<>();
|
||||
}
|
||||
return cacheMap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.adc.da.login.security;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
||||
/**
|
||||
* JWT认证token实体对象
|
||||
*/
|
||||
public class JWTToken implements AuthenticationToken {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 613047528940906064L;
|
||||
// 秘钥
|
||||
private String token;
|
||||
|
||||
public JWTToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return getToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return getToken();
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.adc.da.login.security;
|
||||
|
||||
import com.adc.da.login.exception.TokenRuntimeException;
|
||||
import com.adc.da.login.util.JwtUtils;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 创建一个 token 拦截器.
|
||||
* 需要继承 HandlerInterceptorAdapter,并且声明为spring的组件
|
||||
* @author ch
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
* <p>
|
||||
* Created at 2020/7/30 2:19 下午
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class TokenInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
// 注入jwt工具类
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
|
||||
// 重写 前置拦截方法
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
// 1、从请求头中获取token
|
||||
String token = request.getHeader("token");
|
||||
|
||||
// 2、判断 token 是否存在
|
||||
if (token == null ||"".equals(token)) {
|
||||
log.error("未登录");
|
||||
// 这里可以自定义 抛出 token 异常
|
||||
throw new TokenRuntimeException("未登录");
|
||||
}
|
||||
|
||||
// 3、解析token
|
||||
Claims claim = jwtUtils.getClaimsByToken(token);
|
||||
|
||||
if (null == claim) {
|
||||
System.out.println("token 解析错误");
|
||||
// 这里可以自定义 抛出 token 异常
|
||||
throw new TokenRuntimeException("token解析错误");
|
||||
}
|
||||
|
||||
// 4、判断 token 是否过期
|
||||
Date expiration = claim.getExpiration();
|
||||
boolean tokenExpired = jwtUtils.isTokenExpired(expiration);
|
||||
if (tokenExpired) {
|
||||
System.out.println("token已过期,请重新登录");
|
||||
// 这里可以自定义 抛出 token 异常
|
||||
throw new TokenRuntimeException("token已过期");
|
||||
}
|
||||
|
||||
// 5、 从 token 中获取员工信息
|
||||
String subject = claim.getSubject();
|
||||
|
||||
// 6、去数据库中匹配 id 是否存在 (这里直接写死了)
|
||||
if (null == subject ) {
|
||||
System.out.println("员工不存在");
|
||||
// 这里可以自定义 抛出 token 异常
|
||||
throw new TokenRuntimeException("员工不存在");
|
||||
}
|
||||
|
||||
// 7、成功后 设置想设置的属性,比如员工姓名
|
||||
request.setAttribute("userId", subject);
|
||||
request.setAttribute("userName", "张三");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.adc.da.login.security;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private TokenInterceptor interceptor;
|
||||
|
||||
@Bean
|
||||
public TokenInterceptor getSecurityInterceptor() {
|
||||
return new TokenInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写添加拦截器
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
|
||||
|
||||
addInterceptor.excludePathPatterns("/api/loginIdm");
|
||||
/**
|
||||
* TODO 测试流程 开放 login 接口 正式环境 关闭
|
||||
*/
|
||||
addInterceptor.excludePathPatterns("/api/login");
|
||||
addInterceptor.excludePathPatterns("/v2/api-docs");
|
||||
addInterceptor.excludePathPatterns("/webjars/**");
|
||||
addInterceptor.excludePathPatterns("/swagger-resources/**");
|
||||
addInterceptor.excludePathPatterns("/swagger-ui.html");
|
||||
addInterceptor.excludePathPatterns("/doc.html");
|
||||
addInterceptor.excludePathPatterns("/api/lawss/activiti/get_verify_by_instance");
|
||||
addInterceptor.excludePathPatterns("/api/sys/user/getById");
|
||||
addInterceptor.excludePathPatterns("/api/person/userInfo/getByUserInfoCode");
|
||||
addInterceptor.excludePathPatterns("/api/att/attFile/upload");
|
||||
|
||||
// 添加自定义拦截器,并拦截对应 url
|
||||
addInterceptor.addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package com.adc.da.login.util;
|
||||
|
||||
import com.adc.da.util.SpringContextHolder1;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
/**
|
||||
* Cache工具类
|
||||
*/
|
||||
public class CacheUtils {
|
||||
|
||||
private CacheUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
private static CacheManager cacheManager = (CacheManager) SpringContextHolder1.getBean("ehCacheManagerFactoryBean");
|
||||
|
||||
private static final String SYS_CACHE = "sysCache";
|
||||
|
||||
private static final String ERROR_CACHE = "errorCache";
|
||||
|
||||
public static Object get(String key) {
|
||||
return get(SYS_CACHE, key);
|
||||
}
|
||||
|
||||
public static void put(String key, Object value) {
|
||||
put(SYS_CACHE, key, value);
|
||||
}
|
||||
|
||||
public static void remove(String key) {
|
||||
remove(SYS_CACHE, key);
|
||||
}
|
||||
|
||||
//配合main模块下resource/cache/ehcache-local.xml
|
||||
//<cache name="errorCache" maxElementsInMemory="100" timeToIdleSeconds="180" timeToLiveSeconds="300" eternal="false" overflowToDisk="true"/>
|
||||
public static Object getErrorCache(String key) {
|
||||
return get(ERROR_CACHE, key);
|
||||
}
|
||||
|
||||
public static void putErrorCache(String key, Object value) {
|
||||
put(ERROR_CACHE, key, value);
|
||||
}
|
||||
|
||||
public static void removeErrorCache(String key) {
|
||||
remove(ERROR_CACHE, key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Object get(String cacheName, String key) {
|
||||
Element element = getCache(cacheName).get(key);
|
||||
return element == null ? null : element.getObjectValue();
|
||||
}
|
||||
|
||||
public static void put(String cacheName, String key, Object value) {
|
||||
Element element = new Element(key, value);
|
||||
getCache(cacheName).put(element);
|
||||
}
|
||||
|
||||
public static void remove(String cacheName, String key) {
|
||||
getCache(cacheName).remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个Cache,没有则创建一个。
|
||||
* @param cacheName
|
||||
* @return
|
||||
*/
|
||||
private static Cache getCache(String cacheName) {
|
||||
Cache cache = cacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
cacheManager.addCache(cacheName);
|
||||
cache = cacheManager.getCache(cacheName);
|
||||
cache.getCacheConfiguration().setEternal(true);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public static CacheManager getCacheManager() {
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.adc.da.login.util;
|
||||
|
||||
import com.adc.da.ocr.util.OkHttpUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.json.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class IDMUtil {
|
||||
|
||||
@Autowired
|
||||
private OkHttpUtil okHttpUtil;
|
||||
|
||||
private final String app_key = "app_slrs";
|
||||
private final String app_secret = "wj5iDTqyguQCxnsoo5VU21BoRSZqevhI";
|
||||
private final String access_url = "http://testsso1.foton.com.cn/oauth2.0/accessTokenByJson";
|
||||
private final String profile_ur = "http://testsso1.foton.com.cn/oauth2.0/profileByJson";
|
||||
private final String redirect_url = "http://127.0.0.1:9090";
|
||||
|
||||
public String idmLogin(String code){
|
||||
try{
|
||||
String access_token = "";
|
||||
Map<String,String> param = new HashMap<>();
|
||||
param.put("client_id",app_key);
|
||||
param.put("client_secret",app_secret);
|
||||
param.put("grant_type","authorization_code");
|
||||
param.put("redirect_uri",redirect_url);
|
||||
param.put("code",code);
|
||||
String access_token_str = okHttpUtil.post(access_url,param,new HashMap<>());
|
||||
JSONObject atJsonObj = JSONObject.fromObject(access_token_str);
|
||||
System.out.println("AccessTokenJSON:" + atJsonObj);
|
||||
if (atJsonObj.has("status")) {
|
||||
System.out.println("AccessTokenStatus:" + atJsonObj.get("status"));
|
||||
if ("true".equals(atJsonObj.get("status").toString())) {
|
||||
if (atJsonObj.has("access_token")) {
|
||||
access_token = atJsonObj.get("access_token").toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(StringUtils.isBlank(access_token)){
|
||||
return "";
|
||||
}
|
||||
Map<String,String> param_p = new HashMap<>();
|
||||
param_p.put("access_token",access_token.substring(13));
|
||||
String principal_json = okHttpUtil.post(profile_ur,param_p,new HashMap<>());
|
||||
JSONObject pfjsonObj = JSONObject.fromObject(principal_json);
|
||||
if (pfjsonObj.has("status")) {
|
||||
System.out.println("ProfileStatus:" + pfjsonObj.get("status"));
|
||||
if ("true".equals(pfjsonObj.get("status").toString())) {
|
||||
if (pfjsonObj.has("id")) {
|
||||
System.out.println("ID:" + pfjsonObj.get("id"));
|
||||
}
|
||||
if (pfjsonObj.has("attributes")) {
|
||||
JSONObject attrObj = JSONObject.fromObject(pfjsonObj.get("attributes"));
|
||||
if (attrObj.has("userid")) {
|
||||
return attrObj.get("userid").toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
log.error("单点登录获取用户信息失败");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.adc.da.login.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
|
||||
public class JWTUtil {
|
||||
|
||||
// 设置过期时间,默认为2小时
|
||||
private static long EXPIRE_TIME = 120;
|
||||
|
||||
@Value("${EXPIRE_TIME}")
|
||||
public void setEnv(long expireTime) {
|
||||
setExpireTime(expireTime);
|
||||
}
|
||||
|
||||
public static synchronized void setExpireTime(long expireTime) {
|
||||
EXPIRE_TIME = expireTime;
|
||||
}
|
||||
|
||||
public static boolean verify(String token, String username,String userId, String secret) {
|
||||
try {
|
||||
Algorithm algorithm = Algorithm.HMAC512(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withClaim("username", username).withClaim("userid", userId)
|
||||
.build();
|
||||
verifier.verify(token);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Title: getUsername
|
||||
* @Description: 获取token中的信息无需secret解密也能获得
|
||||
* @Author 刘仁
|
||||
* @DateTime 2019年4月1日 下午4:42:39
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static String getUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUserId(String token){
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("userid").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String sign(String username,String userId, String secret) {
|
||||
Date date = Date
|
||||
.from(LocalDateTime.now().plusMinutes(EXPIRE_TIME).atZone(ZoneId.systemDefault()).toInstant());
|
||||
Algorithm algorithm = Algorithm.HMAC512(secret);
|
||||
String sign = JWT.create()
|
||||
.withClaim("username", username).withClaim("userid", userId)
|
||||
.withExpiresAt(date)
|
||||
.sign(algorithm);
|
||||
|
||||
// 附带username信息
|
||||
return sign;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.adc.da.login.util;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* token 工具类
|
||||
*
|
||||
* @author ch
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
* <p>
|
||||
* Created at 2020/7/30 2:23 下午
|
||||
*/
|
||||
@Component
|
||||
public class JwtUtils {
|
||||
|
||||
// 过期时间
|
||||
private static long expire = 6048000;
|
||||
// 秘钥
|
||||
private static String secret = "HSyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9";
|
||||
|
||||
/**
|
||||
* 创建一个token
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public String generateToken(String userId) {
|
||||
Date now = new Date();
|
||||
Date expireDate = new Date(now.getTime() + expire);
|
||||
return Jwts.builder().setHeaderParam("type", "JWT").setSubject(userId).setIssuedAt(now)
|
||||
.setExpiration(expireDate).signWith(
|
||||
SignatureAlgorithm.HS512, secret).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析token
|
||||
*/
|
||||
public Claims getClaimsByToken(String token) {
|
||||
Claims claims;
|
||||
try {
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(secret) // 设置标识名
|
||||
.parseClaimsJws(token) //解析token
|
||||
.getBody();
|
||||
} catch (ExpiredJwtException e) {
|
||||
claims = e.getClaims();
|
||||
}
|
||||
return claims;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 token 是否过期
|
||||
*/
|
||||
public boolean isTokenExpired(Date expiration){
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.adc.da.login.util;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.adc.da.login.security.JWTRealm;
|
||||
import com.adc.da.login.security.JWTRealm.Principal;
|
||||
import com.adc.da.sys.entity.MenuEO;
|
||||
import com.adc.da.sys.entity.RoleEO;
|
||||
import com.adc.da.sys.entity.UserEO;
|
||||
@@ -12,13 +10,11 @@ import com.adc.da.sys.service.IUserEOService;
|
||||
import com.adc.da.util.SpringContextHolder1;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.UnavailableSecurityManagerException;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.session.InvalidSessionException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -218,15 +214,6 @@ public class UserUtils {
|
||||
|
||||
public static Map<String, Object> getCacheMap() {
|
||||
Map<String, Object> map = Maps.newHashMap();
|
||||
try {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
JWTRealm.Principal principal = (JWTRealm.Principal) subject.getPrincipal();
|
||||
return principal != null ? principal.getCacheMap() : map;
|
||||
} catch (UnavailableSecurityManagerException e) {
|
||||
logger.error(e.getMessage(),e);
|
||||
} catch (InvalidSessionException e) {
|
||||
logger.error(e.getMessage(),e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.adc.da.exception.AdcDaBaseException;
|
||||
import com.adc.da.http.ResponseMessage;
|
||||
import com.adc.da.http.ResponseMessageCodeEnum;
|
||||
import com.adc.da.http.Result;
|
||||
import com.adc.da.login.exception.TokenRuntimeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -32,6 +33,11 @@ public class AdcDaBaseExceptionAdvice {
|
||||
public ResponseMessage handlerAdcDaBaseException(Exception exception) {
|
||||
log.error(exception.getMessage(), exception);
|
||||
// TODO 在数据库中记录程序异常,这个地方的异常是未处理的异常,需要管理员查看并进行处理以防重复出现
|
||||
if(exception.getStackTrace() != null){
|
||||
if(exception.getMessage().equals("token已过期")){
|
||||
return Result.error(ResponseMessageCodeEnum.ERROR_TOKEN.getCode(), "token已过期,请重新登录");
|
||||
}
|
||||
}
|
||||
return Result.error(ResponseMessageCodeEnum.ERROR.getCode(), "程序异常,请重试。如果重复出现请联系管理员处理!");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.adc.da.main.advice;
|
||||
|
||||
import com.adc.da.http.ResponseMessage;
|
||||
import com.adc.da.http.Result;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authz.UnauthenticatedException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
@Order(value=2)
|
||||
public class ShiroExceptionAdvice {
|
||||
|
||||
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
@ExceptionHandler({AuthenticationException.class, UnknownAccountException.class,
|
||||
UnauthenticatedException.class, IncorrectCredentialsException.class})
|
||||
@ResponseBody
|
||||
public ResponseMessage unauthorized(Exception exception) {
|
||||
log.warn(exception.getMessage(), exception);
|
||||
log.info("catch UnknownAccountException");
|
||||
return Result.error("A404", "无权访问");
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
@ExceptionHandler(UnauthorizedException.class)
|
||||
@ResponseBody
|
||||
public ResponseMessage unauthorized1(UnauthorizedException exception) {
|
||||
log.warn(exception.getMessage(), exception);
|
||||
return Result.error("A404","无权访问");
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.adc.da.main.config;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* shiro 自定义URL规则设置
|
||||
*/
|
||||
public class DefinitionUrlConfig {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 匿名用户,无需登录
|
||||
*/
|
||||
private static final String ANON = "anon";
|
||||
|
||||
|
||||
|
||||
// 拦截器
|
||||
//rest:比如/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
|
||||
//port:比如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
|
||||
//perms:比如/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,比如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
|
||||
//roles:比如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,比如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。//要实现or的效果看http://zgzty.blog.163.com/blog/static/83831226201302983358670/
|
||||
//anon:比如/admins/**=anon 没有参数,表示可以匿名使用。
|
||||
//authc:比如/admins/user/**=authc表示需要认证才能使用,没有参数
|
||||
//authcBasic:比如/admins/user/**=authcBasic没有参数表示httpBasic认证
|
||||
//ssl:比如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
|
||||
//user:比如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
|
||||
public static Map<String,String> definitionUrlOptions(){
|
||||
Map<String, String> filterRuleMap = new LinkedHashMap<>();
|
||||
//TODO 此处设置URL过滤规则 默认是全部请求进行拦截,此处设置为不拦截的URL地址
|
||||
filterRuleMap.put("/api/login",ANON);//登录接口
|
||||
// swagger接口文档
|
||||
filterRuleMap.put("/v2/api-docs", "anon");
|
||||
filterRuleMap.put("/webjars/**", "anon");
|
||||
filterRuleMap.put("/swagger-resources/**", "anon");
|
||||
filterRuleMap.put("/swagger-ui.html", "anon");
|
||||
filterRuleMap.put("/doc.html", "anon");
|
||||
return filterRuleMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.adc.da.main.config;
|
||||
|
||||
import com.adc.da.login.security.JWTFilter;
|
||||
import com.adc.da.login.security.JWTRealm;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
@Order(value=1)
|
||||
public class ShiroConfig {
|
||||
|
||||
private static final String JWT_FILTER_NAME = "jwt";
|
||||
|
||||
private static final String URL_SUFFIX="/api";
|
||||
|
||||
/**
|
||||
* 自定义realm,实现登录授权流程
|
||||
* @return
|
||||
*/
|
||||
@Bean(name="jwtRealm")
|
||||
public JWTRealm jwtRealm() {
|
||||
return new JWTRealm();
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置securityManager 管理subject(默认),并把自定义realm交由manager
|
||||
*/
|
||||
@Bean
|
||||
public DefaultSecurityManager securityManager() {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
// 设置realm.
|
||||
securityManager.setRealm(jwtRealm());
|
||||
//注入缓存管理器
|
||||
securityManager.setCacheManager(ehCacheManager());
|
||||
/*
|
||||
* 关闭shiro自带的session,详情见文档
|
||||
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
|
||||
*/
|
||||
DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO();
|
||||
DefaultSessionStorageEvaluator storageEvaluator = new DefaultSessionStorageEvaluator();
|
||||
storageEvaluator.setSessionStorageEnabled(false);
|
||||
defaultSubjectDAO.setSessionStorageEvaluator(storageEvaluator);
|
||||
securityManager.setSubjectDAO(defaultSubjectDAO);
|
||||
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截链
|
||||
*/
|
||||
@Bean
|
||||
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||
shiroFilterFactoryBean.setFilters(filterMap());
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(definitionMap());
|
||||
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义拦截器,处理所有请求
|
||||
*/
|
||||
private Map<String, Filter> filterMap() {
|
||||
Map<String, Filter> filterMap = new HashMap<>();
|
||||
filterMap.put(JWT_FILTER_NAME, new JWTFilter());
|
||||
return filterMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* url拦截规则
|
||||
*/
|
||||
private Map<String, String> definitionMap() {
|
||||
// 拦截器
|
||||
//rest:比如/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
|
||||
//port:比如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
|
||||
//perms:比如/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,比如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
|
||||
//roles:比如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,比如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。//要实现or的效果看http://zgzty.blog.163.com/blog/static/83831226201302983358670/
|
||||
//anon:比如/admins/**=anon 没有参数,表示可以匿名使用。
|
||||
//authc:比如/admins/user/**=authc表示需要认证才能使用,没有参数
|
||||
//authcBasic:比如/admins/user/**=authcBasic没有参数表示httpBasic认证
|
||||
//ssl:比如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
|
||||
//user:比如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
|
||||
Map<String, String> definitionMap = DefinitionUrlConfig.definitionUrlOptions();
|
||||
// definitionMap.put(URL_SUFFIX+"/**", JWT_FILTER_NAME);
|
||||
return definitionMap;
|
||||
}
|
||||
|
||||
/* *//**
|
||||
* 开启注解
|
||||
*//*
|
||||
@Bean
|
||||
@DependsOn("lifecycleBeanPostProcessor")
|
||||
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
||||
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
// 强制使用cglib代理,防止和aop冲突
|
||||
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
|
||||
return defaultAdvisorAutoProxyCreator;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 开启shiro aop注解支持. 使用代理方式; 所以需要开启代码支持;
|
||||
*
|
||||
* @param securityManager 安全管理器
|
||||
* @return 授权Advisor
|
||||
*/
|
||||
@Bean("authorizationAttributeSourceAdvisor")
|
||||
public AuthorizationAttributeSourceAdvisor advisor(DefaultSecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* shiro缓存管理器;
|
||||
* 需要注入对应的其它的实体类中:
|
||||
* 1、安全管理器:securityManager
|
||||
* 可见securityManager是整个shiro的核心;
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public EhCacheManager ehCacheManager() {
|
||||
EhCacheManager cacheManager = new EhCacheManager();
|
||||
cacheManager.setCacheManagerConfigFile("classpath:cache/ehcache.xml");
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.adc.da.main.config;
|
||||
|
||||
import com.adc.da.login.security.JWTRealm;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
|
||||
//@Configuration
|
||||
public class ShiroConfiguration {
|
||||
|
||||
@Bean(name = "ehCacheManagerFactoryBean")
|
||||
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
|
||||
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
|
||||
ClassPathResource classPathResource = new ClassPathResource("cache/ehcache-local.xml");
|
||||
ehCacheManagerFactoryBean.setConfigLocation(classPathResource);
|
||||
return ehCacheManagerFactoryBean;
|
||||
}
|
||||
|
||||
@Bean(name = "shiroCacheManager")
|
||||
@DependsOn({ "ehCacheManagerFactoryBean" })
|
||||
public EhCacheManager shiroCacheManager() {
|
||||
EhCacheManager ehCacheManager = new EhCacheManager();
|
||||
ehCacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
|
||||
return ehCacheManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn({ "lifecycleBeanPostProcessor" })
|
||||
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
||||
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
proxyCreator.setProxyTargetClass(true);
|
||||
return proxyCreator;
|
||||
}
|
||||
|
||||
@Bean(name = "lifecycleBeanPostProcessor")
|
||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean(name = "securityManager")
|
||||
public SecurityManager securityManager() {
|
||||
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
|
||||
defaultWebSecurityManager.setRealm(jwtRealm());
|
||||
|
||||
// 关闭shiro自带的session
|
||||
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
|
||||
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
|
||||
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
|
||||
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
|
||||
defaultWebSecurityManager.setSubjectDAO(subjectDAO);
|
||||
|
||||
// 自定义缓存管理器
|
||||
defaultWebSecurityManager.setCacheManager(shiroCacheManager());
|
||||
SecurityUtils.setSecurityManager(defaultWebSecurityManager);
|
||||
return defaultWebSecurityManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HashedCredentialsMatcher hashedCredentialsMatcher() {
|
||||
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
|
||||
hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;
|
||||
hashedCredentialsMatcher.setHashIterations(2);// 散列的次数,比如散列两次,相当于
|
||||
// md5(md5(""));
|
||||
return hashedCredentialsMatcher;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JWTRealm jwtRealm() {
|
||||
JWTRealm jwtRealm = new JWTRealm();
|
||||
return jwtRealm;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager());
|
||||
return advisor;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
#=============================================
|
||||
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
|
||||
spring.datasource.url = jdbc:mysql://39.100.23.127:3306/foton_slrs_test2?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
|
||||
#spring.datasource.url = jdbc:mysql://10.96.10.171/foton_slrs_test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
|
||||
#spring.datasource.url = jdbc:mysql://10.96.10.54/foton_slrs_test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
|
||||
spring.datasource.username = root
|
||||
spring.datasource.password = root
|
||||
|
||||
@@ -49,6 +49,10 @@ spring.rabbitmq.port=5672
|
||||
spring.rabbitmq.username=guest
|
||||
spring.rabbitmq.password=guest
|
||||
spring.rabbitmq.listener.simple.acknowledge-mode= manual
|
||||
# 生产者 默认关闭 发版 需改为 true
|
||||
spring.rabbitmq.listener.direct.auto-startup=false
|
||||
# 消费者 默认关闭 发版 需改为 true
|
||||
spring.rabbitmq.listener.simple.auto-startup=false
|
||||
#消费失败消息干掉
|
||||
spring.rabbitmq.listener.simple.default-requeue-rejected= true
|
||||
#5秒
|
||||
@@ -70,7 +74,7 @@ OCR.userId =dayuzhou1234
|
||||
OCR.authCode =123456
|
||||
OCR.publicKey =EC4KKA6ZDTCPAOCRBC5M
|
||||
# OCR文件存储路径
|
||||
OCR.ocrPath=/opt/foton-slrs/front/dist/file/
|
||||
OCR.ocrPath=/opt/foton-slrs/front/dist/file/a
|
||||
# OCR文件请求下载或在线预览时URL
|
||||
OCR.ocrDownPath=http://62.234.136.153:8038/file/
|
||||
OCR.times=20
|
||||
|
||||
+13
-13
@@ -48,66 +48,66 @@ public class LawsDto {
|
||||
private String NYLX;
|
||||
|
||||
@ApiModelProperty(value = "标准年份")
|
||||
@ExcelProperty(value = "标准年份", index = 5)
|
||||
// @ExcelProperty(value = "标准年份", index = 5)
|
||||
private String standYear;
|
||||
|
||||
@ApiModelProperty(value = "标准类别")
|
||||
@ExcelProperty(value = "标准类别", index = 6)
|
||||
// @ExcelProperty(value = "标准类别", index = 6)
|
||||
private String standSortShow;
|
||||
|
||||
@ApiModelProperty(value = "标准发表日期")
|
||||
@ExcelProperty(value = "标准发表日期", index = 7)
|
||||
// @ExcelProperty(value = "标准发表日期", index = 7)
|
||||
private String issueTime;
|
||||
|
||||
@ColumnWidth(16)
|
||||
@ExcelProperty(value = "标准实施日期", index = 8)
|
||||
@ExcelProperty(value = "标准实施日期", index = 5)
|
||||
@ApiModelProperty(value = "标准实施日期")
|
||||
@DateTimeFormat("yyyy年MM月dd日")
|
||||
private String SSRQ;
|
||||
|
||||
@ColumnWidth(16)
|
||||
@ExcelProperty(value = "新车型实施日期", index = 9)
|
||||
@ExcelProperty(value = "新车型实施日期", index = 6)
|
||||
@ApiModelProperty(value = "新车型实施日期")
|
||||
@DateTimeFormat("yyyy年MM月dd日")
|
||||
private String XCXSSRQGJ;
|
||||
|
||||
@ColumnWidth(16)
|
||||
@ExcelProperty(value = "在产车实施日期", index = 10)
|
||||
@ExcelProperty(value = "在产车实施日期", index = 7)
|
||||
@ApiModelProperty(value = "在产车实施日期")
|
||||
@DateTimeFormat("yyyy年MM月dd日")
|
||||
private String ZCCSSRQGJ;
|
||||
|
||||
@ExcelProperty(value = "责任部门", index = 11)
|
||||
@ExcelProperty(value = "责任部门", index = 8)
|
||||
@ApiModelProperty(value = "责任部门")
|
||||
private String ZRBM;
|
||||
|
||||
@ColumnWidth(14)
|
||||
@ExcelProperty(value = "适用产品线", index = 12)
|
||||
@ExcelProperty(value = "适用产品线", index = 9)
|
||||
@ApiModelProperty(value = "适用产品线")
|
||||
private String SYCPX;
|
||||
|
||||
@ColumnWidth(20)
|
||||
@ExcelProperty(value = "乘用车VPPS编码", index = 13)
|
||||
@ExcelProperty(value = "乘用车VPPS编码", index = 10)
|
||||
@ApiModelProperty(value = "乘用车VPPS编码")
|
||||
private String CYCVPPSBM;
|
||||
|
||||
@ColumnWidth(20)
|
||||
@ExcelProperty(value = "乘用车vpps中文名称", index = 14)
|
||||
@ExcelProperty(value = "乘用车vpps中文名称", index = 11)
|
||||
@ApiModelProperty(value = "乘用车vpps中文名称")
|
||||
private String CYCVPPSCN;
|
||||
|
||||
@ColumnWidth(20)
|
||||
@ExcelProperty(value = "卡车VPPS编码", index = 15)
|
||||
@ExcelProperty(value = "卡车VPPS编码", index = 12)
|
||||
@ApiModelProperty(value = "卡车VPPS编码")
|
||||
private String KCCVPPSBM;
|
||||
|
||||
@ColumnWidth(20)
|
||||
@ExcelProperty(value = "卡车vpps中文名称", index = 16)
|
||||
@ExcelProperty(value = "卡车vpps中文名称", index = 13)
|
||||
@ApiModelProperty(value = "卡车vpps中文名称")
|
||||
private String KCCVPPSCN;
|
||||
|
||||
@ApiModelProperty(value = "责任工程师")
|
||||
@ExcelProperty(value = "责任工程师", index = 17)
|
||||
// @ExcelProperty(value = "责任工程师", index = 17)
|
||||
private String responsibleEngineer;
|
||||
|
||||
@ApiModelProperty(value = "1")
|
||||
|
||||
+1
@@ -104,6 +104,7 @@ public class SarPublicIdeaAllController extends BaseController<SarPublicIdeaAll>
|
||||
if (!StringUtils.isEmpty(cid)){
|
||||
QueryWrapper<SarPublicIdeaAll> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq(SarPublicIdeaAll.CID,cid);
|
||||
wrapper.orderByAsc("part_code");
|
||||
data=sarPublicIdeaAllDao.selectList(wrapper);
|
||||
}
|
||||
List<GetExcelDto> standExcel=new ArrayList<>();
|
||||
|
||||
+1
-2
@@ -8,7 +8,6 @@ import com.adc.da.http.Result;
|
||||
import com.adc.da.slrs.sarLawsAttrDetailedList.entity.LawsDto;
|
||||
import com.adc.da.slrs.sarStandItems.entity.*;
|
||||
import com.adc.da.slrs.sarStandItems.service.impl.SarStandItemsServiceImpl;
|
||||
import com.adc.da.slrs.sarStandardsInfo.entity.SarStandardsInfo;
|
||||
import com.adc.da.util.UUIDUtils;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -56,7 +55,7 @@ public class SarStandItemsController extends BaseController<SarStandItems> {
|
||||
|
||||
@ApiOperation(value = "分解单查询")
|
||||
@GetMapping("/querySarItemAndInterpretation")
|
||||
public ResponseMessage<PageInfo<SarStandItems>> querySarItemAndInterpretation(FindSarItemsPageReqDTO page){
|
||||
public ResponseMessage querySarItemAndInterpretation(FindSarItemsPageReqDTO page){
|
||||
List<SarStandItems> rows = ServiceImpl.querySarItemAndInterpretation(page);
|
||||
|
||||
PageInfo<SarStandItems> pageInfo = getPageInfo(page.getPager(), rows);
|
||||
|
||||
+3
@@ -13,6 +13,9 @@ import java.util.Date;
|
||||
public class FindSarItemsPageReqDTO extends BasePage {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Integer page = 1;
|
||||
private Integer pageSize = 20;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "标准id")
|
||||
private String standId;
|
||||
|
||||
+6
-1
@@ -1,5 +1,6 @@
|
||||
package com.adc.da.slrs.sarStandItems.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -22,9 +23,13 @@ public class SarStandItemsDto {
|
||||
@ApiModelProperty(value = "条目编号")
|
||||
private String itemsNum;
|
||||
|
||||
@ApiModelProperty(value = "内容")
|
||||
@ApiModelProperty(value = "名称")
|
||||
private String itemsName;
|
||||
|
||||
@ApiModelProperty(value = "内容")
|
||||
@TableField("TERMS_CONDITIONS")
|
||||
private String termsConditions;
|
||||
|
||||
@ApiModelProperty(value = "责任部门")
|
||||
private String responsibleUnit;
|
||||
|
||||
|
||||
+29
-24
@@ -36,7 +36,12 @@ public class SarStandUnqualified extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty("标准ID")
|
||||
@ExcelProperty("标准号")
|
||||
@ApiModelProperty(value = "标准编号")
|
||||
@TableField("STAND_SERIAL_NUMBER")
|
||||
private String standSerialNumber;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "标准ID")
|
||||
@TableField("STAND_ID")
|
||||
private String standId;
|
||||
@@ -69,27 +74,27 @@ public class SarStandUnqualified extends BaseEntity {
|
||||
@TableField("ITEMS_NAME")
|
||||
private String itemsName;
|
||||
|
||||
@ExcelProperty(value = "产品类型",converter = ProductTypeConverter.class)
|
||||
@ApiModelProperty(value = "产品类型(research为在研产品,product为在产产品)")
|
||||
@TableField("PRODUCT_TYPE")
|
||||
private String productType;
|
||||
|
||||
@ExcelProperty("产品线")
|
||||
@ApiModelProperty(value = "产品线")
|
||||
@TableField("PRODUCT_LINE")
|
||||
private String productLine;
|
||||
|
||||
@ExcelProperty("责任部门")
|
||||
@ApiModelProperty(value = "责任部门")
|
||||
@TableField("RESPONSIBLE_UNIT")
|
||||
private String responsibleUnit;
|
||||
|
||||
@ExcelProperty("项目名称")
|
||||
@ApiModelProperty(value = "项目名称")
|
||||
@TableField("PRODUCT_NAME")
|
||||
private String productName;
|
||||
|
||||
@ExcelProperty("创建部门")
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "创建部门")
|
||||
@TableField("CREATE_DEPT_ID")
|
||||
private String createDeptId;
|
||||
|
||||
@ExcelProperty("创建人")
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "创建人")
|
||||
@TableField("CREATE_BY_ID")
|
||||
private String createById;
|
||||
@@ -113,17 +118,16 @@ public class SarStandUnqualified extends BaseEntity {
|
||||
@TableField("ACTUAL_CLOSE_TIME")
|
||||
private Date actualCloseTime;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "计划关闭时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField("PLAN_CLOSE_TIME")
|
||||
private Date planCloseTime;
|
||||
|
||||
@ExcelProperty("不合规项目")
|
||||
@ApiModelProperty(value = "未符合原因")
|
||||
@TableField("REASON")
|
||||
private String reason;
|
||||
|
||||
@ExcelProperty("责任部门")
|
||||
@ApiModelProperty(value = "责任部门")
|
||||
@TableField("RESPONSIBLE_UNIT")
|
||||
private String responsibleUnit;
|
||||
|
||||
@ExcelProperty("质量工程师")
|
||||
@ApiModelProperty(value = "质量工程师")
|
||||
@TableField("QA_ENGINEER")
|
||||
@@ -139,33 +143,34 @@ public class SarStandUnqualified extends BaseEntity {
|
||||
@TableField("DUTY_ENGINEER")
|
||||
private String dutyEngineer;
|
||||
|
||||
@ExcelProperty("标准编号")
|
||||
@ApiModelProperty(value = "标准编号")
|
||||
@TableField("STAND_SERIAL_NUMBER")
|
||||
private String standSerialNumber;
|
||||
|
||||
@ExcelProperty(value = "产品类型",converter = ProductTypeConverter.class)
|
||||
@ApiModelProperty(value = "产品类型(research为在研产品,product为在产产品)")
|
||||
@TableField("PRODUCT_TYPE")
|
||||
private String productType;
|
||||
@ExcelProperty("计划关闭时间")
|
||||
@ApiModelProperty(value = "计划关闭时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField("PLAN_CLOSE_TIME")
|
||||
private Date planCloseTime;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "主键")
|
||||
@TableId(type = IdType.UUID)
|
||||
private String id;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "质量工程师")
|
||||
@TableField(exist=false)
|
||||
private String qaEngineerName;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "认证工程师")
|
||||
@TableField(exist=false)
|
||||
private String authEngineerName;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "责任工程师")
|
||||
@TableField(exist=false)
|
||||
private String dutyEngineerName;
|
||||
|
||||
@ExcelIgnore
|
||||
@ApiModelProperty(value = "国内OR海外")
|
||||
@TableField(exist=false)
|
||||
private String standType;
|
||||
|
||||
+4
@@ -6,6 +6,7 @@ import com.adc.da.base.web.BaseController;
|
||||
import com.adc.da.http.ResponseMessage;
|
||||
import com.adc.da.http.Result;
|
||||
import com.adc.da.slrs.sarSarAccessInfo.entity.SarSarAccessInfo;
|
||||
import com.adc.da.slrs.sarStandItems.entity.SarStandItemsDto;
|
||||
import com.adc.da.slrs.sarStandardComplianceAssessResult.entity.*;
|
||||
import com.adc.da.slrs.sarStandardComplianceAssessResult.service.ISarInterpretationForeignStandardService;
|
||||
import com.adc.da.slrs.sarStandardComplianceAssessResult.service.ISarInterpretationNationalStandardService;
|
||||
@@ -165,6 +166,9 @@ public class SarStandardComplianceAssessResultController {
|
||||
if (eo.getType() != null) queryWrapper.eq("type", eo.getType());
|
||||
if (eo.getProductName() != null) queryWrapper.like("product_name", eo.getProductName());
|
||||
if (eo.getProductId() != null) queryWrapper.like("product_id", eo.getProductId());
|
||||
queryWrapper.orderByAsc("product_name");
|
||||
queryWrapper.orderByAsc("standard_item");
|
||||
|
||||
// if (eo.getInterpretationTime() != null) queryWrapper.eq("INTERPRETATION_TIME", eo.getInterpretationTime());
|
||||
|
||||
IPage<SarStandardComplianceProductAssess> page = iSarStandardComplianceProductAssessService.page(iPage, queryWrapper);
|
||||
|
||||
+4
-1
@@ -218,7 +218,10 @@ public class SarStandardsInfoController extends BaseController<SarStandardsInfo>
|
||||
int result = sarStandardsInfoEOService.deleteSarStandards(ids);
|
||||
if (result > 0) {
|
||||
return Result.success("0", "删除成功", result);
|
||||
} else {
|
||||
}else if(result == -1) {
|
||||
return Result.success("-1","所选的标准下挂有标准,无法删除");
|
||||
}
|
||||
else {
|
||||
return Result.error("删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -15,6 +15,8 @@ import com.adc.da.search.entity.StandLawsEO;
|
||||
import com.adc.da.search.service.StandLawsSearchService;
|
||||
import com.adc.da.slrs.otConvertMq.dao.OtConvertMqDao;
|
||||
import com.adc.da.slrs.otConvertMq.entity.OtConvertMq;
|
||||
import com.adc.da.slrs.sarLawsAttrDetailedList.entity.SarLawsAttrDetailedList;
|
||||
import com.adc.da.slrs.sarLawsAttrDetailedList.service.impl.SarLawsAttrDetailedListServiceImpl;
|
||||
import com.adc.da.slrs.sarLawsInfo.entity.SarLawsInfo;
|
||||
import com.adc.da.slrs.sarLawsInfo.page.SarLawsInfoEOPage;
|
||||
import com.adc.da.slrs.sarLawsInfo.page.SarLawsItemsEOPage;
|
||||
@@ -1285,13 +1287,32 @@ public class SarStandardsInfoServiceImpl extends ServiceImpl<SarStandardsInfoDao
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
SarLawsAttrDetailedListServiceImpl detailedListService;
|
||||
|
||||
public int deleteSarStandards(String ids) {
|
||||
QueryWrapper<SarLawsAttrDetailedList> detailedListQueryWrapper = new QueryWrapper<>();
|
||||
|
||||
|
||||
String[] idArr = ids.split(",");
|
||||
SarStandardsInfo sarStandardsInfoEO = new SarStandardsInfo();
|
||||
sarStandardsInfoEO.setValidFlag("1");
|
||||
sarStandardsInfoEO.setModifyTime(new Date());
|
||||
int countResult = 0;
|
||||
//如果清单下挂着标准A,在标准库里删除标准A的话,加个验证 不让删这个标准
|
||||
for (String id : idArr){
|
||||
detailedListQueryWrapper.eq("stand_id",id);
|
||||
|
||||
int count = detailedListService.count(detailedListQueryWrapper);
|
||||
if (count>0){
|
||||
countResult = -1;
|
||||
return countResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (String id : idArr) {
|
||||
|
||||
countResult++;
|
||||
//查询删除的标准信息(为删除代替关系)
|
||||
SarStandardsInfo getDelStandInfoList = dao.selectById(id);
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class TsUserServiceImpl extends ServiceImpl<TsUserDao, TsUser> implements
|
||||
Page<TsUser> tsUserPage = new Page<>();
|
||||
System.out.println(tsUser.getCurrent());
|
||||
System.out.println(tsUser.getSize());
|
||||
List<TsUser> tsUserList = tsUserDao.getUserAndPositionPage((tsUser.getCurrent()-1)*tsUser.getSize(),1*tsUser.getSize(),tsUser);
|
||||
List<TsUser> tsUserList = tsUserDao.getUserAndPositionPage((tsUser.getCurrent()-1)*tsUser.getSize(),tsUser.getSize(),tsUser);
|
||||
Integer total = tsUserDao.getUserAndPositionCount(tsUser);
|
||||
tsUserPage.setRecords(tsUserList);
|
||||
tsUserPage.setCurrent(tsUser.getCurrent());
|
||||
|
||||
+3
@@ -413,6 +413,9 @@
|
||||
<!-- 标准名称 -->
|
||||
<if test="standName != null and standName != ''">
|
||||
and stand_name like concat(concat('%',#{standName}),'%')
|
||||
or STAND_NUMBER like concat(concat('%',#{standName}),'%')
|
||||
or STAND_YEAR like concat(concat('%',#{standName}),'%')
|
||||
or STAND_SORT like concat(concat('%',#{standName}),'%')
|
||||
</if>
|
||||
<if test="standEnName != null and standEnName != ''">
|
||||
and stand_en_name like concat(concat('%',#{standEnName}),'%')
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
left join ts_position p
|
||||
on up.position_id=p.id
|
||||
where u.institution_id=#{TsUser.institutionId}
|
||||
<if test="TsUser.uname != null and TsUser.uname != '' ">
|
||||
and u.uname like concat('%',#{TsUser.uname},'%')
|
||||
</if>
|
||||
<if test="TsUser.email != null and TsUser.email != '' ">
|
||||
and u.email like concat('%',#{TsUser.email},'%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserIdsByPositionIds" resultType="String">
|
||||
|
||||
@@ -53,6 +53,7 @@ public class UserEO extends BaseEntity implements Serializable {
|
||||
private String orgType;
|
||||
|
||||
private String ssoId;
|
||||
private String token;
|
||||
/**
|
||||
* java字段名转换为原始数据库列名。<b>如果不存在则返回null</b><br>
|
||||
* <p>字段列表:</p>
|
||||
@@ -382,4 +383,12 @@ public class UserEO extends BaseEntity implements Serializable {
|
||||
public void setOrgType(String orgType) {
|
||||
this.orgType = orgType;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user