基于SpringBoot 3.0 +SpringSecurity 6.0 +OAuth2 实现GitHub、Google认证授权登录
第一章 OAuth2协议简介
1.1 OAuth是什么
开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。
1.2 OAuth涉及角色
- 资源所有者(Resource Owner):顾名思义,资源的所有者,很多时候其就是我们普通的自然人(但不限于自然人,如某些应用程序也会创建资源),拥有资源的所有权。
- 资源服务器(Resource Server):保存着受保护的用户资源。
- 应用程序(Client):准备访问用户资源的应用程序,其可能是一个web应用,或是一个后端web服务应用,或是一个移动端应用,也或是一个桌面可执行程序。
- 授权服务器(Authorization Server):授权服务器,在获取用户的同意授权后,颁发访问令牌给应用程序,以便其获取用户资源。
1.3 OAuth认证流程
过程如下:
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
由以上步骤可以看出,B为关键,即如何获取授权为认证的关键步骤。
1.4 协议四种授权模式
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式。
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
1.4.1 授权码模式
功能最完善,流程最严密的授权模式。可以是用户真正的授权,它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。
过程如下:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
1.4.2 简化模式
简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌。
过程如下:
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
1.4.3 密码模式
用户向客户端提供自己的用户名和密码,客户端直接使用这些信息,向认证服务商申请令牌。这种方式认证服务器无法判定用户是否真正授权了,用户名和密码可能是第三方应用盗取而来,存在安全隐患。
它的步骤如下:
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
1.4.4 客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
它的步骤如下:
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
第二章 SpringBoot 3.0 + SpringSecurity 6 + OAuth2 认证服务器
2.1开发环境介绍
SpringBoot 3.1.0
2.2 客户端
2.2.1 文件目录
2.2.2 pom依赖
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.2.3 创建Oauth2DemoApplication启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Oauth2DemoApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2DemoApplication.class, args);
}
}
2.2.4 创建DemoController类
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName DemoCotroller
* @Description TODO
* @Author qinchanghe
* @Date 2023/6/16 09:30
* @Version 1.0
**/
@RestController
@RequestMapping("/api/demo")
public class DemoCotroller {
@GetMapping
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello");
}
}
2.2.5 启动Oauth2DemoApplication
浏览器访问http://localhost:8080/api/demo
控制台显示密码输入即可
2.2.6 创建SecurityConfig类
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;
/**
* @ClassName SecurityConfig
* @Description TODO
* @Author qinchanghe
* @Date 2023/6/16 09:35
* @Version 1.0
**/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
;
return http.build();
}
}
2.3 授权服务器
2.3.1使用GitHub作为授权服务器
github授权服务器
1
把生成的ClientID 和 Client Secret加入配置文件application.yml即可。
spring:
security:
oauth2:
client:
registration:
github:
clientId: #客户端ID
clientSecret: #客户端密码
运行即可看到
2.3.2 使用Google作为授权服务器
谷歌服务器
创建客户端ID
把生成的ClientID 和 Client Secret加入配置文件application.yml即可。
spring:
security:
oauth2:
client:
registration:
github:
clientId: #客户端ID
clientSecret: #客户端密码
google:
clientId: #客户端ID
clientSecret: #客户端密码
启动Oauth2DemoApplication即可。
完成任务。
版权归原作者 OVERCOME_1 所有, 如有侵权,请联系我们删除。