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 ...
随机推荐
- 视图系统CBV 和 response
CBV和FBV FBV(function based view ) CBV(class based view) 1. CBV的定义 # 增加出版社 CBV from django.views imp ...
- Redis中的Stream数据类型作为消息队列的尝试
Redis的List数据类型作为消息队列,已经比较合适了,但存在一些不足,比如只能独立消费,订阅发布又无法支持数据的持久化,相对前两者,Redis Stream作为消息队列的使用更为有优势. 相信 ...
- py+selenium一个可被调用的登录测试脚本【待优化】
大部分系统现在都有登录页面,本文主要尝试写一个登录的测试脚本,及另一个脚本调用它登录测试已登录的页面模块. 目标: 登录脚本:从excel里获取登录的测试数据(包括异常测试)→执行登录脚本→输出是否通 ...
- 和朱晔一起复习Java并发(四):Atomic
本节我们来研究下并发包中的Atomic类型. AtomicXXX和XXXAdder以及XXXAccumulator性能测试 先来一把性能测试,对比一下AtomicLong(1.5出来的).LongAd ...
- UVA-10608 Friends 【并查集】
There is a town with N citizens. It is known that some pairs of people are friends. According to the ...
- Baozi Leetcode Solution 205: Isomorphic Strings
Problem Statement Given two strings s and t, determine if they are isomorphic. Two strings are isomo ...
- 个人永久性免费-Excel催化剂功能第30波-工作表快捷操作(批量创建、命名、排序、工作表目录)
日常使用Excel过程中,最多的操作无外乎单元格和工作表的操作,单元格的操作在前面已经有详细的辅助功能提供,此篇提供工作表相关的操作.这两项的操作若能有提速,日常大量的工作叠加起来真是省下不少时间. ...
- kubernetes的volume的权限设置(属主和属组)
apiVersion: v1kind: Podmetadata: name: hello-worldspec: containers: # specification of the pod's c ...
- 从后端到前端之Vue(四)小试牛刀——真实项目的应用(树、tab、数据列表和分页)
学以致用嘛,学了这么多,在真实项目里面怎么应用呢?带着问题去学习才是最快的学习方式.还是以前的那个项目,前后端分离,现在把前端换成vue的,暂时采用脚本化的方式,然后在尝试工程化的方式. 现在先实现功 ...
- MyEclipse 2016 Stable 1.0破解教程
一.下载所需文件 1. Windows最新版: MyEclipse 2016 Stable 1.0离线安装包(文件大小:1.52GB)--完整安装包,无需在线下载http://pan.baidu.co ...