spring-cloud-oauth2实现用户认证及单点登录
作者 | 工程师小哥
来源 | urlify.cn/mI3qEz
需求在微服务架构中 , 我们有很多业务模块 , 每个模块都需要有用户认证 , 权限校验 。 有时候也会接入来自第三方厂商的应用 。 要求是只登录一次 , 即可在各个服务的授权范围内进行操作 。 看到这个需求 , 立马就想到了这不就是单点登录吗?于是基于这样的需求 , 作者使用spring-cloud-oauth2去简单的实现了下用户认证和单点登录 。
相关介绍OAuth2OAuth2是一个关于授权的网络标准 , 他定制了设计思路和执行流程 。 OAuth2一共有四种授权模式:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password)和客户端模式(client credentials) 。 数据的所有者告诉系统同意授权第三方应用进入系统 , 获取这些数据 。 于是数据所有者生产了一个短时间内有效的授权码(token)给第三方应用 , 用来代替密码 , 供第三方使用 。 具体流程请看下图 , 具体的OAuth2介绍 , 可以参考这篇文章 , 写的很详细 。 ()
文章插图
Token令牌(token)和密码(password)的作用是一样的 , 都可以进入系统获取资源 , 但是也有几点不同:
- 令牌是短期的 , 到期会自动失效 , 用户无法修改 。 密码是长期的 , 用户可以修改 , 如果不修改 , 就不会发生变化 。
- 令牌可以被数据所有者撤销 , 令牌会立即失效 。 密码一般不允许其他人撤销 , 只能被操作权限更高的人或者本人修改/重制 。
- 令牌是有权限范围的 , 会被数据所有者授予 。
在微服务架构中 , 我们的一个应用可能会有很多个服务运行 , 协调来处理实际的业务 。 这就需要用到单点登录的技术 , 来统一认证调取接口的是哪个用户 。 那总不能请求一次 , 就认证一次 , 这么做肯定是不行的 。 那么就需要在认证完用户之后 , 给这个用户授权 , 然后发一个令牌(token) , 有效期内用户请求资源时 , 就只需要带上这个标识自己身份的token即可 。
架构说明认证中心:oauth2-oauth-server,OAuth2的服务端 , 主要完成用户Token的生成、刷新、验证等 。
微服务:mzh-etl,微服务之一 , 接收到请求之后回到认证中心(oauth2-oauth-server)去验证 。
代码实现使用到的框架是java基础的spring boot 和spring-cloud-oauth2
认证中心:1、引入需要的maven包
org.springframework.boot spring-boot-starter-weborg.springframework.cloud spring-cloud-starter-oauth2org.springframework.boot spring-boot-starter-data-redisorg.springframework.boot spring-boot-starter-actuator因为spring-cloud-starter-oauth2中包含了spring-cloud-starter-security , 所以就不用再单独引入了 , 引入redis包是为了使用redis来存储token 。2、配置application.yml这里主要用到的是redis的配置 , mysql数据库的配置暂时没有用到 。
spring:application:name: oauth-serverdatasource:url: jdbc:mysql://localhost:3306/mzh_oauth?useSSL=false --tt-darkmode-bgcolor: #1C1C1C;">WebSecurityConfigurerAdapter
/** * @Author mzh * @Date 2020/10/24 */@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate CustomUserDetailsService customUserDetailsService;/*** 修改密码的加密方式* @return*/@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception{return super.authenticationManagerBean();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception{// 如果使用BCryptPasswordEncoder , 这里就必须指定密码的加密类auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/oauth/**").permitAll();}}BCryptPasswordEncoder是一个不可逆的密码加密类 , AuthenticationManager是OAuth2的password必须指定的授权管理Bean 。
CustomUserDetailsService这个类是被注入进来的 , 熟悉spring security的同学应该知道 , spring security有一个自己的UserdetailsService用于权限校验时获取用户信息 , 但是很多时候不符合我们的业务场景 , 就需要重现实现这个类 。
4、实现CustomUserDetailsServiceUserDetailsService这个类的核心方法就是loadUserByUsername()方法 , 他接收一个用户名 , 返回一个UserDetails对象 。
- 看不上|为什么还有用户看不上华为Mate40系列来看看内行人怎么说
- 闲鱼|电诉宝:“闲鱼”网络欺诈成用户投诉热点 Q3获“不建议下单”评级
- 用户|5G信号有猫腻,又在考验用户的智商?
- 垫底|5G用户突破2亿:联通垫底,电信月增700万,中国移动有多少?
- iPhone|接近8千万!苹果被罚款了!中国iPhone用户这次真的该生气了!
- 苹果|iPhone13迎来变化!或回归指纹解锁,这几点备受用户喜爱
- 屏幕|苹果iPhone12屏幕不仅发白,还绿的你发慌,用户:环保绿
- 与用户|掌握好这4个步骤,实现了规模性的盈利
- 视频|短视频如何在前3秒吸引用户眼球?
- 用户|把更多主动权交还给用户,市面上敢这么做的或许只有OriginOS了
