背景

一直对OAuth 2.0的四种授权模式比较好奇,了解的仅限网上的资料,没有使用代码体验过,这次使用spring-security-oauth2来体验这四种模式的整个过程。

相关代码

pom文件

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.1.4.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.4.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.16.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-security-core</artifactId>
<groupId>org.springframework.security</groupId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>26.0-jre</version>
</dependency>
</dependencies>
配置类

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfigurerAdapter extends AuthorizationServerConfigurerAdapter { @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("clientUser")
.secret("{bcrypt}" + new BCryptPasswordEncoder().encode("123456"))
.authorizedGrantTypes("authorization_code", "implicit", "password", "client_credentials");
} @Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
UserDetails userDetails = User.withUsername("username")
.password("{bcrypt}" + new BCryptPasswordEncoder().encode("password"))
.roles("123")
.build();
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(userDetails);
daoAuthenticationProvider.setUserDetailsService(inMemoryUserDetailsManager);
AuthenticationManager authenticationManager = new ProviderManager(
Lists.<AuthenticationProvider>newArrayList(daoAuthenticationProvider));
endpoints.authenticationManager(authenticationManager);
}
} @Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic();
} @Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager(
SecurityProperties properties) {
SecurityProperties.User user = properties.getUser();
List<String> roles = user.getRoles();
return new InMemoryUserDetailsManager(User.withUsername("user")
.password("{bcrypt}" + new BCryptPasswordEncoder().encode("123456"))
.roles(StringUtils.toStringArray(roles)).build());
}
}
启动类

@SpringBootApplication(
exclude = UserDetailsServiceAutoConfiguration.class
// excludeName = "org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration"
)
public class SpringSecurityStudyApplication { public static void main(String[] args) {
SpringApplication.run(SpringSecurityStudyApplication.class, args);
}
}

授权码模式

第一步 访问GET /oauth/authorize

相关代码在org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint

org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint

请求参数和返回结果如下:

返回结果在浏览器上展示的话,是让用户来勾选是否同意授权的一个页面,还有返回结果的_csrf的值要作为第二步的参数。

curl如下:

curl --location --request GET 'http://127.0.0.1:8090/oauth/authorize?response_type=code&client_id=clientUser&redirect_uri=https://www.baidu.com/&scope=scope' \
--header 'Authorization: Basic dXNlcjoxMjM0NTY=' \
--header 'Cookie: JSESSIONID=AB254815273DB81F1F3BAF74E94DAAB6'

第二步 访问POST /oauth/authorize

相关代码在org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint

crul如下:

curl --location --request POST 'http://127.0.0.1:8090/oauth/authorize?user_oauth_approval=true&scope.scope=true&_csrf=a95516db-6ce2-4033-9b81-1060b6c4d829' \
--header 'Cookie: JSESSIONID=73E846796ACB7818E09B93AC4CFD320D'

_csrf 要使用第一步返回的结果,在返回头的Location里可以得到授权码

第一个参数必须要有,因为:

<input name="user_oauth_approval" value="true" type="hidden"/>

@RequestMapping(value = "/oauth/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, ?> model, SessionStatus sessionStatus, Principal principal) {
} public static final String USER_OAUTH_APPROVAL = "user_oauth_approval";

第二个参数是用户是否同意授权

第三步 访问POST /oauth/token

相关代码在org.springframework.security.oauth2.provider.endpoint.TokenEndpoint

code 使用第二步的返回结果

crul如下:

curl --location --request POST 'http://127.0.0.1:8090/oauth/token' \
--header 'Authorization: Basic Y2xpZW50VXNlcjoxMjM0NTY=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: JSESSIONID=5D41BF01BC875BDF266D3C2178537F21' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=1pakV1' \
--data-urlencode 'redirect_uri=https://www.baidu.com/' \
--data-urlencode 'client_id=clientUser' \
--data-urlencode 'scope=scope'

简化模式

第一步 访问GET /oauth/authorize

crul如下:

curl --location --request GET 'http://127.0.0.1:8090/oauth/authorize?response_type=token&client_id=clientUser&redirect_uri=https://www.baidu.com/&scope=scope' \
--header 'Authorization: Basic dXNlcjoxMjM0NTY=' \
--header 'Cookie: JSESSIONID=6AD429F6CF30C10C0E9F1A35EC78A790'

第二步 访问POST /oauth/authorize



crul如下:

curl --location --request POST 'http://127.0.0.1:8090/oauth/authorize?user_oauth_approval=true&scope.scope=true&_csrf=1ba6be5e-845f-47f2-9680-db613adc47c7' \
--header 'Cookie: JSESSIONID=6AD429F6CF30C10C0E9F1A35EC78A790'

密码模式

直接 访问POST /oauth/token

curl如下:

curl --location --request POST 'http://127.0.0.1:8090/oauth/token' \
--header 'Authorization: Basic Y2xpZW50VXNlcjoxMjM0NTY=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: JSESSIONID=7E149951AB7D3C03E31E21450754DAAE' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=username' \
--data-urlencode 'scope=scope' \
--data-urlencode 'password=password'

