转-OAuth2.0 原理流程及其单点登录和权限控制

原文链接

单点登录是多域名企业站点流行的登录方式。本文以现实生活场景辅助理解,力争彻底理清 OAuth2.0 实现单点登录的原理流程。同时总结了权限控制的实现方案,及其在微服务架构中的应用。

1 什么是单点登录

1.1 多点登录

传统的多点登录系统中,每个站点都实现了本站专用的帐号数据库和登录模块。各站点的登录状态相互不认可,各站点需要逐一手工登录。如下图,有两个术语含义如下:

  • 认证(authentication): 验证用户的身份;
  • 授权(authorization): 验证用户的访问权限。

1706260087945.png

1.2 单点登录

单点登录,英文是 Single Sign On,缩写为 SSO。

多个站点(192.168.1.20X)共用一台认证授权服务器(192.168.1.110,用户数据库和认证授权模块共用)。用户经由其中任何一个站点(比如 192.168.1.201)登录后,可以免登录访问其他所有站点。而且,各站点间可以通过该登录状态直接交互。

1706260115462.png

2 OAuth2 认证授权的原理流程

2.1 生活实例【★★重点★★】

为了直观的理解 OAuth2.0 原理流程,我们假设这样一个生活场景:

(1)档案局A(客户端 / Client):以“档案局ID/密码”标识,是掌握档案资源的机构。并列还有很多档案局B/C/…,每个档案局存储的档案内容(资源 / Resource)不一样,比如政治、经济、军事、文化等;

(2)公民张三(资源所有者 / Resource Owner):以“用户名/密码”标识,需要到各个档案局查档案;

(3)派出所(授权服务器 / Authentication Server):可以是单个巨大的派出所,也可以是数据共享的派出所集群,掌管的信息、提供的对外接口功能有:

  • 档案局信息:所有档案局的“档案局ID/密码”,证明档案局的身份;
  • 公民信息:所有公民的“用户名/密码”,能提供张三是张三的用户身份证明(认证 / Authentication)
  • 公民对于档案局的权限:有张公民和档案局的权限的映射表,可查得各公民对各档案局是否有操作权限(授权 / Authorization)。通常,设计中会增加官职(角色 / Role)一层,各公民属于哪个官职(角色),哪个官职(角色)对于特定档案局有操作权限。

2.1.1 张三首次访问档案局A

张三之前从未到访档案局,第一次来档案局。对照下图序号理解:

(1)张三来到“档案局A”的“档案处”,该处要求实名登记后才能查询,被指示到“用户登记处”办理(HTTP重定向);

(2)张三来到“档案局A”的“用户登记处”,既不能证明身份(认证),又不能证明自己有查档案A的权限(授权)。张三携带档案局A的标识(client-id),被重定向至“授权信开具处”;

(3)张三来到“派出所”的“授权信开具处”,出示档案局A的标识,希望开具授权信(授权)。该处要求首先证明身份(认证),被重定向至“用户身份验证处”;

(4)张三来到“派出所”的“用户身份验证处”,领取了用户身份表(网页登录表单 Form);

(5)张三填上自己的用户名和密码,交给(提交 / Submit)“用户身份验证处”,该处从私用数据库中查得用户名密码匹配,确定此人是张三,开具身份证明信,完成认证。张三带上身份证明信和档案局A的标识,被重定向至“授权信开具处”;

(6)张三再次来到“授权信开具处”,出示身份证明信和档案局A的标识,该处从私用数据库中查得,张三的官职是市长级别(角色),该官职具有档案局A的查询权限,就开具“允许张三查询档案局A”的授权信(授权码 / code),张三带上授权信被重定向至“档案局”的“用户登录处”;

(7)张三到了“档案局”的“用户登录处”,该处私下拿出档案局A的标识(client-id)和密码,再附上张三出示的授权信(code),向“派出所”的“腰牌发放处”为张三申请的“腰牌”(token),将来张三可以带着这个腰牌表明身份和权限。又被重定向到“档案处”;

(8)张三的会话(Session)已经关联上了腰牌(token),可以直接通过“档案处”查档案。

1706260138545.png

2.1.2 张三首次访问档案局B

张三已经成功访问了档案局A,现在他要访问档案局B。对照下图序号理解:

(1)/(2) 同上;

(3)张三已经有“身份证明信”,直接在“派出所”的“授权信开具处”成功开具“访问档案局B”的授权信;

(4)/(5)/(6) 免了;

