diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/SysRuntimeExceptionHandler.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/SysRuntimeExceptionHandler.java new file mode 100644 index 00000000..93006848 --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/SysRuntimeExceptionHandler.java @@ -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 + *

+ * 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(); + } +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/TokenRuntimeException.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/TokenRuntimeException.java new file mode 100644 index 00000000..089bf175 --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/exception/TokenRuntimeException.java @@ -0,0 +1,24 @@ +package com.adc.da.login.exception; + +import lombok.Data; + +/** + * 自定义 token 异常 + * + * @author ch + * @version 1.0.0 + * @since 1.0.0 + *

+ * Created at 2020/8/6 4:58 下午 + */ +@Data +public class TokenRuntimeException extends RuntimeException{ + + private String code = "401"; + private String msg; + + public TokenRuntimeException(String msg) { + this.msg = msg; + } + +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/rest/LoginRestController.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/rest/LoginRestController.java index 589c05a9..65f4d611 100644 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/rest/LoginRestController.java +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/rest/LoginRestController.java @@ -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 - *

- * 若配置文件缺少该参数,将设置为1 - */ - @Value("${verifyCodeMode:1}") - private int verifyCodeMode; - - -// @ApiOperation(value = "登录") -// @PostMapping(value = "/login") -// @ResponseBody -// public ResponseMessage 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,7 +63,7 @@ public class LoginRestController { return Result.error("r0011", "您输入的帐号已禁用"); } if (PasswordUtils.validatePassword(password, userEO.getPassword())) { - String token = JWTUtil.sign(username, userEO.getUsid(),userEO.getPassword()); + String token = jwtUtils.generateToken(userEO.getUsid()); response.setHeader("Authorization", token); response.addHeader("Access-Control-Allow-Headers", "Authorization"); // 加密重要信息 @@ -156,69 +79,47 @@ 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 userInfo(HttpServletResponse response) throws NumberFormatException { - UserEO user = UserUtils.getUser(); - if (user != null) { - return Result.success(user); + public ResponseMessage 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(); + UserEO userEO = userService.getUserByLoginNameNotDeleted("wenxianshun"); + if (null == userEO) { + return Result.error("r0011", "用户不存在"); + } + if(userEO.getDisableFlag()==1){ + return Result.error("r0011", "帐号已禁用"); + } + String token = jwtUtils.generateToken("wenxianshun"); + 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> 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(); - } } diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTFilter.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTFilter.java deleted file mode 100644 index 03366e66..00000000 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTFilter.java +++ /dev/null @@ -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; - } - -} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTRealm.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTRealm.java deleted file mode 100644 index 529af2b5..00000000 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTRealm.java +++ /dev/null @@ -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的时候才会进行回调. - *

- * 权限信息.(授权): - * 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 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 getCacheMap() { - if (cacheMap == null) { - cacheMap = new HashMap<>(); - } - return cacheMap; - } - } - -} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTToken.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTToken.java deleted file mode 100644 index 6d857613..00000000 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/JWTToken.java +++ /dev/null @@ -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; - } -} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/TokenInterceptor.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/TokenInterceptor.java new file mode 100644 index 00000000..6385a6e4 --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/TokenInterceptor.java @@ -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 + *

