spring boot学习第十七篇:OAuth2概述及使用GitHub登录第三方网站

0. 导言
我们在浏览器上可以访问成百上千个网站,使用每个网站的服务一般都要先注册账号,那么我们为了更好地记忆,一般都会在多个网站使用相同的账号和密码进行注册。那么问题就来了,如果在你注册的网站中有某些个网站的系统设计不够严谨和安全,数据库的用户信息使用明文存储,那么一旦这个网站遭到攻击或者是数据泄露,那么一些不怀好意的人就可能通过使用这些泄露的数据“撞库”,刚好就登录了你使用相同账号密码注册的其他网站。那么你的权益就有可能会受到损害。

由此行内大佬们便提出了 OAuth。

1. OAuth2 简介
OAuth 是一个开放的非常重要的认证标准/协议,允许用户授权第三方应用访问其存储在其他网站上的资源,而无需将用户名密码提供给第三方网站的开放标准/协议。OAuth2 是 OAuth 的最新版本,同时也是被广泛应用的一个版本。我们在网站上常见的QQ登录,微信扫码登录,GitHub 授权登录就是基于 OAuth2.0 实现的。

官方文档:RFC 6749 - The OAuth 2.0 Authorization Framework

2. OAuth2 认证授权总体流程
整体认证授权流程如下:

从这张图中我们可以看出,整个 OAuth2 的认证授权流程中有4个不同角色:

Client:客户端,也就是第三方网站(相对于认证网站来说)。
Resource Owner:资源拥有者,也就是“我”。
Authorization Server:认证服务器或者说授权服务器。
Resource Server:资源服务器。
3. OAuth2 标准接口
/oauth/authorize:授权端点

/oauth/token:获取令牌端点

/oauth/confirm_access:用户确认授权提交端点

/oauth/error:授权服务错误信息端点

/oauth/check_token:用于资源服务访问的令牌解析端点

/oauth/token_key:提供公有密匙的端点,如果使用JWT令牌的话

4. OAuth2 四种授权模式
4.1 授权码模式
授权码模式(Authorization Code):这是最常用的授权模式。在模式下,用户通过将重定向到授权服务器来进行身份验证,并获一个授权码。然后,应程序使用授权码与授权服务器进行交互,以获取访问牌和刷新令牌。访问令牌用于问受保护的资源,而刷新令牌用于获取新的访问令牌。微信扫码登录就是典型的授权码模式。

授权码模式的授权流程如下图所示:

具体流程如下:

(A)用户访问第三方应用,第三方应用通过浏览器导向认证服务器。

(B)用户选择是否给予客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。