(7)“档案局B”的“用户登记处”完成登记;

(8)“档案局B”的“档案处”查得档案。

1706260155880.png

2.1.3 张三再次访问档案局A

张三已经成功访问了档案局A,现在他要访问档案局A。对照下图序号理解:

(1)直接成功查到了档案;

(2~8)都免了。

1706260177919.png

2.2 HTTP 重定向原理

HTTP 协议中,浏览器的 REQUEST 发给服务器之后,服务器如果发现该业务不属于自己管辖,会把你支派到自身服务器或其他服务器(host)的某个接口(uri)。正如我们去政府部门办事,每到一个窗口,工作人员会说“你带上材料A,到本所的X窗口,或者其他Y所的Z窗口”进行下一个手续。

1706260200813.png

2.3 SSO 工作流程

至此,就不难理解 OAuth 2.0 的认证/授权流程,此处不再赘述。请拿下图对照“2.1 生活实例”一节来理解。

1706260216697.png

2.4 OAuth2.0 进阶

  • RFC 6749: The OAuth 2.0 Authorization Framework
  • RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage
  • 帮你深入理解OAuth2.0协议

根据官方标准,OAuth 2.0 共用四种授权模式:

  • Authorization Code: 用在服务端应用之间,这种最复杂,也是本文采用的模式;
  • Implicit: 用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)
  • Resource Owner Password Credentials(password): 应用直接都是受信任的(都是由一家公司开发的,本例子使用)
  • Client Credentials: 用在应用API访问。

1706260240129.png

3 基于 SpringBoot 实现认证/授权

官方文档:Spring Cloud Security

3.1 授权服务器(Authorization Server)

(1) pom.xml

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

(2) application.properties

server.port=8110 ## 监听端口

(3) AuthorizationServerApplication.java

@EnableResourceServer 
// 启用资源服务器
public class AuthorizationServerApplication 
{    // ...
}

(4) 配置授权服务的参数

@Configuration  
@EnableAuthorizationServer  
public class Oauth2AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {  @Override  public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {  clients.inMemory()  .withClient("webapp").secret("secret") //客户端 id/secret  .authorizedGrantTypes("authorization code") //授权妈模式  .scopes("user_info")  .autoApprove(true) //自动审批  .accessTokenValiditySeconds(3600); //有效期1hour  }  
}  @Configuration  
public class Oauth2WebSecurityConfigurer extends WebSecurityConfigurerAdapter {  @Override  protected void configure(HttpSecurity http) throws Exception {  http.requestMatchers()  .antMatchers("/login", "/oauth/authorize/oauth/logout")  .and().authorizeRequests().anyRequest().authenticated()  .and().formLogin().permitAll();  }  @Override  protected void configure(AuthenticationManagerBuilder auth) throws Exception {  auth.inMemoryAuthentication().withUser("admin").password("admin123").roles("ADMIN");  }  
}

3.2 客户端(Client, 业务网站)

(1) pom.xml

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

(2) application.properties

server port=8080  
security.oauth2.client.client-id=webapp  
security.oauth2.client.client-secret=secret  
security.oauth2.client.access-token-uri=http://localhost:8110/oauth/token  
security.oauth2.client.user-authorization-uri=http://localhost:8110/oauth/authorize  
security.oauth2.resource.user-info-uri=http://localhost:8110/oauth/user

(3) 配置 WEB 安全

@Configuration  
@EnableOAuth2Sso  
public class Oauth2WebsecurityConfigurer extends WebSecurityConfigurerAdapter {  @Override  public void configure(HttpSecurity http) throws Exception {  http.antMatcher("/**").authorizeRequests()  .antMatchers("/", "/login").permitAll()  .anyRequest().authenticated();  }  
}  @RestController  
public class Oauth2ClientController {  @GetMapping("/")  public ModelAndView index() {  return new ModelAndView("index");  }  @GetMapping("/welcome")  public ModelAndView welcome() {  return new ModelAndView("welcome");  }  
}

3.3 用户权限控制(基于角色)

