sso增加
This commit is contained in:
parent
011960a2f4
commit
fba20bf30e
@ -14,6 +14,8 @@ categories:
|
|||||||
|
|
||||||
**项目源码:**:[github](https://github.com/FleyX/demo-project/tree/master/1.SSO%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/sso)
|
**项目源码:**:[github](https://github.com/FleyX/demo-project/tree/master/1.SSO%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/sso)
|
||||||
|
|
||||||
|
**特别说明**:本文针对的是新版 spring boot 2.1.3,其 spring data 依赖为 spring-boot-starter-data-redis,且其默认连接池为 lettuce
|
||||||
|
|
||||||
  redis 作为一个高性能的内存数据库,如果不会用就太落伍了,之前在 node.js 中用过 redis,本篇记录如何将 redis 集成到 spring boot 中。提供 redis 操作类,和注解使用 redis 两种方式。主要内容如下:
|
  redis 作为一个高性能的内存数据库,如果不会用就太落伍了,之前在 node.js 中用过 redis,本篇记录如何将 redis 集成到 spring boot 中。提供 redis 操作类,和注解使用 redis 两种方式。主要内容如下:
|
||||||
|
|
||||||
- docker 安装 redis
|
- docker 安装 redis
|
||||||
@ -46,12 +48,28 @@ services:
|
|||||||
|
|
||||||
## 添加 maven 依赖
|
## 添加 maven 依赖
|
||||||
|
|
||||||
  只需添加`spring-boot-starter-data-redis`依赖即可
|
  只需添加`spring-boot-starter-data-redis`依赖即可,并排除 lettuce 依赖,然后引入 jedis 和 jedis 的依赖 commons-pool2
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.lettuce</groupId>
|
||||||
|
<artifactId>lettuce-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -120,7 +138,7 @@ public class RedisConfig extends CachingConfigurerSupport {
|
|||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@Bean
|
@Bean
|
||||||
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
|
public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory factory) {
|
||||||
StringRedisTemplate template = new StringRedisTemplate(factory);
|
StringRedisTemplate template = new StringRedisTemplate(factory);
|
||||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||||
ObjectMapper om = new ObjectMapper();
|
ObjectMapper om = new ObjectMapper();
|
||||||
@ -135,6 +153,29 @@ public class RedisConfig extends CachingConfigurerSupport {
|
|||||||
template.afterPropertiesSet();
|
template.afterPropertiesSet();
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//使用jedis连接池建立jedis连接工厂
|
||||||
|
@Bean
|
||||||
|
public JedisConnectionFactory jedisConnectionFactory() {
|
||||||
|
logger.info("jedisConnectionFactory:初始化了");
|
||||||
|
JedisPoolConfig config = new JedisPoolConfig();
|
||||||
|
config.setMaxIdle(maxIdle);
|
||||||
|
config.setMinIdle(minIdle);
|
||||||
|
config.setMaxWaitMillis(maxWaitMillis);
|
||||||
|
config.setMaxTotal(maxActive);
|
||||||
|
//链接耗尽时是否阻塞,默认true
|
||||||
|
config.setBlockWhenExhausted(true);
|
||||||
|
//是否启用pool的jmx管理功能,默认true
|
||||||
|
config.setJmxEnabled(true);
|
||||||
|
JedisConnectionFactory factory = new JedisConnectionFactory();
|
||||||
|
factory.setPoolConfig(config);
|
||||||
|
factory.setHostName(host);
|
||||||
|
factory.setPort(port);
|
||||||
|
factory.setPassword(password);
|
||||||
|
factory.setDatabase(database);
|
||||||
|
factory.setTimeout(timeout);
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -232,6 +273,7 @@ public class RedisService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
上面的代码执行后将在 redis 中插入两条记录。使用`keys *`将看到如下结果:
|
上面的代码执行后将在 redis 中插入两条记录。使用`keys *`将看到如下结果:
|
||||||
|
|
||||||
![结果](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190311140300.png)
|
![结果](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190311140300.png)
|
||||||
|
@ -32,6 +32,8 @@ categories:
|
|||||||
|
|
||||||
  单点点说就是:一次登录后可免登陆访问其他的可信平台。比如我们登录淘宝网后,再打开天猫首页可以发现已经是登录状态了。SSO 是一种比较流行的服务于企业业务整合的一种解决方案。
|
  单点点说就是:一次登录后可免登陆访问其他的可信平台。比如我们登录淘宝网后,再打开天猫首页可以发现已经是登录状态了。SSO 是一种比较流行的服务于企业业务整合的一种解决方案。
|
||||||
|
|
||||||
|
<!-- readmore -->
|
||||||
|
|
||||||
# 如何实现 SSO
|
# 如何实现 SSO
|
||||||
|
|
||||||
  我们都知道目前的 http 协议是无状态的,也就是第一次请求和第二次请求是完全独立,不相关的,但现实中我们的业务逻辑都是有状态的,这样就引入了 cookie-session 的机制来维护状态,浏览器端存储一个 sessionId,后台存储跟该 sessionId 相关的数据。每次向后台发起请求时都携带此 sessionId 就能维持状态了。然后就有了 cookie,浏览器在发送请求时自动将 cookie 中的数据放到请求中,发给服务端,无需手动设置。
|
  我们都知道目前的 http 协议是无状态的,也就是第一次请求和第二次请求是完全独立,不相关的,但现实中我们的业务逻辑都是有状态的,这样就引入了 cookie-session 的机制来维护状态,浏览器端存储一个 sessionId,后台存储跟该 sessionId 相关的数据。每次向后台发起请求时都携带此 sessionId 就能维持状态了。然后就有了 cookie,浏览器在发送请求时自动将 cookie 中的数据放到请求中,发给服务端,无需手动设置。
|
||||||
@ -117,12 +119,28 @@ SSO说:好嘞,这个地址是合法的可以送jwt过去,这就跳转过
|
|||||||
|
|
||||||
  要注意这里**有个坑**就是:如果另外一个恶意系统 C 安装相同的格式跳转到 SSO,想要获取 jwt,这显然是不应该给它的。所以在回跳回去的时候要判断一下这个回调地址是不是合法的,能不能给 jwt 给它,可以向后台请求判断也可以在 sso 前台直接写死合法的地址。在 demo 是没有这个判断过程的。
|
  要注意这里**有个坑**就是:如果另外一个恶意系统 C 安装相同的格式跳转到 SSO,想要获取 jwt,这显然是不应该给它的。所以在回跳回去的时候要判断一下这个回调地址是不是合法的,能不能给 jwt 给它,可以向后台请求判断也可以在 sso 前台直接写死合法的地址。在 demo 是没有这个判断过程的。
|
||||||
|
|
||||||
|
### 实现业务系统
|
||||||
|
|
||||||
|
  业务系统代码非常简单,主要是用了一个拦截器,拦截 http 请求,提取出 token 向 sso 认证中心验证 token 是否有效,有效放行,否则返回错误给前端。太简单也不贴代码了,到 github 上看看就明白了。
|
||||||
|
|
||||||
# 效果
|
# 效果
|
||||||
|
|
||||||
  上面说了一大串都是原理了,其实这个难也就难在原理部分,代码实现并没有那么复杂。这里就不贴代码了,有需要直接到 github 上看。
|
  上面说了一大串都是原理了,其实这个难也就难在原理部分,代码实现并没有那么复杂。这里就不贴代码了,有需要直接到 github 上看。
|
||||||
|
|
||||||
  这里上个效果图:
|
  这里上几个效果图:
|
||||||
|
|
||||||
|
- 系统 A 首次登陆系统
|
||||||
|
![系统A登陆gif](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E7%B3%BB%E7%BB%9F1%E9%A6%96%E6%AC%A1%E7%99%BB%E5%BD%95.gif)
|
||||||
|
|
||||||
|
可以看到首次登陆是需要跳到 sso 认证中心输入用户名密码进行登陆验证的。登陆成功回跳后接口请求成功。
|
||||||
|
|
||||||
|
- 将 A 的启动端口改为 8082 后再次启动,当作系统 B
|
||||||
|
![系统B登陆gif](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E7%B3%BB%E7%BB%9F2%E7%99%BB%E5%BD%95.gif)
|
||||||
|
|
||||||
|
可以看到这次是无需登陆的,跳到认证中心后就马上跳回了,如果去掉 alert 一般是看不出跳转过程的。
|
||||||
|
|
||||||
|
最后在任意一个系统注销,都会让所有的系统推出登陆。
|
||||||
|
|
||||||
可以看到,在系统 A 登录系统后,系统 B,系统 C 都不再需要输入用户名密码进行登录。如果速度足够快甚至都注意不到调到 SSO 再跳回来的过程。
|
可以看到,在系统 A 登录系统后,系统 B,系统 C 都不再需要输入用户名密码进行登录。如果速度足够快甚至都注意不到调到 SSO 再跳回来的过程。
|
||||||
|
|
||||||
|
  如果有什么问题,可以在下方留言,或者邮件给我。看到都会回复的。
|
||||||
|
BIN
java/web相关/file/系统1首次登录.gif
Normal file
BIN
java/web相关/file/系统1首次登录.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 KiB |
BIN
java/web相关/file/系统2登录.gif
Normal file
BIN
java/web相关/file/系统2登录.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 372 KiB |
Loading…
x
Reference in New Issue
Block a user