From 05f00b055878145a51cdd8cad6684db0dd193c7c Mon Sep 17 00:00:00 2001 From: fengshuonan Date: Sat, 2 Jan 2021 22:22:21 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90auth=E3=80=91=E4=BB=8E=E6=96=B0?= =?UTF-8?q?=E6=95=B4=E7=90=86session=E8=B6=85=E6=97=B6=E6=83=85=E5=86=B5?= =?UTF-8?q?=E7=9A=84=E6=A0=A1=E9=AA=8C=E5=92=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roses/kernel/auth/api/AuthServiceApi.java | 14 ++------- .../kernel/auth/api/SessionManagerApi.java | 10 ++++++ .../auth/api/cookie/SessionCookieCreator.java | 4 +-- .../exception/enums/AuthExceptionEnum.java | 26 ++++++++-------- .../kernel/auth/auth/AuthServiceImpl.java | 31 ++++++++++++++----- .../permission/PermissionServiceImpl.java | 4 +-- .../auth/session/DefaultSessionManager.java | 13 +++++++- 7 files changed, 64 insertions(+), 38 deletions(-) diff --git a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/AuthServiceApi.java b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/AuthServiceApi.java index a9c7422e3..86ab39301 100644 --- a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/AuthServiceApi.java +++ b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/AuthServiceApi.java @@ -49,7 +49,9 @@ public interface AuthServiceApi { void logoutWithToken(String token); /** - * 校验token + * 校验jwt token的正确性,调用jwt工具类相关方法校验 + *

+ * 结果有三种,第一是jwt过期了,第二是用户随便写的错误token,第三种是token正确,token正确不会抛出异常 * * @param token 某个用户的登录token * @throws AuthException 认证异常,如果token错误或过期,会有相关的异常抛出 @@ -58,16 +60,6 @@ public interface AuthServiceApi { */ void validateToken(String token) throws AuthException; - /** - * 获取token是否正确 - * - * @param token 某个用户的登录token - * @return true-token正确,false-token错误 - * @author fengshuonan - * @date 2020/10/19 14:16 - */ - boolean getTokenFlag(String token); - /** * 校验用户是否认证通过,认证是校验token的过程,校验失败会抛出异常 * diff --git a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/SessionManagerApi.java b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/SessionManagerApi.java index ff8a701fd..cbc140b73 100644 --- a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/SessionManagerApi.java +++ b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/SessionManagerApi.java @@ -73,4 +73,14 @@ public interface SessionManagerApi { */ void refreshSession(String token); + /** + * 销毁当前用户对应的会话cookie + *

+ * 一般用在单体不分离版本中 + * + * @author fengshuonan + * @date 2021/1/2 20:25 + */ + void destroySessionCookie(); + } diff --git a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/cookie/SessionCookieCreator.java b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/cookie/SessionCookieCreator.java index a3b567c56..693e9e481 100644 --- a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/cookie/SessionCookieCreator.java +++ b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/cookie/SessionCookieCreator.java @@ -1,7 +1,5 @@ package cn.stylefeng.roses.kernel.auth.api.cookie; -import cn.hutool.core.convert.Convert; - import javax.servlet.http.Cookie; /** @@ -27,7 +25,7 @@ public abstract class SessionCookieCreator { */ public Cookie createCookie(String cookieName, String cookieValue, Integer sessionExpiredSeconds) { Cookie cookie = new Cookie(cookieName, cookieValue); - cookie.setMaxAge(Convert.toInt(sessionExpiredSeconds)); + cookie.setMaxAge(sessionExpiredSeconds); this.expandCookieProp(cookie); return cookie; } diff --git a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java index 4805c0ed2..d84f39608 100644 --- a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java +++ b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java @@ -15,44 +15,44 @@ import lombok.Getter; public enum AuthExceptionEnum implements AbstractExceptionEnum { /** - * 认证异常 + * 会话过期或超时,token过期,都属于这种异常,提示用户从新登录 */ - AUTH_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "认证失败,请检查您的登录是否过期"), + AUTH_EXPIRED_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "当前登录会话过期,请重新登录"), + + /** + * jwt token解析失败,可能用户写错了token,或者用户随意写的token,导致jwt无法解析 + */ + TOKEN_PARSE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "02", "TOKEN解析失败,请传递正常TOKEN"), /** * 登陆时,账号或密码为空 */ - PARAM_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "02", "登陆失败,账号或密码参数为空"), + PARAM_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "03", "登陆失败,账号或密码参数为空"), /** * 账号或密码错误 */ - USERNAME_PASSWORD_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "03", "账号或密码错误"), + USERNAME_PASSWORD_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "04", "账号或密码错误"), /** * 用户状态异常,可能被禁用可能被冻结,用StrUtil.format()格式化 */ - USER_STATUS_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "04", "当前用户被{},请检查用户状态是否正常"), + USER_STATUS_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "05", "当前用户被{},请检查用户状态是否正常"), /** * 登陆失败,账号参数为空 */ - ACCOUNT_IS_BLANK(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "05", "登陆失败,账号参数为空"), + ACCOUNT_IS_BLANK(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "06", "登陆失败,账号参数为空"), /** * 获取token失败 */ - TOKEN_GET_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "06", "获取token失败,请检查header和param中是否传递了用户token"), + TOKEN_GET_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "07", "获取token失败,请检查header和param中是否传递了用户token"), /** * 获取资源为空 */ - RESOURCE_DEFINITION_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "07", "获取资源为空,请检查当前请求url是否存在对应的ResourceDefinition"), - - /** - * 获取不到token对应的用户信息,请检查登录是否过期 - */ - TOKEN_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "08", "获取不到token对应的用户信息,请检查登录是否过期"), + RESOURCE_DEFINITION_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "08", "获取资源为空,请检查当前请求url是否存在对应的ResourceDefinition"), /** * 权限校验失败,请检查用户是否有该资源的权限 diff --git a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/auth/AuthServiceImpl.java b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/auth/AuthServiceImpl.java index f74331f4d..fdacfd704 100644 --- a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/auth/AuthServiceImpl.java +++ b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/auth/AuthServiceImpl.java @@ -14,6 +14,7 @@ import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse; import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser; import cn.stylefeng.roses.kernel.jwt.api.context.JwtContext; import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException; +import cn.stylefeng.roses.kernel.jwt.api.exception.enums.JwtExceptionEnum; import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload; import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil; import cn.stylefeng.roses.kernel.system.UserServiceApi; @@ -24,6 +25,9 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Date; +import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.AUTH_EXPIRED_ERROR; +import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.TOKEN_PARSE_ERROR; + /** * 认证服务的实现 * @@ -77,15 +81,26 @@ public class AuthServiceImpl implements AuthServiceApi { @Override public void validateToken(String token) throws AuthException { try { + // 1. 先校验jwt token本身是否有问题 JwtContext.me().validateTokenWithException(token); - } catch (JwtException e) { - throw new AuthException(e.getErrorCode(), e.getUserTip()); - } - } - @Override - public boolean getTokenFlag(String token) { - return JwtContext.me().validateToken(token); + // 2. 判断session里是否有这个token + LoginUser session = sessionManagerApi.getSession(token); + if (session == null) { + throw new AuthException(AUTH_EXPIRED_ERROR); + } + } catch (JwtException jwtException) { + // jwt token本身过期的话,返回 AUTH_EXPIRED_ERROR + if (JwtExceptionEnum.JWT_EXPIRED_ERROR.getErrorCode().equals(jwtException.getErrorCode())) { + throw new AuthException(AUTH_EXPIRED_ERROR); + } else { + // 其他情况为返回jwt解析错误 + throw new AuthException(TOKEN_PARSE_ERROR); + } + } catch (Exception jwtSelfException) { + // 其他jwt解析错误 + throw new AuthException(TOKEN_PARSE_ERROR); + } } @Override @@ -114,7 +129,7 @@ public class AuthServiceImpl implements AuthServiceApi { // 6. 如果会话信息为空,则判定此次校验失败 if (loginUser == null) { - throw new AuthException(AuthExceptionEnum.AUTH_ERROR); + throw new AuthException(AUTH_EXPIRED_ERROR); } } diff --git a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/permission/PermissionServiceImpl.java b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/permission/PermissionServiceImpl.java index bc49746e3..f27cff75e 100644 --- a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/permission/PermissionServiceImpl.java +++ b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/permission/PermissionServiceImpl.java @@ -11,8 +11,8 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Set; +import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.AUTH_EXPIRED_ERROR; import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.PERMISSION_RES_VALIDATE_ERROR; -import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.TOKEN_ERROR; /** * 权限相关的service @@ -37,7 +37,7 @@ public class PermissionServiceImpl implements PermissionServiceApi { // 2. 获取token对应的用户信息 LoginUser session = sessionManagerApi.getSession(token); if (session == null) { - throw new AuthException(TOKEN_ERROR); + throw new AuthException(AUTH_EXPIRED_ERROR); } // 3. 验证用户有没有当前url的权限 diff --git a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/DefaultSessionManager.java b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/DefaultSessionManager.java index 75ddea429..89b8c527d 100644 --- a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/DefaultSessionManager.java +++ b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/DefaultSessionManager.java @@ -76,7 +76,7 @@ public class DefaultSessionManager implements SessionManagerApi { // 如果开启了cookie存储会话信息,则需要给HttpServletResponse添加一个cookie if (AuthConfigExpander.getSessionAddToCookie()) { String sessionCookieName = AuthConfigExpander.getSessionCookieName(); - Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, token, Convert.toInt(sessionExpiredSeconds)); + Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, token, Convert.toInt(AuthConfigExpander.getAuthJwtTimeoutSeconds())); HttpServletResponse response = HttpServletUtil.getResponse(); response.addCookie(cookie); } @@ -155,4 +155,15 @@ public class DefaultSessionManager implements SessionManagerApi { } } + @Override + public void destroySessionCookie() { + // 如果开启了cookie存储会话信息,则需要给HttpServletResponse添加一个cookie + if (AuthConfigExpander.getSessionAddToCookie()) { + String sessionCookieName = AuthConfigExpander.getSessionCookieName(); + Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, null, 0); + HttpServletResponse response = HttpServletUtil.getResponse(); + response.addCookie(cookie); + } + } + }