wuheng 1 жил өмнө
parent
commit
970dfd6596

+ 4 - 0
common/pom.xml

@@ -14,6 +14,10 @@
     </parent>
 
     <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>javax.annotation</groupId>
             <artifactId>javax.annotation-api</artifactId>

+ 3 - 1
common/src/main/java/com/koobietech/eas/common/pojo/JwtUserPojo.java

@@ -10,11 +10,13 @@ public class JwtUserPojo {
     String username;
     Long id;
     Enum type;
+    Enum jwtType;
 
-    public JwtUserPojo(String username, Long id, Enum type) {
+    public JwtUserPojo(String username, Long id, Enum type, Enum jwtType) {
         this.username = username;
         this.id = id;
         this.type = type;
+        this.jwtType = jwtType;
     }
 
     public JwtUserPojo() {

+ 1 - 1
common/src/main/java/com/koobietech/eas/common/result/JsonResult.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 public class JsonResult implements Serializable {
     private boolean status = false;
     private String msg = "";
-    private Object data = null;
+    private Object data = new String[]{};
 
     private Integer code = 200;
 

+ 4 - 0
common/src/main/java/com/koobietech/eas/common/utils/JwtManager.java

@@ -5,6 +5,7 @@ import com.auth0.jwt.algorithms.Algorithm;
 import com.auth0.jwt.exceptions.JWTVerificationException;
 import com.auth0.jwt.interfaces.DecodedJWT;
 import com.auth0.jwt.interfaces.JWTVerifier;
+import com.koobietech.eas.dao.constant.JwtType;
 import com.koobietech.eas.dao.constant.UserType;
 import com.koobietech.eas.common.exception.EasException;
 import com.koobietech.eas.common.pojo.JwtUserPojo;
@@ -34,6 +35,7 @@ public class JwtManager {
                 .withClaim("user", userDto.getUsername())
                 .withClaim("id", userDto.getId())
                 .withClaim("type", userDto.getType().toString())
+                .withClaim("jwtType", userDto.getJwtType().toString())
                 .withExpiresAt( calendar.getTime() )
                 .sign(Algorithm.HMAC256(SECRET));
         return sign;
@@ -51,6 +53,7 @@ public class JwtManager {
                 .withClaim("user", userDto.getUsername())
                 .withClaim("id", userDto.getId())
                 .withClaim("type", userDto.getType().toString())
+                .withClaim("jwtType", userDto.getJwtType().toString())
                 .withExpiresAt( calendar.getTime() )
                 .sign(Algorithm.HMAC256(SECRET));
         return sign;
@@ -69,6 +72,7 @@ public class JwtManager {
             jwtUserPojo.setId(verify.getClaim("id").asLong());
             jwtUserPojo.setUsername(verify.getClaim("user").asString());
             jwtUserPojo.setType(UserType.valueOf(verify.getClaim("type").asString()));
+            jwtUserPojo.setJwtType(JwtType.valueOf(verify.getClaim("jwtType").asString()));
         } catch ( JWTVerificationException e){
             throw new EasException("token 不正确!");
         }

+ 26 - 0
common/src/main/java/com/koobietech/eas/common/utils/ResponseManager.java

@@ -0,0 +1,26 @@
+package com.koobietech.eas.common.utils;
+
+import cn.hutool.json.JSONUtil;
+import com.koobietech.eas.common.result.JsonResult;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author lc
+ */
+public class ResponseManager {
+    public static void printResponse(HttpServletResponse response, String message, int code) {
+        response.setHeader("Cache-Control","no-cache");
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json");
+        try {
+            response.getWriter().println(JSONUtil.parse(JsonResult.fail(message, code)));
+            response.getWriter().flush();
+            response.getWriter().close();
+            response.flushBuffer();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+    }
+}

+ 9 - 0
controller/src/main/java/com/koobietech/eas/config/ExceptionAdviceConfiguration.java

@@ -5,6 +5,7 @@ import com.koobietech.eas.common.result.JsonResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
+import org.springframework.security.core.AuthenticationException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.ResponseStatus;
@@ -18,6 +19,14 @@ public class ExceptionAdviceConfiguration {
 
     private static final Logger logger = LoggerFactory.getLogger(ExceptionAdviceConfiguration.class);
 
+    @ResponseBody
+    @ResponseStatus(HttpStatus.OK)
+    @ExceptionHandler(AuthenticationException.class)
+    public JsonResult handleAuthenticationException(AuthenticationException ex) {
+        System.out.println( ex.getMessage() );
+        return JsonResult.fail(ex.getMessage(), 1000);
+    }
+
     @ResponseBody
     @ResponseStatus(HttpStatus.OK)
     @ExceptionHandler(Exception.class)

+ 1 - 0
controller/src/main/resources/application.yaml

@@ -33,6 +33,7 @@ security:
       - /login/studentLogin
       - /login/verify/get
       - /login/verify/check
+      - /favicon.ico
 project:
   path: ${user.home}/archivesFiles
 

+ 9 - 0
dao/src/main/java/com/koobietech/eas/dao/constant/JwtType.java

@@ -0,0 +1,9 @@
+package com.koobietech.eas.dao.constant;
+
+/**
+ * @author lc
+ */
+
+public enum JwtType {
+    TOKEN, REF_TOKEN
+}

+ 4 - 11
security/src/main/java/com/koobietech/eas/security/exception/EasAuthenticationEntryPoint.java

@@ -1,26 +1,19 @@
 package com.koobietech.eas.security.exception;
 
-import cn.hutool.json.JSONUtil;
-import com.koobietech.eas.common.result.JsonResult;
+import com.koobietech.eas.common.utils.ResponseManager;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
 
 /**
  * @author lc
  */
 public class EasAuthenticationEntryPoint implements AuthenticationEntryPoint {
     @Override
-    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Cache-Control","no-cache");
-        response.setCharacterEncoding("UTF-8");
-        response.setContentType("application/json");
-        response.getWriter().println(JSONUtil.parse(JsonResult.fail("不允许访问", 403)));
-        response.getWriter().flush();
+    public void commence(HttpServletRequest request, HttpServletResponse response,
+                         AuthenticationException authException) {
+        ResponseManager.printResponse(response, "不允许访问", 403);
     }
 }

+ 3 - 11
security/src/main/java/com/koobietech/eas/security/exception/EasAuthenticationFailureHandler.java

@@ -1,14 +1,11 @@
 package com.koobietech.eas.security.exception;
 
-import cn.hutool.json.JSONUtil;
-import com.koobietech.eas.common.result.JsonResult;
+import com.koobietech.eas.common.utils.ResponseManager;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.web.access.AccessDeniedHandler;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
 
 /**
  * @author lc
@@ -17,12 +14,7 @@ public class EasAuthenticationFailureHandler implements AccessDeniedHandler {
     @Override
     public void handle(HttpServletRequest request,
                        HttpServletResponse response,
-                       AccessDeniedException e) throws IOException, ServletException {
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Cache-Control","no-cache");
-        response.setCharacterEncoding("UTF-8");
-        response.setContentType("application/json");
-        response.getWriter().println(JSONUtil.parse(JsonResult.fail("您无权操作!", 403)));
-        response.getWriter().flush();
+                       AccessDeniedException accessException) {
+        ResponseManager.printResponse(response, "您无权操作!", 403);
     }
 }

+ 33 - 37
security/src/main/java/com/koobietech/eas/security/filter/EasSecurityFilter.java

@@ -3,6 +3,7 @@ package com.koobietech.eas.security.filter;
 import com.koobietech.eas.common.exception.EasException;
 import com.koobietech.eas.common.pojo.JwtUserPojo;
 import com.koobietech.eas.common.utils.JwtManager;
+import com.koobietech.eas.common.utils.ResponseManager;
 import com.koobietech.eas.dao.pojo.UserDetailPojo;
 import com.koobietech.eas.service.EasSysUserLoginRedisService;
 import org.slf4j.Logger;
@@ -41,52 +42,47 @@ public class EasSecurityFilter extends OncePerRequestFilter {
 
         //从请求里面拿到token
         String token = request.getHeader("Authorization");
-        //判断token是否存在
-        if (StringUtils.hasText(token)) {
-            //解析token成JwtUserDto
-            JwtUserPojo jwtUserPojo = null;
-            try {
-                //过滤器 允许 Token 不正确, 后面Security 会拦截处理
-                jwtUserPojo = jwtManager.decodeJwt(token);
-            } catch ( EasException e) {
-                logger.debug(e.getMessage());
-            }
-            if ( Objects.nonNull(jwtUserPojo) ) {
-                //判断token是否有效
-                UserDetailPojo userDetailPojo = null;
-                try {
-                    userDetailPojo = loginRedisService.checkToken(jwtUserPojo);
-                } catch ( EasException e) {
-                    logger.debug(e.getMessage());
-                }
+        try {
+            //判断token是否存在
+            if (StringUtils.hasText(token)) {
+                //解析token成JwtUserDto
+                JwtUserPojo jwtUserPojo = jwtManager.decodeJwt(token);
+
+                if (Objects.nonNull(jwtUserPojo)) {
+                    //判断token是否有效
+                    UserDetailPojo userDetailPojo = loginRedisService.checkToken(jwtUserPojo);
 
-                // 如果获取到了有效的用户对象
-                if (Objects.nonNull(userDetailPojo)) {
-                    // 获取当前的 SecurityContext 对象,用于保存当前用户的安全上下文信息
-                    SecurityContext context = SecurityContextHolder.getContext();
+                    // 如果获取到了有效的用户对象
+                    if (Objects.nonNull(userDetailPojo)) {
+                        // 获取当前的 SecurityContext 对象,用于保存当前用户的安全上下文信息
+                        SecurityContext context = SecurityContextHolder.getContext();
 
-                    // 获取用户的权限列表
-                    List<String> permissionPojo = userDetailPojo.getPermissionPojos();
+                        // 获取用户的权限列表
+                        List<String> permissionPojo = userDetailPojo.getPermissionPojos();
 
-                    // 创建一个 ArrayList 集合,用于存储用户权限对应的 SimpleGrantedAuthority 权限对象
-                    ArrayList<SimpleGrantedAuthority> objects = new ArrayList<>();
+                        // 创建一个 ArrayList 集合,用于存储用户权限对应的 SimpleGrantedAuthority 权限对象
+                        ArrayList<SimpleGrantedAuthority> objects = new ArrayList<>();
 
-                    // 遍历用户的权限列表
-                    if ( Objects.nonNull(permissionPojo) ) {
-                        for (String userPermission : permissionPojo) {
-                            // 创建一个 SimpleGrantedAuthority 权限对象,并添加到集合中
-                            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(userPermission);
-                            objects.add(authority);
+                        // 遍历用户的权限列表
+                        if (Objects.nonNull(permissionPojo)) {
+                            for (String userPermission : permissionPojo) {
+                                // 创建一个 SimpleGrantedAuthority 权限对象,并添加到集合中
+                                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(userPermission);
+                                objects.add(authority);
+                            }
                         }
-                    }
 
-                    // 使用用户的用户名、空凭证参数和权限对象集合创建一个 UsernamePasswordAuthenticationToken 身份验证令牌
-                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailPojo, null, objects);
+                        // 使用用户的用户名、空凭证参数和权限对象集合创建一个 UsernamePasswordAuthenticationToken 身份验证令牌
+                        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailPojo, null, objects);
 
-                    // 将身份验证令牌设置到当前的 SecurityContext 中
-                    context.setAuthentication(authenticationToken);
+                        // 将身份验证令牌设置到当前的 SecurityContext 中
+                        context.setAuthentication(authenticationToken);
+                    }
                 }
             }
+        } catch (EasException e) {
+            ResponseManager.printResponse(response, e.getMessage(), e.getCode());
+            return;
         }
         filterChain.doFilter(request, response);
     }

+ 9 - 3
service/src/main/java/com/koobietech/eas/service/impl/EasSysAdminLoginServiceImpl.java

@@ -8,6 +8,7 @@ import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.common.utils.FileManager;
 import com.koobietech.eas.common.utils.JwtManager;
 import com.koobietech.eas.common.utils.PasswordManager;
+import com.koobietech.eas.dao.constant.JwtType;
 import com.koobietech.eas.dao.constant.UserType;
 import com.koobietech.eas.dao.dto.LoginTokenDto;
 import com.koobietech.eas.dao.mapper.AdminLoginMapper;
@@ -120,9 +121,12 @@ public class EasSysAdminLoginServiceImpl implements EasSysAdminLoginService {
         userDetailPojoInRedis.setUserType(userType);
 
         // 生成token
-        JwtUserPojo jwtUserPojo = new JwtUserPojo(userDetailPojoInRedis.getUsername(), userDetailPojoInRedis.getId(), userType);
+        JwtUserPojo jwtUserPojo = new JwtUserPojo(userDetailPojoInRedis.getUsername(),
+                userDetailPojoInRedis.getId(), userType, JwtType.TOKEN);
+        JwtUserPojo refJwtUserPojo = new JwtUserPojo(userDetailPojoInRedis.getUsername(),
+                userDetailPojoInRedis.getId(), userType, JwtType.REF_TOKEN);
         String token = jwtManager.createJwt(jwtUserPojo, token_expires);
-        String refreshToken = jwtManager.createJwt(jwtUserPojo, refreshToken_expires);
+        String refreshToken = jwtManager.createJwt(refJwtUserPojo, refreshToken_expires);
         System.out.println("token:" + token);
         System.out.println("refreshToken:" + refreshToken);
 
@@ -152,9 +156,11 @@ public class EasSysAdminLoginServiceImpl implements EasSysAdminLoginService {
             throw new EasException("refresh token已过期", 412);
         }
         //如果不为空 那UserDetail里面就封装了用户的信息 生成新的token和refresh token
-        String newToken = jwtManager.createJwt(jwtUserPojo, token_expires);
         String newRefreshToken = jwtManager.createJwt(jwtUserPojo, refreshToken_expires);
 
+        jwtUserPojo.setJwtType(JwtType.TOKEN);
+        String newToken = jwtManager.createJwt(jwtUserPojo, token_expires);
+
         //生成新的k值 (token)
         String newRedisTokenKey = loginRedisService.createJwtTokenKey(jwtUserPojo);
 

+ 6 - 2
service/src/main/java/com/koobietech/eas/service/impl/EasSysStudentLoginServiceImpl.java

@@ -6,6 +6,7 @@ import com.koobietech.eas.common.pojo.JwtUserPojo;
 import com.koobietech.eas.common.utils.FileManager;
 import com.koobietech.eas.common.utils.JwtManager;
 import com.koobietech.eas.common.utils.PasswordManager;
+import com.koobietech.eas.dao.constant.JwtType;
 import com.koobietech.eas.dao.constant.UserType;
 import com.koobietech.eas.dao.dto.LoginTokenDto;
 import com.koobietech.eas.dao.pojo.DepartmentPojo;
@@ -120,11 +121,14 @@ public class EasSysStudentLoginServiceImpl implements EasSysStudentLoginService
 
         userDetailPojo.setUserType(UserType.MEMBER);
         // 生成token
-        JwtUserPojo jwtUserPojo = new JwtUserPojo(userDetailPojo.getUsername(), userDetailPojo.getId(), UserType.MEMBER);
+        JwtUserPojo jwtUserPojo = new JwtUserPojo(userDetailPojo.getUsername(),
+                userDetailPojo.getId(), UserType.MEMBER, JwtType.TOKEN);
+        JwtUserPojo refJwtUserPojo = new JwtUserPojo(userDetailPojo.getUsername(),
+                userDetailPojo.getId(), UserType.MEMBER, JwtType.REF_TOKEN);
 
         String token = jwtManager.createJwt(jwtUserPojo, token_expires);
 
-        String refreshToken = jwtManager.createJwt(jwtUserPojo, refreshToken_expires);
+        String refreshToken = jwtManager.createJwt(refJwtUserPojo, refreshToken_expires);
 
         // 生成redis key
         String jwtTokenKey = studentLoginRedisService.createJwtTokenKey(jwtUserPojo);

+ 15 - 4
service/src/main/java/com/koobietech/eas/service/impl/EasSysUserLoginRedisServiceImpl.java

@@ -3,6 +3,7 @@ package com.koobietech.eas.service.impl;
 import com.koobietech.eas.common.exception.EasException;
 import com.koobietech.eas.common.pojo.JwtUserPojo;
 import com.koobietech.eas.common.service.RedisService;
+import com.koobietech.eas.dao.constant.JwtType;
 import com.koobietech.eas.dao.pojo.UserDetailPojo;
 import com.koobietech.eas.service.EasSysUserLoginRedisService;
 import org.springframework.stereotype.Service;
@@ -21,12 +22,22 @@ public class EasSysUserLoginRedisServiceImpl implements EasSysUserLoginRedisServ
 
     @Override
     public UserDetailPojo checkToken(JwtUserPojo jwtUserPojo) {
-        String jwtKey = createJwtTokenKey(jwtUserPojo);
         //判断redis里面是否有这个key
-        if (!redisService.hasKey(jwtKey)) {
-            throw new EasException("token已过期");
+        if ( jwtUserPojo.getJwtType().equals(JwtType.TOKEN) ) {
+            String jwtKey = createJwtTokenKey(jwtUserPojo);
+            if (redisService.hasKey(jwtKey)) {
+                return (UserDetailPojo) redisService.get(jwtKey);
+            }
         }
-        return (UserDetailPojo) redisService.get(jwtKey);
+
+        //刷新token来换token
+        if ( jwtUserPojo.getJwtType().equals(JwtType.REF_TOKEN) ) {
+            String refJwtKey = createJwtRefreshTokenKey(jwtUserPojo);
+            if (redisService.hasKey(refJwtKey)) {
+                return (UserDetailPojo) redisService.get(refJwtKey);
+            }
+        }
+        throw new EasException("token已过期", 9988);
     }
 
     @Override