  • 授权服务器中,定义各用户拥有的角色: user=USER, admin=ADMIN/USER, root=ROOT/ADMIN/USER
  • 业务网站中(client),注解标明哪些角色可
@RestController  
public class Oauth2ClientController {  @GetMapping("/welcome")  public ModelAndView welcome() {  return new ModelAndView("welcome");  }  @GetMapping("/api/user")  @PreAuthorize("hasAuthority('USER')")  public Map<String, Object> apiUser() {  }  @GetMapping("/api/admin")  @PreAuthorize("hasAuthority('ADMIN')")  public Map<String, Object> apiAdmin() {  }  @GetMapping("/api/root")  @PreAuthorize("hasAuthority('ROOT')")  public Map<String, Object> apiRoot() {  }  
}

4 综合运用

4.1 权限控制方案

下图是基本的认证/授权控制方案,主要设计了认证授权服务器上相关数据表的基本定义。可对照本文“2.1 生活实例”一节来理解。

1706261125133.png

4.2 在微服务架构中的应用

与常规服务架构不同,在微服务架构中,Authorization Server/Resource Server 是作为微服务存在的,用户的登录可以通过API网关一次性完成,无需与无法跳转至内网的 Authorization Server 来完成。

1706261141918.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741256.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】-Java反射

Java 反射由浅入深 | 进阶必备 原文链接 本博文主要记录我学习 Java 反射(reflect)的一点心得,在了解反射之前,你应该先了解 Java 中的 Class 类,如果你不是很了解,可以先简单了解下。 一、Java 反射机制 参考了许多博文,总结了以下个人观点,若有不妥还望指正:Java 反…

OAuth2.0登录的四种方式

OAuth登录的四种方式 1. 授权码 授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。 这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信…

C++关于计算浮点数小数位数时遇到的浮点数精确度问题(以及浮点数强制转换问题)

起因是当我想要计算浮点数的小数位位数(利用当浮点数num减去其整数位 ) 我的想法是先分离出小数位,然后每次循环给小数位乘上10,直到不存在小数位时,就会满足当num - (int)num == 0通过这种方式就可以得到小数位的长度 #include <iostream> using namespace std; in…

codeforces 955 div 2 D

题目链接 D. Beauty of the mountains 题目大意解题思路 首先记录所有雪山和没有雪山两种山峰的高度差为 \(tot\) ,然后对于每个可能的子矩,我们可以每次给所有山峰都加一或者减一,因此只要计算出矩阵内两种山峰的个数差的绝对值我们就能得到每次操作该子矩阵对tot的贡献 \(…

全局ID工具类

测试方法学习: 定义一个任务(生成id),执行300次,让不同线程执行这300次,用线程池对象的submit方法。心甘情愿做你现在想做的每一件事。

Dubbo源码学习

学习Dubbo框架与手写模拟相关内容 一、存在的意义 Dubbo:解决分布式系统的复杂性,实现服务治理(使服务之间的调用变的简单)和自动注册与发现,简化服务调用。 二、调用过程Dubbo的使用 接口代表一种服务,对应不同的实现,使服务之间的依赖变的简单。 服务消费者通过ClassP…

软件测试的分类and测试进阶路线

本文来自博客园,作者:子沐呐吖,转载请注明原文链接:https://www.cnblogs.com/SuperLee017/p/18292404

使用资源编排 ROS 轻松部署单点网站——以 WordPress 为例

介绍 WordPress是一款免费开源的网站内容管理系统(CMS),它可以帮助用户简单快捷地创建和管理自己的网站,包括博客、新闻网站、电子商务网站、社交网络等等。WordPress 有丰富的主题和插件库,使得用户可以轻松地为网站定制外观和功能。WordPress 的易用性和可扩展性使其成为…

[Java SE] Java-文件系统-常用文件路径的获取方法

1 获取相对路径 /*** 获取相对路径 【推荐】* 使用Java提供的Path类和Paths类来获取相对路径。* 例如,假设有两个路径a和b,我们可以使用Path类的relativize()方法来获取相对路径,该方法返回一个相对路径的Path对象。*/ @Test public void getRelativePathTest1(){Path pathA…

CH582 CH592 CH573 BLE central主机获取handle值

GATT_DiscCharsByUUID和GATT_ReadUsingCharUUID 差异

[深入理解Java虚拟机]Java内存模型

Java内存模型 概述 多任务处理在现代计算机操作系统中几乎已是一项必备的功能了。在许多场景下,让计算机同时去做几件事情,不仅是因为计算机的运算能力强大了,还有一个很重要的原因是计算机的运算速度与它的存储和通信子系统的速度差距太大,大量的时间都花费在磁盘I/O、网络…

深入理解 DB-GPT

DB-GPT 项目介绍 DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。目的是构建大模型领域的基础设施,通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Mult…