SpringCloud-OAuth2(二):实战篇
如果不了解Oauth2 是什么、工作流程的可以看我上一篇文章:
SpringCloud-OAuth2(一):基础篇
这篇讲的内容是:Oauth2在SpringBoot/SpringCloud中的实战。
SpringBoot版本:2.2.5.Release
SpringCloud版本:Hoxton.SR9
JDK版本:1.8
1:POM配置
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
<dependency>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<groupId>org.springframework.cloud</groupId>
</dependency>
<!--使用redis存放token-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--密码加密解密依赖包-->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>
2:关键配置
2.1:认证服务配置-WebAuthorizationConfig
@Configuration
@EnableAuthorizationServer
public class WebAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final UserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
private final TokenStore tokenStore;
private final AuthorizationCodeServices authorizationCodeServices;
private final AuthTokenExceptionHandler authTokenExceptionHandler;
public WebAuthorizationConfig(AuthenticationManager authenticationManager,
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder,
TokenStore tokenStore,
AuthorizationCodeServices authorizationCodeServices,
AuthTokenExceptionHandler authTokenExceptionHandler) {
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.tokenStore = tokenStore;
this.authorizationCodeServices = authorizationCodeServices;
this.authTokenExceptionHandler = authTokenExceptionHandler;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = PasswordHelper.encryptPassword(Oauth2ClientUserEnums.ADMIN.getClientSecret());
clients.inMemory()
.withClient(Oauth2ClientUserEnums.ADMIN.getClientId())
.secret(secret)
.scopes("all", "test")
.resourceIds("admin")
// autoApprove 可跳过授权页直接返回code
.autoApprove("all")
.redirectUris("http://www.baidu.com")
//客户端认证所支持的授权类型 1:客户端凭证 2:账号密码 3:授权码 4:token刷新 5:简易模式
.authorizedGrantTypes(CLIENT_CREDENTIALS, PASSWORD, REFRESH_TOKEN, AUTHORIZATION_CODE, IMPLICIT)
//用户角色
.authorities("admin")
//允许自动授权
.autoApprove(false)
//token 过期时间
.accessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(12))
//refresh_token 过期时间
.refreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30))
;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.passwordEncoder(passwordEncoder) //设置密码编辑器
.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()") //开启 /oauth/token_key 的访问权限控制
.checkTokenAccess("permitAll()") //开启 /oauth/check_token 验证端口认证权限访问
;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 配置授权服务器端点的属性
endpoints.authenticationManager(authenticationManager) //认证管理器
.tokenStore(tokenStore)
.authorizationCodeServices(authorizationCodeServices)
.userDetailsService(userDetailsService)
.exceptionTranslator(authTokenExceptionHandler);
}
}
注解:@EnableAuthorizationServer表明当前服务是认证服务。
介绍一下几个基础组件
①:authenticationManager
认证管理器,对客户端凭证、用户进行认证的地方。
②:tokenStore
存放token的地方,默认是存放在Inmemory(内存)中的。
③:authorizationCodeServices
code生成服务,使用默认的即可。
④:userDetailsService
用户详情服务,可重写实现,用户信息从数据库中加载。
⑤:authTokenExceptionHandler
自定义的 token 鉴别失败异常处理器。
⑥:authClientExceptionHandler
自定义的 客户端凭证 鉴别失败异常处理器。
2.2:资源服务配置-WebResourceConfig
@Configuration
@EnableResourceServer
public class WebResourceConfig extends ResourceServerConfigurerAdapter {
private final AuthClientExceptionHandler authClientExceptionHandler;
public WebResourceConfig(AuthClientExceptionHandler authClientExceptionHandler) {
this.authClientExceptionHandler = authClientExceptionHandler;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("admin").stateless(true).authenticationEntryPoint(authClientExceptionHandler);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// 资源链路
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().formLogin().permitAll()
// 登录放通
.and()
.authorizeRequests()
.antMatchers("/oauth/**", "/favicon.ico")
//.authenticated()
.permitAll()
// 其他请求都需认证
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
// 跨域
.and()
.cors()
// 关闭跨站请求防护
.and()
.csrf()
.disable();
}
}
注解:@EnableResourceServer表明当前服务是认证服务。
笔记:
为什么要放开 /favicon.ico 的访问权限?因为在进行授权码模式的时候,一直无法跳转到我定义的redirect_uri 地址中去。
使用 logging.level.org.springframework.security=debug 发现会访问 /favicon.ico ,然后报错,再然后就是调到登录页去了。
因此 /favicon.ico 放开之后,认证正常,成功调到redirect_uri 地址并返回了code。(这是OAuth2的小坑吗?)
2.3:安全配置-WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
public WebSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder); //为认证管理器配置passwordEncoder,无论客户端凭证密码还是用户密码都通过passwordEncoder进行密码匹配
}
@Bean
@Override
protected UserDetailsService userDetailsService() {
return new VipUserDetailService();
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
详细配置可以翻阅我的GitHub:GitHub地址
3:认证授权演示
3.1:授权码模式
注意!!!一定要配置redirect_uri,并且一定要允许表单登录!!!
以下是步骤:
①:浏览器输入以下链接地址,会重定向到登录页
http://localhost:8123/oauth/authorize?client_id=admin&client_secret=admin&response_type=code&redirect_uri=http://www.baidu.com&scope=test

②:输入配置的用户名密码,回调到授权页

如果我们配置的scope是autoApprove的,即可跳过这步,直接到第③步,拿到code。
③:选择 Approve,点击Authorize 即可调到redirect_uri地址

④:拿code 换 token
我的请求地址:127.0.0.1:8123/oauth/token?grant_type=authorization_code&code=h35Fh1&redirect_uri=http://www.baidu.com
需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.2:用户密码模式
我的请求地址:127.0.0.1:8123/oauth/token?grant_type=password&username=found&password=123456
需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.3:客户端凭证模式
我的请求地址:127.0.0.1:8123/oauth/token?grant_type=client_credentials
需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.4:简易模式
浏览器输入以下地址即可拿到token:
http://localhost:8123/oauth/authorize?client_id=admin&client_secret=admin&response_type=token&redirect_uri=http://www.baidu.com

3.5:token 刷新
我的请求地址:127.0.0.1:8123/oauth/token?grant_type=refresh_token&refresh_token=dde5f388-4ad7-4781-a1b7-aaafb3c34b10
refresh_token是服务器颁发给客户端的,作用就是在一定时间内,让用户不用重新登录。
需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

4:从第三方登录让你理解什么是授权码模式
个人认为做第三方登录是当前比较流行的做法。
4.1:流程
①:比如我们现在登录processOn,就可以选择第三方登录。

②:点击QQ登录后会调到这个页面↓↓↓↓↓↓↓↓↓↓↓↓

③:这个client_id 应该就是processOn 官方申请的第三方客户端凭证了。
选择账号密码登录,输入账号密码之后就可以拿到token,(我手速快截了个图)

④:可以看到返回了access_token、过期时间。
随后processOn既发起请求进行登录操作,登录成功进入用户首页,失败则重定向到登录页。


4.2:uml图

可以看到不需要用户进行Authorize操作即可拿到token了,说明QQ第三方认证中心设置的scope=all是autoApprove的。
总结 :
学习总要从身边找例子,这样才能更好的理解。
SpringCloud-OAuth2(二):实战篇的更多相关文章
- OAuth2简易实战(二)-模拟客户端调用
1. OAuth2简易实战(二) 1.1. 目标 模拟客户端获取第三方授权,并调用第三方接口 1.2. 代码 1.2.1. 核心流程 逻辑就是从数据库读取用户信息,封装成UserDetails对象,该 ...
- 二、Redis基本操作——String(实战篇)
小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...
- 工作经常使用的SQL整理,实战篇(二)
原文:工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...
- SpringCloud学习(二):微服务入门实战项目搭建
一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...
- ActiveMQ实战篇之ActiveMQ实现request/reply模型(二)
ActiveMQ实战篇之ActiveMQ实现request/reply模型(二)
- 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构
本篇承接上篇内容,如果你不小心点击进来,建议重新从第一篇开始完整阅读. 构建NetCore应用框架之实战篇索引 一.BitAdminCore框架简介 从前篇论述我们知道,我们接下来将要去做一个管理系统 ...
- [SQL SERVER系列]工作经常使用的SQL整理,实战篇(二)[原创]
工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实战篇(三) 接着上一篇“工作经常使用的SQL整 ...
- Ceres Solver: 高效的非线性优化库(二)实战篇
Ceres Solver: 高效的非线性优化库(二)实战篇 接上篇: Ceres Solver: 高效的非线性优化库(一) 如何求导 Ceres Solver提供了一种自动求导的方案,上一篇我们已经看 ...
- 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序
如何在Visual Studio 2017中使用C# 7+语法 前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...
随机推荐
- 如何通过CRM解决公司业绩下滑的问题
大部分公司都需要新客户的支持来维持市场和实现预期的目标.尽管销售部门一直在努力,但这种努力还是无法阻止业绩下降. 想要做到销售增长,不仅要取决企业的进步,还需要改掉使业绩下降的问题.小Z将从四个方面对 ...
- input type
input的type有: text 文本输入 password密码输入 file选择文件 radio单选按钮 checkbox复选按钮 submit对应form的action按钮 button 普通按 ...
- [bug] idea编译后没有xml文件
原因 在maven中build 参考 https://www.cnblogs.com/lewskay/p/6422464.html https://blog.csdn.net/lovequanquqn ...
- [Qt] 信号和槽
信号与槽:是一种对象间的通信机制 观察者模式:当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目的的,类似广播.如果有对象对这个信号感兴趣,它就 ...
- systemctl服务------字符和图像界面切换systemctl set-default multi-user.target systemctl isolate multi-user.target #当前立即进入字符模式 [root@room4pc09 桌面]# systemctl isolate graphical.target #当前立即进入图形模式
查看服务运行状态 [root@room4pc09 桌面]# systemctl status crond #查看服务运行状态 ● crond.service - Command Scheduler L ...
- Linux学习之路-Linux-at及cron命令【7】---20171215
Linux学习之路-Linux-at及cron命令[7]---20171215 DannyExia000人评论986人阅读2017-12-24 17:28:03 ntpdate 命令 [root@ ...
- 运维电子书PDF汇总
SRE Google运维解密 Nginx Cookbook 2019 链接:https://pan.baidu.com/s/1Sob4JSjNKe77wMACmDZHig 提取码:rhc6
- mysql基础之日志管理(查询日志、慢查询日志、错误日志、二进制日志、中继日志、事务日志)
日志文件记录了MySQL数据库的各种类型的活动,MySQL数据库中常见的日志文件有 查询日志,慢查询日志,错误日志,二进制日志,中继日志 ,事务日志. 修改配置或者想要使配置永久生效需将内容写入配置文 ...
- mysql基础之mariadb概念
一.数据库介绍 什么是数据库(Database)? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库 ...
- CentOS7安装开发工具套件时报错解决方案
操作系统:CentOS 7.2 执行安装命令时显示以下信息: [root@DEV-CMDB-DB02 ~]# yum -y groupinstall "Development Tools&q ...