在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用传统的session方式来解决,我想已经out了,我们是否可以找一个通用的方案,比如用传统cas来实现多系统之间的sso单点登录或使用oauth的第三方登录方案? 今天给大家简单讲解一下使用spring拦截器Interceptor机制、jwt认证方式、redis分布式缓存实现sso单点登录,闲话少说,直接把步骤记录下来分享给大家:
1. 引入jwt的相关jar包,在项目pom.xml中引入:
- <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>2.2.0</version>
- </dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>2.2.0</version>
</dependency>
2. 拦截器配置:
- <mvc:interceptor>
- <mvc:mapping path="${adminPath}/**" />
- <mvc:exclude-mapping path="${adminPath}/rest/login"/>
- <bean class="com.ml.honghu.interceptor.LoginInterceptor" />
- </mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="${adminPath}/**" />
<mvc:exclude-mapping path="${adminPath}/rest/login"/>
<bean class="com.ml.honghu.interceptor.LoginInterceptor" />
</mvc:interceptor>
我这里简单配置了要拦截的url和过滤的url(这个根据自己项目来定)
3. 编写jwt的加密或者解密工具类:
- public class JWT {
- private static final String SECRET = "HONGHUJWT1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
- private static final String EXP = "exp";
- private static final String PAYLOAD = "payload";
- //加密
- public static <T> String sign(T object, long maxAge) {
- try {
- final JWTSigner signer = new JWTSigner(SECRET);
- final Map<String, Object> claims = new HashMap<String, Object>();
- ObjectMapper mapper = new ObjectMapper();
- String jsonString = mapper.writeValueAsString(object);
- claims.put(PAYLOAD, jsonString);
- claims.put(EXP, System.currentTimeMillis() + maxAge);
- return signer.sign(claims);
- } catch(Exception e) {
- return null;
- }
- }
- //解密
- public static<T> T unsign(String jwt, Class<T> classT) {
- final JWTVerifier verifier = new JWTVerifier(SECRET);
- try {
- final Map<String,Object> claims= verifier.verify(jwt);
- if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
- String json = (String)claims.get(PAYLOAD);
- ObjectMapper objectMapper = new ObjectMapper();
- return objectMapper.readValue(json, classT);
- }
- return null;
- } catch (Exception e) {
- return null;
- }
- }
- }
public class JWT {
private static final String SECRET = "HONGHUJWT1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
private static final String EXP = "exp";
private static final String PAYLOAD = "payload";
//加密
public static <T> String sign(T object, long maxAge) {
try {
final JWTSigner signer = new JWTSigner(SECRET);
final Map<String, Object> claims = new HashMap<String, Object>();
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(object);
claims.put(PAYLOAD, jsonString);
claims.put(EXP, System.currentTimeMillis() + maxAge);
return signer.sign(claims);
} catch(Exception e) {
return null;
}
}
//解密
public static<T> T unsign(String jwt, Class<T> classT) {
final JWTVerifier verifier = new JWTVerifier(SECRET);
try {
final Map<String,Object> claims= verifier.verify(jwt);
if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
String json = (String)claims.get(PAYLOAD);