<>一、单体应用的安全,传统的SSO

某些页面必须登录后才能正常使用,之前了解过单体架构可以通过分布式session或JWT实现传统的sso,又或者通过NG的ip hash算法
(原理是根据用户的IP不变,定位到固定的后端服务器中寻找session)
这些都不是重点!!!!!

<>二、Oauth2协议

个人的理解是这样的:我们可以在Oauth2上实现单点登录
,但是Oauth2不仅仅只能实现单点登录,可以实现授权第三方应用有权限去访问另外的服务提供者上的信息,而不需要将你的登录信息(账号密码)提供给第三方应用,安全。

(一)Oauth2的四种授权模式(只管开发情况下常用的两种)
(1)密码模式:适用于第三方APP是高度受信用的,例如是自己公司开发的app项目。简单来说就是用户在第三方应用
上输入你的账户密码,但是第三方应用不会保存你的账户密码,同时到认证服务器上去验证第三方是否可信,以及你的用户信息

(2)授权码模式(最安全的模式) 与密码模式不同的是,用户不在第三方应用上输入账户密码了,而是通过认证服务器发给你的登录页面上登录,更加安全。

<>三、动手搭建微服务认证中心实现微服务鉴权注意:这张图只是娱乐模式

搭建过程:

1)创建工程,导入oauth2的依赖

2)创建认证服务器
,写一个配置类实现AuthorizationServerConfigurerAdapter类,配置相关信息,并通过@EnableAuthorizationServer来说明该类是认证服务器的配置类,重写Adapter中的configure方法,在这三种configure的方法中配置相关信息,相关信息包括:

a)第三方客户端配置,配置哪些应用可以来访问我们的服务器,在娱乐模式下,我们暂采用内存模式的存储模式
图中的浏览器、订单服务、支付都是属于第三方客户端,需要配置器client_id、密码、权限、token过期时间、支持的模式等等`
关于第三方客户端的配置,在真实开发环境下,将第三方存储模式改为db模式,也就是把第三方客户端进行持久化到数据库中,设置一个表,字段对应了配置信息。
`
代码如下
第三方客户端配置: @Override public void configure(ClientDetailsServiceConfigurer
clients) throws Exception { clients.jdbc(dataSource); }
b)针对用户的配置,第三方客户端带过来的用户名,密码我认证中心怎么去验证正确性?就通过这里的配置去验证。这里直接讲真实开发环境的操作:

真实生产环境下,我们会把token存储到redis中(之前实在内存中),或者使用jwt,这里使用redis存储,然后用户配置这里,标志下token的存储方式,并且通过authenticationManager去验证输入的用户信息是否在DB中有对应。
@Bean public TokenStore tokenStore() { //生产上 需要把token存储到redis中或者使用jwt return
new JdbcTokenStore(dataSource); } // 授权服务器针对用户 颁发的token的存储方式 @Override public
void configure(AuthorizationServerEndpointsConfigurer endpoints) throws
Exception { endpoints .tokenStore(tokenStore())
.authenticationManager(authenticationManager); }
c)针对资源服务器(也就是各种微服务)来校验令牌的配置
对应图中微服务去校验令牌那个过程这里不仅需要校验用户信息,还要验证第三方客户端的信息,如id,密码,权限等在认证中心是否有对应。

3)搭建微服务(资源服务器)

创建一个配置类,加上@EnableResourceServer注解,继承ResourceServerConfigurerAdapter类,重写configure方法
a)标明资源服务器id(这里和认证中心配置中的appid对应) b) 设置该服务在拥有什么权限(read、write)的情况下才能正式访问
3.1)资源服务器的安全配置
在资源服务器拿到令牌,需要验证token的配置

<>四、生产最佳实战(重头戏来了)

改动点:
1、加入网关
2、微服务不再做权限控制(微服务一多了,配置贼麻烦),把权限控制功能放到网关上
3、授权服务器引入rbac模型权限控制

实现过程:
一、创建网关工程
网关功能分析:
1、对于第三方应用来请求的token,不许拦截 2、对带有token的请求对token进行校验token的正确性
3、从tokenInfo获取权限信息,进行权限控制
加入依赖、填写配置

二、编写核心过滤器
(一)认证过滤器,用来认证的,拿到token信息
1)拿到url判断是否需要拦截(比如一些请求获得token的信息就不用拦截了)
2)获取请求头的协议头Authorization中的信息
3)校验token信息
5)网关信息校验(意思是网关这时候也变成第三方客户端了,需要讲网关相应配置信息添加到表中)
6)拿到token可得到token中的各项信息:权限、用户、可访问哪些路径等
7)最终将tokeninfo信息放到request中,以便下一个过滤器使用

(二)鉴权过滤器
1)通过request拿到token信息
2)判断是否需要鉴权、以及token信息是否有效
3)通过token获得权限信息(是一个列表)
4)真正发行

三、授权服务器引入rbac模型权限控制
(1)之前说过authenticationManager的作用是去验证输入的用户信息是否在DB中有对应。这次引入rbac模型,构建用户认证组件去
查询用户信息以及权限,在原本的Service的基础上,通过改造,去访问数据库,返回用户的所有权限。

(2)关于rbac模型
一图便知晓通过查询用户,可以得到其角色信息=>权限信息(例如有和权限、可以访问哪些路径)

<>五、总结

以上过程、比较复杂,自己也是查阅和很多的资料、试错、整了很久(四天的时间)才弄好。

当然也遇到一些小问题:再用admin用户登录的时候,首先获得了该用户对应的token信息,再去通过谷歌Test发起Post请求Order/1的时候,发现老是报错,访问不了,究其原因是因为,数据库中order表中对应的id=1的用户是zhangsan。
也就是说,token与你对应的访问路径不符了,该问题找了一下午,一天白干:)

<>六、补充

针对之前模糊的点:token经过Oauth2
可以设置成该令牌包含的权限,通过rbac模型,也就是通过authenticationManager访问数据库查询到的拥有的权限的信息,(读或写,可访问的路径(order、product服务))、用户信息,token的增强信息。

其实我们每次登录的时候,都会从MemberService中 通过远程的认证中心
(认证中心IP:端口号**/oauth/token)去拿到Token**,也就是会员服务远程调用认证中心服务,并且在网关过滤器中,我们将用户登录的路径/sso以及认证中心的路径/oauth都给放行了,以便能够拿到Token。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信