Oauth2认证模式之授权码模式实现
Oauth2认证模式之授权码模式(authorization code)
本示例实现了Oauth2之授权码模式,授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。
阅读本示例之前,你需要先有以下两点基础:
- 需要对spring security有一定的配置使用经验,用户认证这一块,spring security oauth2建立在spring security的基础之上
- oauth2开放授权标准基础,可以稳步到OAuth2 详解,浏览下授权码模式,理解下基本概念
概述
实现 oauth2,可以简易的分为三个步骤
- 配置资源服务器
- 配置认证服务器
- 配置spring security
代码实现
1.pom.xml添加maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
2.配置资源服务器
public class ResourceServerConfig {
private static final String RESOURCE_ID = "account";
@Configuration
@EnableResourceServer()
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(true);
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.requestMatchers()
// 保险起见,防止被主过滤器链路拦截
.antMatchers("/account/**").and()
.authorizeRequests().anyRequest().authenticated()
.and()
.authorizeRequests()
.antMatchers("/account/info/**").access("#oauth2.hasScope('get_user_info')")
.antMatchers("/account/child/**").access("#oauth2.hasScope('get_childlist')");
}
}
}
3.配置认证服务器
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client1")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT")
.scopes("get_user_info", "get_childlist")
.secret("secret")
.redirectUris("http://localhost:8081/client/account/redirect")
.autoApprove(true)
.autoApprove("get_user_info");
}
4.配置spring security
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
protected UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
// 创建两个内存用户
manager.createUser(User.withUsername("admin").password("123456").authorities("USER").build());
manager.createUser(User.withUsername("lin").password("123456").authorities("USER").build());
return manager;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
/**
* 密码生成器(默认为bcrypt模式)
*
* @return
*/
// @Bean
// PasswordEncoder passwordEncoder() {
// return PasswordEncoderFactories.createDelegatingPasswordEncoder();
// }
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.
requestMatchers()
// 必须登录过的用户才可以进行 oauth2 的授权码申请
.antMatchers("/", "/home", "/login", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.and()
.httpBasic()
.disable()
.exceptionHandling()
.accessDeniedPage("/login?authorization_error=true")
.and()
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
.disable();
}
}
使用介绍
- 找到AuthResServerApplication.java运行server服务,默认端口:8080
- 找到ClientApplication.java运行client客户端,端口:8081
1.尝试直接访问用户信息
http://localhost:8080/account/info/testAccount1/
返回未授权错误
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
2.尝试获取授权码
结果被主过滤器拦截,302 跳转到登录页,因为 /oauth/authorize 端点是受保护的端点,必须登录的用户才能申请 code。
3.输入用户名和密码
输入用户名和密码 admin 123456
如上用户名密码是交给 SpringSecurity 的主过滤器用来认证的
4.登录成功后,真正进行授权码的申请
oauth/authorize 认证成功,会根据 redirect_uri 执行 302 重定向,并且带上生成的 code,注意重定向到的是 8001 端口,这个时候已经是另外一个应用了。
localhost:8081/client/account/redirect?code=xxxx
代码中封装了一个 http 请求,使得 client1 使用 restTemplate 向 server 发送 token 的申请,当然是使用 code 来申请的,并最终成功获取到 access_token
{
access_token: "59a25558-f714-4ca8-aa87-c36f93c120bf",
token_type: "bearer",
refresh_token: "92436849-7ef7-4923-8270-5a2c9b464556",
expires_in: 43199,
scope: "get_user_info get_childlist"
}
5.携带 access_token 访问account信息
http://localhost:8080/account/info/testAccount1?access_token=59a25558-f714-4ca8-aa87-c36f93c120bf
6.正常返回信息
{
name: "testAccount1",
nickName: "测试用户1",
remark: "备注1",
childAccount: [
{
name: "testChild1_0",
nickName: "测试子用户1_0",
remark: "0",
childAccount: null
},
{
name: "testChild1_1",
nickName: "测试子用户1_1",
remark: "1",
childAccount: null
},
{
name: "testChild1_2",
nickName: "测试子用户1_2",
remark: "2",
childAccount: null
},
{
name: "testChild1_3",
nickName: "测试子用户1_3",
remark: "3",
childAccount: null
},
{
name: "testChild1_4",
nickName: "测试子用户1_4",
remark: "4",
childAccount: null
},
{
name: "testChild1_5",
nickName: "测试子用户1_5",
remark: "5",
childAccount: null
},
{
name: "testChild1_6",
nickName: "测试子用户1_6",
remark: "6",
childAccount: null
},
{
name: "testChild1_7",
nickName: "测试子用户1_7",
remark: "7",
childAccount: null
},
{
name: "testChild1_8",
nickName: "测试子用户1_8",
remark: "8",
childAccount: null
},
{
name: "testChild1_9",
nickName: "测试子用户1_9",
remark: "9",
childAccount: null
}
]
}
资料
Oauth2认证模式之授权码模式实现的更多相关文章
- IdentityServer4实现OAuth2.0四种模式之授权码模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式 授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token ...
- Owin + WebApi + OAuth2 搭建授权模式(授权码模式 Part I)
绪 最近想要整理自己代码封装成库,也十分想把自己的设计思路贴出来让大家指正,奈何时间真的不随人意. 想要使用 OWIN 做中间件服务,该服务中包含 管线.授权 两部分.于是决定使用 webapi .O ...
- Oauth2.0认证---授权码模式
目录: 1.功能描述 2.客户端的授权模式 3.授权模式认证流程 4.代码实现 1.功能描述 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(au ...
- oauth2.0授权码模式详解
授权码模式原理 授权码模式(authorization code)是功能最完整.流程最严密的授权模式.它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动. 它 ...
- 微信授权就是这个原理,Spring Cloud OAuth2 授权码模式
上一篇文章Spring Cloud OAuth2 实现单点登录介绍了使用 password 模式进行身份认证和单点登录.本篇介绍 Spring Cloud OAuth2 的另外一种授权模式-授权码模式 ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_06-SpringSecurityOauth2研究-Oauth2授权码模式-申请令牌
3.3 Oauth2授权码模式 3.3.1 Oauth2授权模式 Oauth2有以下授权模式: 授权码模式(Authorization Code) 隐式授权模式(Implicit) 密码模式(Reso ...
- IdentityServer4系列 | 授权码模式
一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...
- 基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】
之前已经简单实现了OAUTH2的授权码模式(Authorization Code),但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了.官方推 ...
- 学习Spring Security OAuth认证(一)-授权码模式
一.环境 spring boot+spring security+idea+maven+mybatis 主要是spring security 二.依赖 <dependency> <g ...
随机推荐
- c# 图文添加文字斜水印
项目中有个添加水印的需求,需要给图片铺满斜水印. 网上搜了半天全是添加在图片上.下.左.右的案例. 于是按照网上的某一段案例自己修改了一些代码. Bitmap bitmap = new Bitmap( ...
- 02(e)多元无约束优化问题- 梯度的两种求解方法以及有约束转化为无约束问题
2.1 求解梯度的两种方法 以$f(x,y)={{x}^{2}}+{{y}^{3}}$为例,很容易得到: $\nabla f=\left[ \begin{aligned}& \frac{\pa ...
- C++学习书籍推荐《C++ Primer 第五版 (英文)》下载
百度云及其他网盘下载地址:点我 编辑推荐 <C++ Primer(英文版)(第5版)>是全球最畅销的C++图书.这本久负盛名的C++经典教程,时隔八年之久,终迎来的重大升级.除令全球无数程 ...
- Bzoj 1229: [USACO2008 Nov]toy 玩具 题解 三分+贪心
1229: [USACO2008 Nov]toy 玩具 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 338 Solved: 136[Submit] ...
- python 2.7 - 3.5 升级之路 (二) : 语法与类库升级
背景 在上一篇博文中,我们为升级python 2 -> 3已经做了一些准备.在这篇中,我们将针对语法与类库这两个方面进行讨论. 关于语法 1. print 在python3中, print 已经 ...
- Mysql 时间相关
-- 当前时间SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP(), LOCALTIME(), LOCALTIMESTAMP();SELECT CURDATE(), ...
- 小记---idea springboot 报错没有get或者set方法
给idea 安装一个插件即可
- kubernetes的volume的权限设置(属主和属组)
apiVersion: v1kind: Podmetadata: name: hello-worldspec: containers: # specification of the pod's c ...
- Java EE.JSP.脚本
脚本是<%与%>之间Java语言编写的代码块. 1.输出表达式 <%=表达式%>输出表达式的计算结果. 2.注释 1)输出到客户端的注释:<!-comment-> ...
- C#中Tuple的使用
鉴于MSDN上面的机器翻译实在太烂,还是自己翻译吧,虽然麻烦了点(-_-). 定义:元组是具有 特定数量和序列 的元素 的数据结构 (注意断句哈!) 元组通常有四种使用方式︰ 一.表示一组数据 例如 ...