扩展登录方式

v1.4.1
Parker 5 years ago
parent ad3717d51c
commit 4a57348a6d

@ -1,24 +1,7 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.common.constants; package org.opsli.common.constants;
/** /**
* @BelongsProject: opsli-boot * @Author:
* @BelongsPackage: org.opsli.common.constants
* @Author: Parker
* @CreateTime: 2020-09-16 17:42 * @CreateTime: 2020-09-16 17:42
* @Description: * @Description:
*/ */
@ -33,4 +16,10 @@ public interface SignConstants {
/** 时间戳 */ /** 时间戳 */
String TIMESTAMP = "timestamp"; String TIMESTAMP = "timestamp";
/** 其他信息 */
String OTHER = "other";
/** 签名 类型 */
String TYPE = "type";
} }

@ -0,0 +1,16 @@
package org.opsli.common.constants;
/**
* @Author:
* @CreateTime: 2020-09-16 17:42
* @Description: Token
*/
public interface TokenTypeConstants {
/** 系统内部TOKEN */
String TYPE_SYSTEM = "system";
/** 外部TOKEN */
String TYPE_EXTERNAL = "external";
}

@ -16,8 +16,13 @@
package org.opsli.core.conf; package org.opsli.core.conf;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
@ -25,21 +30,21 @@ import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.opsli.common.utils.Props; import org.opsli.common.utils.Props;
import org.opsli.core.security.shiro.filter.OAuth2Filter; import org.opsli.core.security.shiro.authenticator.CustomModularRealmAuthenticator;
import org.opsli.core.security.shiro.realm.OAuth2Realm; import org.opsli.core.security.shiro.filter.CustomShiroFilter;
import org.opsli.core.security.shiro.realm.FlagRealm;
import org.opsli.plugins.redis.conf.RedisPluginConfig; import org.opsli.plugins.redis.conf.RedisPluginConfig;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import javax.servlet.Filter; import javax.servlet.Filter;
import java.util.HashMap; import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* Shiro * Shiro
@ -76,7 +81,7 @@ public class ShiroConfig {
//oauth过滤 //oauth过滤
Map<String, Filter> filters = Maps.newHashMapWithExpectedSize(1); Map<String, Filter> filters = Maps.newHashMapWithExpectedSize(1);
filters.put("oauth2", new OAuth2Filter()); filters.put("last_filter", new CustomShiroFilter());
shiroFilter.setFilters(filters); shiroFilter.setFilters(filters);
Map<String, String> filterMap = Maps.newLinkedHashMap(); Map<String, String> filterMap = Maps.newLinkedHashMap();
@ -106,7 +111,7 @@ public class ShiroConfig {
filterMap.put("/swagger-ui.html", "anon"); filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/swagger-resources/**", "anon"); filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/static/file/**", "anon"); filterMap.put("/static/file/**", "anon");
filterMap.put("/**", "oauth2"); filterMap.put("/**", "last_filter");
shiroFilter.setFilterChainDefinitionMap(filterMap); shiroFilter.setFilterChainDefinitionMap(filterMap);
@ -122,16 +127,42 @@ public class ShiroConfig {
} }
@Bean("securityManager") @Bean("securityManager")
public DefaultWebSecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager,LettuceConnectionFactory lettuceConnectionFactory) { public DefaultWebSecurityManager securityManager(SessionManager sessionManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(oAuth2Realm);
securityManager.setSessionManager(sessionManager); securityManager.setSessionManager(sessionManager);
List<Realm> realms = Lists.newArrayList();
// 拿到state包下 实现了 FlagRealm 接口的,所有子类
Set<Class<?>> clazzSet = ClassUtil.scanPackageBySuper(FlagRealm.class.getPackage().getName()
, FlagRealm.class
);
for (Class<?> aClass : clazzSet) {
// 位运算 去除抽象类
if((aClass.getModifiers() & Modifier.ABSTRACT) != 0){
continue;
}
try {
realms.add((Realm) aClass.newInstance());
} catch (Exception ignored){ }
}
if(CollUtil.isNotEmpty(realms)){
// 追加 Realms
securityManager.setRealms(realms);
}
return securityManager; return securityManager;
} }
@Bean /**
public OAuth2Realm oAuth2Realm() { * Realm使
return new OAuth2Realm(); */
@Bean("modularRealmAuthenticator")
public ModularRealmAuthenticator modularRealmAuthenticator(){
CustomModularRealmAuthenticator authenticator = new CustomModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
return authenticator;
} }
@ -157,7 +188,7 @@ public class ShiroConfig {
/** /**
* shiro * shiro
* @param securityManager * @param securityManager
* @return * @return
*/ */
@Bean("authorizationAttributeSourceAdvisor") @Bean("authorizationAttributeSourceAdvisor")

@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.opsli.core.utils.UserTokenUtil; import org.opsli.core.utils.UserTokenUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@ -47,6 +48,10 @@ import java.util.List;
@Import(BeanValidatorPluginsConfiguration.class) @Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig { public class SwaggerConfig {
/** 系统名称 */
@Value("${opsli.system-name:OPSLI 快速开发平台}")
private String systemName;
private final TypeResolver typeResolver; private final TypeResolver typeResolver;
@Autowired @Autowired
@ -87,7 +92,7 @@ public class SwaggerConfig {
private ApiInfo apiInfo() { private ApiInfo apiInfo() {
return new ApiInfoBuilder() return new ApiInfoBuilder()
// //大标题 // //大标题
.title("Opsli-Boot 后台服务API接口文档") .title(systemName + " 服务API接口文档")
// 版本号 // 版本号
.version("1.0") .version("1.0")
// 描述 // 描述

@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.AuthorizationException;
import org.opsli.api.base.result.ResultVo; import org.opsli.api.base.result.ResultVo;
import org.opsli.common.exception.*; import org.opsli.common.exception.*;
@ -143,6 +144,19 @@ public class GlobalExceptionHandler {
); );
} }
/**
* Shiro
*/
@ExceptionHandler(UnsupportedTokenException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResultVo<?> unsupportedTokenException(UnsupportedTokenException e) {
// 找不到认证授权器
return ResultVo.error(TokenMsg.EXCEPTION_NOT_REALM.getCode(),
TokenMsg.EXCEPTION_NOT_REALM.getMessage()
);
}
/** /**
* Token * Token

@ -52,7 +52,9 @@ public enum TokenMsg implements BaseMsg {
* *
*/ */
EXCEPTION_USER_NULL(12200, "用户为空"), EXCEPTION_USER_NULL(12200, "用户为空"),
EXCEPTION_NOT_AUTH(12204, "无权访问该方法"), EXCEPTION_NOT_AUTH(12201, "无权访问该方法"),
EXCEPTION_NOT_REALM(12202, "找不到认证授权器"),
; ;
private final int code; private final int code;

@ -0,0 +1,44 @@
package org.opsli.core.security.shiro.authenticator;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.realm.Realm;
import java.util.Collection;
/**
* 使TokenRealm
* @author Parker
*/
public class CustomModularRealmAuthenticator extends ModularRealmAuthenticator {
/**
* Realm
* realm.supports()RealmRealmsupports()
* @param realms
* @param token
* @return
*/
@Override
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
// 判断getRealms()是否返回为空
assertRealmsConfigured();
// 通过supports()方法匹配对应的Realm
Realm uniqueRealm = null;
for (Realm realm : realms) {
if (realm.supports(token)) {
uniqueRealm = realm;
break;
}
}
if (uniqueRealm == null) {
throw new UnsupportedTokenException();
}
return uniqueRealm.getAuthenticationInfo(token);
}
}

@ -0,0 +1,108 @@
package org.opsli.core.security.shiro.filter;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.opsli.api.base.result.ResultVo;
import org.opsli.common.constants.SignConstants;
import org.opsli.common.constants.TokenTypeConstants;
import org.opsli.core.msg.TokenMsg;
import org.opsli.core.security.shiro.token.ExternalToken;
import org.opsli.core.security.shiro.token.OAuth2Token;
import org.opsli.core.utils.JwtUtil;
import org.opsli.core.utils.UserTokenUtil;
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;
/**
* oauth2
*
* 401
*
*
*
* @author
* @date 2017-05-20 13:00
*/
public class CustomShiroFilter extends AuthenticatingFilter {
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
//获取请求token
String token = UserTokenUtil.getRequestToken((HttpServletRequest) request);
if(StringUtils.isBlank(token)){
return null;
}
// 分析token
String claim = JwtUtil.getClaim(token, SignConstants.TYPE);
// 第三方登录
if(TokenTypeConstants.TYPE_EXTERNAL.equals(claim)){
return new ExternalToken(token);
}
// .... 追加登录方式
return new OAuth2Token(token);
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){
return true;
}
// remeberMe ,remeberMe特殊页面需要授权
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//获取请求token如果token不存在直接返回401
String token = UserTokenUtil.getRequestToken((HttpServletRequest) request);
if(StringUtils.isBlank(token)){
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
httpResponse.setContentType("application/json; charset=utf-8");
// 401 Token失效请重新登录
ResultVo<Object> error = ResultVo.error(TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY.getCode(),
TokenMsg.EXCEPTION_TOKEN_LOSE_EFFICACY.getMessage());
httpResponse.getWriter().print(error.toJsonStr());
return false;
}
return executeLogin(request, response);
}
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
httpResponse.setContentType("application/json; charset=utf-8");
try {
//处理登录失败的异常
Throwable throwable = e.getCause() == null ? e : e.getCause();
ResultVo<Object> error = ResultVo.error(401, throwable.getMessage());
httpResponse.getWriter().print(error.toJsonStr());
} catch (IOException ignored) {}
return false;
}
}

@ -0,0 +1,54 @@
package org.opsli.core.security.shiro.realm;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.opsli.common.exception.TokenException;
import org.opsli.core.security.shiro.token.ExternalToken;
import org.springframework.stereotype.Component;
/**
*
*
* @author
* @date 2020-12-29 14:00
*/
@Component
@Slf4j
public class ExternalRealm extends AuthorizingRealm implements FlagRealm {
/** 账号锁定状态 */
public static final char LOCK_VAL = '1';
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof ExternalToken;
}
/**
* ()
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO 待处理
return null;
}
/**
* ()
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException, TokenException {
// TODO 待处理
return null;
}
}

@ -0,0 +1,11 @@
package org.opsli.core.security.shiro.realm;
/**
* @BelongsProject: think-bboss-parent
* @BelongsPackage: com.think.bboss.core.shiro.realm
* @Author: Parker
* @CreateTime: 2020-12-29 20:10
* @Description: Realm
*/
public interface FlagRealm {
}

@ -30,7 +30,7 @@ import java.util.List;
*/ */
@Component @Component
@Slf4j @Slf4j
public class OAuth2Realm extends AuthorizingRealm { public class OAuth2Realm extends AuthorizingRealm implements FlagRealm {
/** 账号锁定状态 */ /** 账号锁定状态 */
public static final String LOCK_VAL = "1"; public static final String LOCK_VAL = "1";

@ -4,16 +4,17 @@ package org.opsli.core.security.shiro.token;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
/** /**
* jwt token * token
* *
* @author parker * @author
* @date 2017-05-20 13:22 * @date 2017-05-20 13:22
*/ */
public class JwtToken implements AuthenticationToken { public class ExternalToken implements AuthenticationToken {
private String token;
public JwtToken(String token){ private final String token;
public ExternalToken(String token){
this.token = token; this.token = token;
} }
@ -26,4 +27,5 @@ public class JwtToken implements AuthenticationToken {
public Object getCredentials() { public Object getCredentials() {
return token; return token;
} }
} }

@ -11,7 +11,8 @@ import org.apache.shiro.authc.AuthenticationToken;
* @date 2017-05-20 13:22 * @date 2017-05-20 13:22
*/ */
public class OAuth2Token implements AuthenticationToken { public class OAuth2Token implements AuthenticationToken {
private String token;
private final String token;
public OAuth2Token(String token){ public OAuth2Token(String token){
this.token = token; this.token = token;
@ -26,4 +27,5 @@ public class OAuth2Token implements AuthenticationToken {
public Object getCredentials() { public Object getCredentials() {
return token; return token;
} }
} }

@ -8,6 +8,7 @@ import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.opsli.common.constants.SignConstants; import org.opsli.common.constants.SignConstants;
import org.opsli.common.constants.TokenTypeConstants;
import org.opsli.common.exception.JwtException; import org.opsli.common.exception.JwtException;
import org.opsli.common.utils.Props; import org.opsli.common.utils.Props;
import org.opsli.core.msg.JwtMsg; import org.opsli.core.msg.JwtMsg;
@ -79,10 +80,12 @@ public final class JwtUtil {
/** /**
* *
* @param tokenType token
* @param account * @param account
* @param userId ID
* @return java.lang.String Token * @return java.lang.String Token
*/ */
public static String sign(String account, String userId) { public static String sign(String tokenType, String account, String userId) {
try { try {
// 帐号加JWT私钥加密 // 帐号加JWT私钥加密
String secret = account + Base64ConvertUtil.decode(ENCRYPT_JWT_KEY); String secret = account + Base64ConvertUtil.decode(ENCRYPT_JWT_KEY);
@ -91,6 +94,7 @@ public final class JwtUtil {
Algorithm algorithm = Algorithm.HMAC256(secret); Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带account帐号信息 // 附带account帐号信息
return JWT.create() return JWT.create()
.withClaim(SignConstants.TYPE, tokenType)
.withClaim(SignConstants.ACCOUNT, account) .withClaim(SignConstants.ACCOUNT, account)
.withClaim(SignConstants.USER_ID, userId) .withClaim(SignConstants.USER_ID, userId)
.withClaim(SignConstants.TIMESTAMP, String.valueOf(System.currentTimeMillis())) .withClaim(SignConstants.TIMESTAMP, String.valueOf(System.currentTimeMillis()))
@ -106,7 +110,7 @@ public final class JwtUtil {
public static void main(String[] args) { public static void main(String[] args) {
String aaaaaa = JwtUtil.sign("aaaaaa","123123"); String aaaaaa = JwtUtil.sign(TokenTypeConstants.TYPE_SYSTEM, "aaaaaa","123123");
boolean verify = JwtUtil.verify(aaaaaa); boolean verify = JwtUtil.verify(aaaaaa);
System.out.println(aaaaaa); System.out.println(aaaaaa);

@ -5,15 +5,20 @@ import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* Spring ApplicationContext, ApplicaitonContext. * Spring ApplicationContext, ApplicationContext.
* *
* 使 Bean使
* @author Zaric * @author Zaric
* @date 2016-5-29 1:25:40 * @date 2016-5-29 1:25:40
*/ */
@Order(-1)
@Component @Component
@Lazy(false) @Lazy(false)
@Slf4j @Slf4j
@ -21,7 +26,6 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
private static ApplicationContext applicationContext = null; private static ApplicationContext applicationContext = null;
/** /**
* applicationContextBean, . * applicationContextBean, .
*/ */
@ -39,6 +43,27 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
return applicationContext.getBean(requiredType); return applicationContext.getBean(requiredType);
} }
/**
* Bean
* @param beanName beanName
* @param bean bean
* @param <T>
*/
public static <T> boolean registerBean(String beanName, T bean) {
assertContextInjected();
boolean ret = false;
ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
if(context != null){
try {
context.getBeanFactory().registerSingleton(beanName, bean);
ret = true;
}catch (Exception e){
log.error(e.getMessage(), e);
}
}
return ret;
}
/** /**
* SpringContextHolderApplicationContextNull. * SpringContextHolderApplicationContextNull.
*/ */
@ -50,12 +75,11 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
} }
/** /**
* ApplicationContext. * ApplicationContext.
*/ */
private static void assertContextInjected() { private static void assertContextInjected() {
Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder."); Validate.validState(applicationContext != null, "applicationContext属性未注入.");
} }
// ================== // ==================
@ -72,8 +96,9 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
* DisposableBean, Context. * DisposableBean, Context.
*/ */
@Override @Override
public void destroy() throws Exception { public void destroy(){
SpringContextHolder.clearHolder(); SpringContextHolder.clearHolder();
} }
} }

@ -29,6 +29,7 @@ import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.constants.CacheConstants; import org.opsli.common.constants.CacheConstants;
import org.opsli.common.constants.SignConstants; import org.opsli.common.constants.SignConstants;
import org.opsli.common.constants.TokenConstants; import org.opsli.common.constants.TokenConstants;
import org.opsli.common.constants.TokenTypeConstants;
import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException; import org.opsli.common.exception.TokenException;
import org.opsli.common.utils.Props; import org.opsli.common.utils.Props;
@ -116,7 +117,7 @@ public class UserTokenUtil {
); );
// 生成 Token 包含 username userId timestamp // 生成 Token 包含 username userId timestamp
String signToken = JwtUtil.sign(user.getUsername(), user.getId()); String signToken = JwtUtil.sign(TokenTypeConstants.TYPE_SYSTEM, user.getUsername(), user.getId());
// 生成MD5 16进制码 用于缩减存储 // 生成MD5 16进制码 用于缩减存储
String signTokenHex = new Md5Hash(signToken).toHex(); String signTokenHex = new Md5Hash(signToken).toHex();

Loading…
Cancel
Save