详解使用Spring Security OAuth 实现OAuth 2.0 授权
作者:liuyatao 发布时间:2023-10-01 23:05:10
OAuth 2.0 是一种工业级的授权协议。OAuth 2.0是从创建于2006年的OAuth 1.0继承而来的。OAuth 2.0致力于帮助开发者简化授权并为web应用、桌面应用、移动应用、嵌入式应用提供具体的授权流程。
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 supersedes the work done on the original OAuth protocol created in 2006. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
OAuth 2.0的四个角色
为了方便理解,以常用的 使用微信登录 为例
Resource Owner
资源拥有者,对应微信的每个用户微信上设置的个人信息是属于每个用户的,不属于腾讯。
Resource Server
资源服务器,一般就是用户数据的一些操作(增删改查)的REST API,比如微信的获取用户基本信息的接口。
Client Application
第三方客户端,对比微信中就是各种微信公众号开发的应用,第三方应用经过 认证服务器 授权后即可访问 资源服务器 的REST API来获取用户的头像、性别、地区等基本信息。
Authorization Server
认证服务器,验证第三方客户端是否合法。如果合法就给客户端颁布token,第三方通过token来调用资源服务器的API。
四种授权方式(Grant Type)
anthorization_code
授权码类型,适用于Web Server Application。模式为:客户端先调用 /oauth/authorize/ 进到用户授权界面,用户授权后返回 code ,客户端然后根据code和 appSecret 获取 access token 。
implicit简化类型,相对于授权码类型少了授权码获取的步骤。客户端应用授权后认证服务器会直接将access token放在客户端的url。客户端解析url获取token。这种方式其实是不太安全的,可以通过 https安全通道 和 缩短access token的有效时间 来较少风险。
password
密码类型,客户端应用通过用户的username和password获access token。适用于资源服务器、认证服务器与客户端具有完全的信任关系,因为要将用户要将用户的用户名密码直接发送给客户端应用,客户端应用通过用户发送过来的用户名密码获取token,然后访问资源服务器资源。比如支付宝就可以直接用淘宝用户名和密码登录,因为它们属于同一家公司,彼此 充分信任 。
client_credentials
客户端类型,是不需要用户参与的一种方式,用于不同服务之间的对接。比如自己开发的应用程序要调用短信验证码服务商的服务,调用地图服务商的服务、调用手机消息推送服务商的服务。当需要调用服务是可以直接使用服务商给的 appID 和 appSecret 来获取token,得到token之后就可以直接调用服务。
其他概念
scope :访问资源服务器的哪些作用域。
refresh token :当access token 过期后,可以通过refresh token重新获取access token。
实现
有的时候资源服务器和认证服务器是两个不同的应用,有的时候资源服务器和认证服务器在通一个应用中,不同之处在于资源服务器是否需要检查token的有效性,前者需要检查,后者不需要。这里实现后者。
Application的安全配置
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.and().csrf().disable()
.authorizeRequests().anyRequest().authenticated();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("lyt").password("lyt").authorities("ROLE_USER")
.and().withUser("admin").password("admin").authorities("ROLE_ADMIN");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
认证服务器配置
@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("client")
.scopes("read","write")
.secret("secret")
.authorizedGrantTypes("authorization_code","password","implicit","client_credentials");}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
}
资源服务器配置
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableResourceServer
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/oauth2/api/**").authorizeRequests()
.antMatchers(HttpMethod.GET, "/read/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.POST, "/write/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PUT, "/write/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.DELETE, "/write/**").access("#oauth2.hasScope('write')");
}
}
资源服务器 filter-order 设置
需要在 application.yml 中将filter-order设置成3,具体原因参考链接
防止cookie冲突
为了避免认证服务器的cookie和客户端的cookie冲突,出现错误,最好修改 cookie name 或者设置 contextPath 。
测试
postman 中提供OAuth 2.0的认证方式,可以获取到token之后再把认证加入http请求中,即可请求资源服务器的REST API
客户端信息
授权
获取的token
访问资源服务器API
来源:https://juejin.im/post/5a580e726fb9a01caf3757a1


猜你喜欢
- Spring对配置类的处理主要分为2个阶段配置类解析阶段会得到一批配置类的信息,和一些需要注册的beanbean注册阶段将配置类解析阶段得到
- 问题最近 Cordova 项目里有一个需求,这里需要从 assets 目录中读取文件,加载配置信息,并且代码中要用到。因为看到 gradle
- 概述java.util.Random可以产生int、long、float、double以及Goussian等类型的随机数。这也是它与java
- 本文实例讲述了Android编程开发ScrollView中ViewPager无法正常滑动问题解决方法。分享给大家供大家参考,具体如下:这里主
- 目录概述准备工作使用概述springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式
- 本文实例为大家分享了微信小程序支付C#后端源码,供大家参考,具体内容如下using System;using System.Collecti
- CSRF介绍CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click atta
- [LeetCode] 159. Longest Substring with At Most Two Distinct Characters
- 一、新建学生节点类Stu_Node节点包含:学号:int num;姓名:String name;性别:String gender;下一个节点
- 一、前言如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求。Java有原生的API可用于发送HTTP
- 大家都知道在C#里面,我们可以使用Thread.Start方法来启动一个线程,当我们想停止执行的线程时可以使用Thread.Abort方法来
- 一、修改ReadOnly属性1、设置整个DataGridView只读:DataGridView.ReadOnly=true;此时用户的新增行
- 扩展阅读c#基础系列1---深入理解 值类型和引用类型c#基础系列2---深入理解 String引言在上篇文章深入理解值类型和引用类型的时候
- 介绍 在开发过程中,我们有时候会遇到非接口调用而出发程序执行任务的一些场景,比如我们使用quartz定时框架通过配置文件来启动定时任务时,
- 本文实例讲述了Android使用shape使组件呈现出特殊效果的方法。分享给大家供大家参考,具体如下:使用到的布局文件<?xml ve
- 遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。它能解决很多问题,
- 概述本文基于示例的方式解释控制反转,再看控制反转之前,我们先看下常规控制流程,以数据库访问为例示例并没有实际访问数据,而是基于service
- 最近学习了 C#实现文件上传与下载,现在分享给大家。1、C#文件上传创建MyUpload.htm页面,用于测试<form name=&
- 首先当我们将Dwr3配置好以后,我们可以在浏览器中测试一下,查看一下我们配置的Dwr有没有生效,方法是http://localhost:[你
- 一副扑克有54张牌:大小王+4*13,接下来我们来模拟一下斗地主的发牌过程首先,我们需要买牌,新买来的牌都是按顺序摆放的,因此下一步是洗牌,