客户端模式

直接 访问POST /oauth/token

curl如下:

curl --location --request POST 'http://127.0.0.1:8090/oauth/token' \
--header 'Authorization: Basic Y2xpZW50VXNlcjoxMjM0NTY=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: JSESSIONID=7E149951AB7D3C03E31E21450754DAAE' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=scope'

参考

理解OAuth 2.0 - 阮一峰

使用 spring-security-oauth2 体验 OAuth 2.0 的四种授权模式的更多相关文章

  1. OAuth 2.0 的四种授权模式

    RFC 6749 OAuth 2.0 的标准是 RFC 6749 文件.该文件先解释了 OAuth 是什么. OAuth 引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者.......资源 ...

  2. OAuth2.0的四种授权模式

    1.什么是OAuth2 OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OA ...

  3. OAuth2.0的四种授权模式(转)

    1. OAuth2简易实战(一)-四种模式 1.1. 隐式授权模式(Implicit Grant) 第一步:用户访问页面时,重定向到认证服务器. 第二步:认证服务器给用户一个认证页面,等待用户授权. ...

  4. OAuth 2.0 的四种方式

    上一篇文章介绍了 OAuth 2.0 是一种授权机制,主要用来颁发令牌(token).本文接着介绍颁发令牌的实务操作. 下面我假定,你已经理解了 OAuth 2.0 的含义和设计思想,否则请先阅读这个 ...

  5. OAuth2.0 四种授权模式

    OAuth2.0简单笔记(四种授权模式) 金天:坚持写东西,不是一件容易的事,换句话说其实坚持本身都不是一件容易的事.如果学习有捷径,那就是不断实践,不断积累.写笔记,其实是给自己看的,是体现积累的一 ...

  6. OAuth2.0学习(2-1)Spring Security OAuth2.0 开发指南

    开发指南:http://www.cnblogs.com/xingxueliao/p/5911292.html Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际 ...

  7. Spring Security OAuth2.0认证授权一:框架搭建和认证测试

    一.OAuth2.0介绍 OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不 需要将用户名和密码提供给第三方应用或分享他们数据的所有内容. 1.s ...

  8. Spring Security OAuth2 开发指南

    官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...

  9. Spring Security OAuth2 开发指南(非最新版本)

    请注意哈,本文翻译的时候,官网的的版本和本文翻译的时候是一一对应的. 但是官网已经更新文档和概念了,因此和本文翻译的就不在是同一个范围了. 因此我已经将标题修改为(非最新版本),各位老铁直接看官网就可 ...

随机推荐

  1. 领域驱动模型DDD(三)——使用Saga管理事务

    前言 虽然一直说想写一篇关于Saga模式,在多次尝试后不得不承认这玩意儿的仿制代码真不是我一个菜鸟就能完成的,所以还是妥协般地引用现成的Eventuate Tram Saga框架(虽然我对它一直很反感 ...

  2. Day 003:PAT练习--1041 考试座位号 (15 分)

    题目要求: 我写的代码如下: //考试座位号 #include<iostream> #include<algorithm> #include<string> usi ...

  3. 数据结构篇(1) ts实现栈的基本操作和解决相关问题

    interface Stack { _items: any push(element: any): void pop(): any top(): any size(): any isEmpty(): ...

  4. IOC容器--1.12. 基于 Java 的容器配置

    用Java的方式配置Spring ,不使用Spring的XML配置,全权交给Java来做 JavaConfig是Spring的一个子项目,在Sring 4  之后成为核心功能 这种纯Java的配置方式 ...

  5. 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘

    前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...

  6. 老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(三)

    老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(三) 前言 上一篇文章老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(二)从三个问题导入,分析了Spring ...

  7. 一个程序的自我修养「GitHub 热点速览 v.22.19」

    一个程序要诞生涉及前后端技术,比如,你可以用可视化网页搭建工具 tmagic-editor 完成前端部分,而后端部分的数据库以及数据处理可能就要用到 jsonhero-web 和 directus.知 ...

  8. Git移除远程已经上传的文件

    我们常常会将本地的一些秘钥文件不小心推送到远端,此时仅仅修改本地的.gitignore文件,然后再提交推送是不能将远端的此文件删除的. 此时可以用下面的命令 git rm --cached filen ...

  9. 2020级cpp机考模拟题A卷-#题解2

    这部分的题目都有一定难度,有兴趣的同学可以钻研一下. 特此感谢来自BDT20030  tql的支持. 2:素数的和-2 题意: 计算不大于m的素数之和.(多么容易理解的题目啊,对吧) 题解(有点复杂的 ...

  10. 【Unity Shader学习笔记】Unity基础纹理-渐变纹理

    纹理可以用来存储任何表面属性. 可以通过使用渐变纹理来实现插画风格的渲染效果. 这项技术是由Valve公司提出的.Valve使用它来渲染游戏中具有插画风格的角色. 我们使用半兰伯特模型计算漫反射. 因 ...