搭建微服务认证中心实现微服务鉴权

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

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

二、Oauth2协议

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

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

搭建微服务认证中心实现微服务鉴权_第1张图片(2)授权码模式(最安全的模式) 与密码模式不同的是,用户不在第三方应用上输入账户密码了,而是通过认证服务器发给你的登录页面上登录,更加安全。搭建微服务认证中心实现微服务鉴权_第2张图片

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

搭建过程:

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的配置

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

搭建微服务认证中心实现微服务鉴权_第4张图片改动点:
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模型
搭建微服务认证中心实现微服务鉴权_第5张图片一图便知晓通过查询用户,可以得到其角色信息=>权限信息(例如有和权限、可以访问哪些路径)

五、总结

以上过程、比较复杂,自己也是查阅和很多的资料、试错、整了很久(四天的时间)才弄好。
当然也遇到一些小问题:再用admin用户登录的时候,首先获得了该用户对应的token信息,再去通过谷歌Test发起Post请求Order/1的时候,发现老是报错,访问不了,究其原因是因为,数据库中order表中对应的id=1的用户是zhangsan。
也就是说,token与你对应的访问路径不符了,该问题找了一下午,一天白干:)

六、补充

针对之前模糊的点:token经过Oauth2 可以设置成该令牌包含的权限,通过rbac模型,也就是通过authenticationManager访问数据库查询到的拥有的权限的信息,(读或写,可访问的路径(order、product服务))、用户信息,token的增强信息。搭建微服务认证中心实现微服务鉴权_第6张图片

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

搭建微服务认证中心实现微服务鉴权_第7张图片

你可能感兴趣的:(高并发场景解决思路,oauth2,微服务)