+ * 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; + } +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/WebMvcConfig.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/WebMvcConfig.java new file mode 100644 index 00000000..f1762d8b --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/security/WebMvcConfig.java @@ -0,0 +1,38 @@ +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/login"); + addInterceptor.excludePathPatterns("/v2/api-docs"); + addInterceptor.excludePathPatterns("/webjars/**"); + addInterceptor.excludePathPatterns("/swagger-resources/**"); + addInterceptor.excludePathPatterns("/swagger-ui.html"); + addInterceptor.excludePathPatterns("/doc.html"); + + // 添加自定义拦截器,并拦截对应 url + addInterceptor.addPathPatterns("/**"); + } +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/CacheUtils.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/CacheUtils.java deleted file mode 100644 index a855ef5b..00000000 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/CacheUtils.java +++ /dev/null @@ -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 - // - 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; - } - -} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/IDMUtil.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/IDMUtil.java new file mode 100644 index 00000000..d005404c --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/IDMUtil.java @@ -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 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 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 ""; + } +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JWTUtil.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JWTUtil.java deleted file mode 100644 index 1cd681d0..00000000 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JWTUtil.java +++ /dev/null @@ -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; - } - -} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JwtUtils.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JwtUtils.java new file mode 100644 index 00000000..e3c47ae4 --- /dev/null +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/JwtUtils.java @@ -0,0 +1,60 @@ +package com.adc.da.login.util; + +import io.jsonwebtoken.Claims; +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 + *

+ * Created at 2020/7/30 2:23 下午 + */ +@Component +public class JwtUtils { + + // 过期时间 + private static long expire = 604800; + // 秘钥 + 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) { + try { + return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + } catch (Exception e) { + System.out.println("validate is token error"); + return null; + } + } + + /** + * 判断 token 是否过期 + */ + public boolean isTokenExpired(Date expiration){ + return expiration.before(new Date()); + } + +} diff --git a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/UserUtils.java b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/UserUtils.java index 0a8b15db..01507f03 100644 --- a/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/UserUtils.java +++ b/adc-da-jwtLogin/src/main/java/com/adc/da/login/util/UserUtils.java @@ -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 getCacheMap() { Map 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; } } diff --git a/adc-da-main/src/main/java/com/adc/da/main/advice/AdcDaBaseExceptionAdvice.java b/adc-da-main/src/main/java/com/adc/da/main/advice/AdcDaBaseExceptionAdvice.java index 59b6ce91..28cddf98 100644 --- a/adc-da-main/src/main/java/com/adc/da/main/advice/AdcDaBaseExceptionAdvice.java +++ b/adc-da-main/src/main/java/com/adc/da/main/advice/AdcDaBaseExceptionAdvice.java @@ -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; diff --git a/adc-da-main/src/main/java/com/adc/da/main/advice/ShiroExceptionAdvice.java b/adc-da-main/src/main/java/com/adc/da/main/advice/ShiroExceptionAdvice.java deleted file mode 100644 index 65bed1de..00000000 --- a/adc-da-main/src/main/java/com/adc/da/main/advice/ShiroExceptionAdvice.java +++ /dev/null @@ -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","无权访问"); - } -} diff --git a/adc-da-main/src/main/java/com/adc/da/main/config/DefinitionUrlConfig.java b/adc-da-main/src/main/java/com/adc/da/main/config/DefinitionUrlConfig.java deleted file mode 100644 index 2f338bb1..00000000 --- a/adc-da-main/src/main/java/com/adc/da/main/config/DefinitionUrlConfig.java +++ /dev/null @@ -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 definitionUrlOptions(){ - Map 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; - } - - -} diff --git a/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfig.java b/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfig.java deleted file mode 100644 index 4bfc489b..00000000 --- a/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfig.java +++ /dev/null @@ -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 filterMap() { - Map filterMap = new HashMap<>(); - filterMap.put(JWT_FILTER_NAME, new JWTFilter()); - return filterMap; - } - - /** - * url拦截规则 - */ - private Map 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 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; - } - -} diff --git a/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfiguration.java b/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfiguration.java deleted file mode 100644 index f40d34ce..00000000 --- a/adc-da-main/src/main/java/com/adc/da/main/config/ShiroConfiguration.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/entity/UserEO.java b/adc-da-sys/src/main/java/com/adc/da/sys/entity/UserEO.java index 1337593e..4923f79b 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/entity/UserEO.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/entity/UserEO.java @@ -53,6 +53,7 @@ public class UserEO extends BaseEntity implements Serializable { private String orgType; private String ssoId; + private String token; /** * java字段名转换为原始数据库列名。如果不存在则返回null
*

字段列表:

@@ -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; + } }