(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

核心参数(假设第三方网站的地址为:wx.com):

https://wx.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=http://www.baidu.com&scope=read
1
字段    描述
client_id    授权服务器注册应用后的唯一标识
response_type    必须 固定值 在授权码中必须为 token
redirect_uri    必须 通过客户端注册的重定向URL
scope    必须 令牌可以访问资源权限
state    可选 存在原样返回客户端 用来防止 CSRF跨站攻击
申请令牌的请求示例(地址栏中的client表示client_id,secret表示密钥值):

刷新令牌请求示例:

4.2 简化模式
简化模式(Implicit Grant):简化模式不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。其具体的授权流程如图所示

具体步骤如下:

(A)第三方应用将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。#token
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
核心参数:

https://wx.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=http://www.baidu.com&scope=read
1
字段    描述
client_id    授权服务器注册应用后的唯一标识
response_type    必须 固定值 在授权码中必须为 token
redirect_uri    必须 通过客户端注册的重定向URL
scope    必须 令牌可以访问资源权限
state    可选 存在原样返回客户端 用来防止 CSRF跨站攻击
4.3 密码模式
**密码模式(Resource Owner Password Credentials Grant)**中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个相同公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

授权流程图如下所示:

具体步骤如下:

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

(C)认证服务器确认无误后,向客户端提供访问令牌。

核心参数:

https://wx.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID
1
申请令牌的请求示例(地址栏中的client表示client_id,secret表示密钥值):

刷新令牌的请求示例:

4.4 客户端模式
**客户端模式(Client Credentials Grant)**指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。

具体步骤如下:

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

(B)认证服务器确认无误后,向客户端提供访问令牌。

https://wx.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
1
申请令牌的请求示例(地址栏中的client表示client_id,secret表示密钥值):

5. GitHub授权登录
GitHub 授权登录流程:

(1)打开 GitHub 网站,在头部导航栏点击头像,再点击 Settings。

(2)找到 Developer settings

(3)先点击左侧 OAuth Apps ,再点击 New OAuth App

(4)输入信息,点击 Register application

(5)注册成功,点击生成密钥

(6)保存好密钥,之后不会完整显示了

(7)创建一个springboot项目

依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.hmblogs</groupId><artifactId>oauth-test</artifactId><version>0.0.1-SNAPSHOT</version><name>oauth-test</name><description>hmblogs</description><properties><java.version>8</java.version><druid.version>1.2.8</druid.version><log4jdbc.version>1.16</log4jdbc.version><es.version>7.9.2</es.version></properties><dependencies><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>org.bgee.log4jdbc-log4j2</groupId><artifactId>log4jdbc-log4j2-jdbc4.1</artifactId><version>${log4jdbc.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

yml配置文件如下所示:

server:port: 8080servlet.context-path: /spring:security:oauth2:client:registration:github:client-id: Iv1.3a0f77a8ae06e98cclient-secret: deb634113d4bd06a735437ad3f2b95f1ba83f9e4redirect-uri: http://localhost:8080/login/oauth2/code/githubdatasource:druid:db-type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpyurl: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:hmblogs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=falseusername: ${DB_USER:root}password: ${DB_PWD:123456}

创建一个配置类(这是新版本SpringSecurity的配置写法,废弃了WebSecurityConfigurerAdapter):

package com.hmblogs.backend.util;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().oauth2Login();//使用 oauth2 认证// ...return http.build();}}

再创建一个控制器类:

package com.hmblogs.backend.controller;import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@GetMapping("/hello")public DefaultOAuth2User hello(){System.out.println("hello ");Authentication authentication = SecurityContextHolder.getContext().getAuthentication();return (DefaultOAuth2User) authentication.getPrincipal();}
}

启动项目,在浏览器中访问“http://localhost:8080”,跳转到github授权端点。

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

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

相关文章

CentOS7里ifcfg-eth0文件不存在解决方案/Centos7修改网络IP解决方案

Centos7网络IP地址手动设置 1、centos7没有ifcfg-eth0&#xff0c;我的centos7也没有其他博客说的什么ifcfg-ens33、ifcfg-ens32&#xff0c;然后我打开了我这里的ifcfg-eno***&#xff0c;结果发现就是centos6里的ifcfg-eth0里的网络配置。2、vim ifcfg-eno***&#xff08;按t…

202203青少年软件编程(Scratch图形化) 等级考试试卷(四级)

第1题&#xff1a;【 单选题】 由1,2,3,4,5,0这六个数字经过排列组合能够组成多少个六位数偶数&#xff1f; 注意&#xff1a; 每一位都不相同&#xff0c; 最高位不能为0。&#xff08; &#xff09; A:720 B:360 C:312 D:88 【正确答案】: C 【试题解析】 : 逻辑知识…

10分钟带你学会配置DNS服务正反向解析

正向解析 服务端IP客户端IP网址192.168.160.134192.168.160.135www.openlab.com 一、首先做准备工作&#xff1a; 关闭安全软件&#xff0c;关闭防火墙&#xff0c;下载bind软件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootserver ~]# y…

【C++程序员的自我修炼】拷贝构造函数

心存希冀 追光而遇目有繁星 沐光而行 目录 拷贝构造函数概念 拷贝构造的特征 无穷递归的解释 浅拷贝 总结&#xff1a; 深拷贝 拷贝构造函数典型调用场景 总结 契子✨ 在生活中总有很多琐事&#xff0c;不做不行做了又怕麻烦&#xff0c;有时候想要是有个和自己一模一样的人就…

每日一题 第八十九期 洛谷 [NOIP2017 提高组] 奶酪

[NOIP2017 提高组] 奶酪 题目背景 NOIP2017 提高组 D2T1 题目描述 现有一块大奶酪&#xff0c;它的高度为 h h h&#xff0c;它的长度和宽度我们可以认为是无限大的&#xff0c;奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系&#xff0c;在坐标系…

Go——面向对象

一. 匿名字段 go支持只提供类型而不写字段名的方式&#xff0c;也就是匿名字段&#xff0c;也称为嵌入字段。 同名字段的情况 所以自定义类型和内置类型都可以作为匿名字段使用 指针类型匿名字段 二.接口 接口定义了一个对象的行为规范&#xff0c;但是定义规范不实现&#xff…

Matlab之过球面一点的平面方程

这篇文章描述2件事情&#xff1a; 1、已知球面上任意点&#xff0c;求过该点、地心、与北极点的平面方程&#xff08;即过该点的经线平面方程&#xff09;&#xff1b; 2、绕过球心的任意轴旋转平面得到新平面的方程 一、已知球面上任意点&#xff0c;求过该点、地心、与北极点…

javase_进阶 day10 集合(泛型,数据结构)

1.泛型 1.1泛型概述 泛型的介绍 ​ 泛型是JDK5中引入的特性&#xff0c;它提供了编译时类型安全检测机制 泛型的好处 把运行时期的问题提前到了编译期间避免了强制类型转换 泛型的定义格式 <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如:…

CopyTranslator下载地址及安装教程

CopyTranslator是一款免费且开源的机器翻译工具&#xff0c;旨在提供快速、便捷的翻译服务。它采用了先进的神经网络机器翻译技术&#xff0c;能够提供准确、流畅的翻译结果。 CopyTranslator的特点和功能如下&#xff1a; 多语言翻译&#xff1a;支持多种常见的语言对&#…

【随笔】Git 高级篇 -- 项目里程碑 git tag(二十)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

leetcode142 环形链表2

题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部…

基于51单片机篮球24秒倒计时设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机篮球24秒倒计时设计( proteus仿真程序设计报告原理图讲解视频&#xff09; 基于51单片机篮球24秒倒计时设计 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真设计4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接下载链接 仿真图pro…

(3)(3.1) 英特尔Realsense深度摄像头(三)

文章目录 前言 10 系统概述 11 手动设置配套计算机 前言 本文介绍如何将英特尔 Realsense 深度摄像头(Intel Realsense Depth Camera)与 ArduPilot 配合使用&#xff0c;以实现避障(obstacle avoidance)。该方法使用在配套计算机上运行的 Python 脚本&#xff08;非 ROS&am…

HackTheBox-Machines--MonitorsTwo

文章目录 0x01 信息收集0x02 CVE-2022-46169 漏洞利用0x03 权限提升0x04 提升到root权限 MonitorsTwo 测试过程 0x01 信息收集 a.端口扫描: 发现22、80端口    b.信息收集: 1.2.22 Cacti信息收集 nmap -sC -sV 10.129.186.1321.访问 10.129.186.132&#xff0c;为 1.2.22 Ca…

社交革命的引领者:探索Facebook的创新策略

1. 引言&#xff1a;社交媒体的崛起 社交媒体的兴起标志着信息时代的到来&#xff0c;它不仅改变了人们的生活方式&#xff0c;也影响着整个社会结构。作为社交媒体的先驱者&#xff0c;Facebook以其创新的策略和领先的技术&#xff0c;成为了这场社交革命的引领者。从2004年马…

itop4412编译内核时garbage following instruction -- `dmb ish‘ 解决方案

王德法 没人指导的学习路上磕磕绊绊太耗费时间了 今天编译4412开发板源码时报 garbage following instruction – dmb ish’ 以下是解决方案&#xff1a; 1.更新编译器 sudo apt-get install gcc-arm-linux-gnueabi 更新后修改Makefile 中编译器路径如下图 2.你以为更新完就可…

SqlServer功能性配置选择

功能性配置 下面的是必选的

传输层协议——UDP/TCP协议

目录 端口号 端口号范围 pidof UDP协议 UDP协议格式 UDP特点 UDP缓冲区 UDP的注意事项 基于UDP的应用层协议 TCP协议 TCP协议格式 序号与确认序号 窗口大小 6个标记位 紧急指针 确认应答机制 连接管理机制 三次握手 四次挥手 超时重传机制 流量控制 滑动…

【计算机网络】ip子网划分--超详细例题解析

Hello!这一篇主要是计算机网络中的ip地址子网划分的例题&#xff0c;这里例举了四个题型。保证即便从0也可以掌握&#xff01;(前面是一些预备知识&#xff0c;不熟悉的小伙伴一定要看下学习下哦&#xff5e;) 这也是博主的学习过程&#xff0c;做题中仅仅我的理解哦。若文章中…

Unity之C#面试题(二)

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之C#面试题&#xff08;二&#xff09; TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&a…