# **认证中心* auth-server* auth-server在项目中的位置 ![](https://img.kancloud.cn/43/3a/433a1aa4c85d69f6cf32671c8c6fbf54_1055x734.png) auth-server在项目用的作用 ![](https://box.kancloud.cn/67e561ea8cb7eeab5f62d74f4956a5ab_1064x532.png) ## 认证服务器颁发token核心流程 * /oauth/token?grant_type=password #请求授权token * /oauth/token?grant_type=refresh_token #刷新token * /oauth/check_token #校验token * /oauth/authorize #授权码模式 ## OAUTH 核心处理调用关系 ![](https://box.kancloud.cn/153c89b5bdf9cef58e6bf51005624413_857x461.png) ![](https://box.kancloud.cn/61db9c23a4af534a31da34b273fedb9b_927x531.png) 根据以上流程重写了密码模式,(仅用来学习流程,并没有真正调用) ![](https://box.kancloud.cn/a3683f7beb1c62446e5c517b26696ce1_1751x595.png) 根据以上流程重写了客户端模式(仅用来学习流程,并没有真正调用) ![](https://box.kancloud.cn/65c0a102ac6e419b4695ae0e70c45426_1648x622.png) # 代码结构 认证服务器@EnableAuthorizationServer ![](https://box.kancloud.cn/4327a1d87e4e8e79b06dbaac9ce51b65_1738x607.png) ### AuthorizationServer 认证服务器 AuthorizationServer配置主要是覆写如下的三个方法,分别针对endpoints、clients、security配置。 认证服务同时也是一个资源服务器@EnableResourceServer ### ResourceServer资源服务器配置 ![](https://box.kancloud.cn/0868208721326fb41dffc032a9e18f07_1786x638.png) # auth-server核心表 oauth_client_details --> JdbcClientDetailsService 处理 ![](https://box.kancloud.cn/35a46621f0574c3e6165dda495e416c1_1916x543.png) 为了性能,重构JdbcClientDetailsService,oauth_client_details内容缓存redis中map中 ![](https://box.kancloud.cn/58c840241be2a8062af4f9e50351e71d_1901x844.png) ## 授权码存取策略 授权码缓存redis里面,RedisAuthorizationCodeServices,解决启动多个认证中心授权码问题 ![](https://box.kancloud.cn/da07dc8a5bfb4f0eef8a17213c214d60_1577x654.png) ## 异常通用处理 ![](https://box.kancloud.cn/125f255b3f58f070949623342f963a8e_1776x801.png) ## token票据服务 ![](https://box.kancloud.cn/55cafd11e73a34a76914b4c3ca61ecd2_1771x702.png) ## spring security 自定义用户验证逻辑,取sys_user表 ![](https://box.kancloud.cn/73507e4063206e159c8d088fdc2663dc_1756x668.png) ## 服务间鉴权处理,feigin调用解决token传递问题 ![](https://box.kancloud.cn/b8ef91cfaad8bd86632cf3e46977d68a_1744x686.png) **注意,基于密码模式的方式需要先启动用户中心,通过feigin调用** ![](https://img.kancloud.cn/81/c3/81c3fb329d5cca970c6f6c094bb6cb12_921x556.png) ### feign原理 ![](https://img.kancloud.cn/18/4d/184dd90c81a44e8e46fb34f6cc279600_1211x585.png) ### feign声明 ![](https://box.kancloud.cn/8b0f61a737fa07e771f61d6678b8c65a_1752x726.png) ### 服务调用 ![](https://img.kancloud.cn/39/f8/39f8174b9e577392f2a0ee98211f069c_739x762.png) 启动user-center后测试auth-server的密码模式 ![](https://box.kancloud.cn/e0c1166c9435ca32629ff625343ced1c_1907x944.png) **如果是客户端模式,可以通过swagger测试** 访问认证中心地址http://130.75.131.208:8000/document.html ![](https://box.kancloud.cn/1cbf53f07d1d7d32d9af307225aa066e_1911x904.png) 需要带上token,否则无法访问auth-server的资源 ![](https://box.kancloud.cn/61ba5a06eea91e2a16dab4cb0cc48c92_1174x528.png) ## 权限访问白名单 ### 配置文件 ![](https://box.kancloud.cn/141d93cff0be2656f6310faa239a43cd_1742x673.png) ### 处理类 ![](https://box.kancloud.cn/cf95e9daa6644104fa4c78bf5b96d829_1738x715.png) ### 处理/oauth/authorize 核心类AuthorizationEndpoint ![](https://box.kancloud.cn/d970243ea0fac42f0784d4e7a2895dec_1118x678.png) #### 授权码模式 获取授权码 http://127.0.0.1:8000/oauth/authorize?client_id=owen&redirect_uri=http://127.0.0.1:9997/dashboard/login&state=abc&scope=app&response_type=code 用授权码换token ![](https://box.kancloud.cn/fbfa8acafaf99603a1169d96fbb4d39b_1637x352.png) #### 密码模式 >基本流程就是: 通过ClientDetailsSevice根据ClientId查找对应的Client,由Oauth2RequestFactory生成TokenRequest。检查是否能对应的找到Client,没有就抛出异常。 检查参数,都没问题了最后就调用Ganter的grant方法来生成Token并返回。 >密码模式,即用户提供username,password,clientId,clientSecret,grantType=password等信息,请求/oauth/token,获得access_token,用户即可通过access_token访问资源 访问/oauth/token >对应代码处理流程 此时FilterChainProxy的filter顺序如下。重要的Filter有ClientCredentialsTokenEndpointFilter和BasicAuthenticationFilter,前者从request parameters中抽取client信息,后者从header Authorization Basic XXXX中抽取client信息。 ![](https://box.kancloud.cn/c2da6efd9ac36097796aafc414f93246_1648x843.png) **ClientCredentialsTokenEndpointFilter**会从parameter中抽取client_id,client_secret信息,并进行client的身份验证。 ![](https://box.kancloud.cn/ba4b7bf3c47c4dc5459d4192259e9fc8_833x494.png) ![](https://box.kancloud.cn/9963569242229cd877dd1abb6a522b2a_912x739.png) 访问/oauth/token,都事先验证了client信息,并作为authentication存储在SecurityContextHolder中。传递到TokenEndPoint的principal是client,paramters包含了user的信息和grantType。 ![](https://box.kancloud.cn/62a46e5d5b3feb8ec9ca87f47a679c87_842x490.png) ![](https://box.kancloud.cn/4e1fdb001e75b7d07dfd98d88812099b_961x153.png) ### 处理/oauth/token核心类TokenEndpoint ![](https://box.kancloud.cn/95a0c28a24999a030093a8ca832980d8_1206x532.png) ![](https://box.kancloud.cn/cd129821b9eb34b2145923e976062188_961x683.png) #### security认证原理 >认证的工作是交给AuthenticationManager去做,AuthenticationManager下有多个认证器 AuthenticationProvider 只要其中一个AuthenticationProvider通过认证就算登陆成功,而且在认证器中抛出异常,无法终止认证流程只是算该认证器未通过。 第一个config就算配置了一个AuthenticationManagerBuilder 这个类会生成一个 AuthenticationManager和DaoAuthenticationProvider认证器,认证调用userdetailservice 的loadUserByUsername方法来和你传入的username passworde做比较,password 是通过BCryptPasswordEncoder来做编码后比较的,这样做是为了提高安全性。 ## 通过arthas理解OAUTH密码模式 ![](https://box.kancloud.cn/c166a2246d88ca8cc31b64f7d32a77f6_1563x394.png) ![](https://box.kancloud.cn/b73ab6847f26a3fc8e545ac8d8360ab0_1547x314.png) ![](https://box.kancloud.cn/a2e57bed6f98c43750f8b9d782ceb134_1548x127.png) ## 代码分析 ![](https://img.kancloud.cn/b7/67/b767e7d66c6d0c16c6b78465553cd87a_663x420.png) ### 认证授权效果图 ![](https://box.kancloud.cn/abab658b5e65084b2aead66130dc90f6_1922x950.gif) ### redis token 结构 ``` 排除refresh_token,主要key如下: * auth_to_access:OAuth2Authentication相关信息加密后的值,value为string结构 这个主要是通过OAuth2Authentication来获取OAuth2AccessToken * auth:token值,value为string结构 这个主要用来获取token的OAuth2Authentication,用来获取相应的权限信息 * client_id_to_access:clientId,value为list结构 这个主要是存储了每个clientId申请的OAuth2AccessToken的集合 方便用来审计和应急处理跟clientId相关的token * access:token值,value为string 这个主要是通过token值来获取OAuth2AccessToken * uname_to_access:clientId:userId,value的结构是list 存储OAuth2AccessToken的集合 主要是为了通过clientId,userId来获取OAuth2AccessToken集合,方便用来获取及revoke approval ``` ## 项目pom版本依赖 ![](https://box.kancloud.cn/f61d7429e13a2592f0e3b4721500663a_1768x667.png) 左侧2.0.x版本 左侧1.5.9版本差异 ![](https://box.kancloud.cn/6c10f0c1ae40e1bdbf5ba48f35fb1f4b_920x816.png)