Spring Boot OAuth 2.0整合详解

目录

[一、Spring Boot 2.x 示例](#一、Spring Boot 2.x 示例)

1、初始化设置

2、设置重定向URI

[3、配置 application.yml](#3、配置 application.yml)

4、启动应用程序

[二、Spring Boot 2.x 属性映射](#二、Spring Boot 2.x 属性映射)

二、CommonOAuth2Provider

三、配置自定义提供者(Provider)属性

[四、覆盖 Spring Boot 2.x 的自动配置](#四、覆盖 Spring Boot 2.x 的自动配置)

[五、注册一个 ClientRegistrationRepository @Bean](#五、注册一个 ClientRegistrationRepository @Bean)

[六、注册一个 SecurityFilterChain @Bean](#六、注册一个 SecurityFilterChain @Bean)

七、完全覆盖自动配置

[八、不使用 Spring Boot 2.x 的 Java 配置](#八、不使用 Spring Boot 2.x 的 Java 配置)


一、Spring Boot 2.x 示例

Spring Boot 2.x为OAuth 2.0登录带来了全面的自动配置功能。

本节展示了如何通过使用Google作为认证提供者来配置 OAuth 2.0 登录示例,并涵盖以下主题。

  • 初始化设置
  • 设置重定向URI
  • 配置 application.yml
  • 启动应用程序

1、初始化设置

要使用谷歌的OAuth 2.0认证系统进行登录,你必须在谷歌API控制台中设置一个项目,以获得OAuth 2.0凭证。

|------------------------------------------------------------|
| 谷歌用于认证的 OAuth 2.0实现 符合 OpenID Connect 1.0规范,并通过了 OpenID认证。 |

按照 OpenID Connect 页面上的指示,从 "Setting up OAuth 2.0" 部分开始。

在完成 "Obtain OAuth 2.0 credentials" 的说明后,你应该有新的OAuth客户端,其证书包括一个 Client ID 和一个 Client Secret。

2、设置重定向URI

重定向URI是终端用户的用户代理在通过谷歌认证并在同意页面上授权访问OAuth客户端( 在上一步创建的)后,被重定向到应用程序中的路径。

在 "设置重定向URI" 小节中,确保授权的重定向URI字段被设置为 localhost:8080/login/oauth2/code/google。

|------------------------------------------------------------------------------------------------------|
| 默认重定向URI模板是 {baseUrl}/login/oauth2/code/{registrationId}。registrationId 是 ClientRegistration 的唯一标识符。 |

|----------------------------------------------------------------------------------|
| 如果OAuth客户端在代理服务器后面运行,你应该检查 代理服务器配置,以确保应用程序的配置正确。另外,请看支持的 URI模板变量 的 redirect-uri。 |

3、配置 application.yml

现在你已经有了一个新的谷歌OAuth客户端,你需要配置应用程序,以使用OAuth客户端的认证流程。要做到这一点。

  1. 进入 application.yml 并设置以下配置。
  2. spring: security: oauth2: client: registration: google: client-id: google-client-id client-secret: google-client-secret
  3. Copied!
  4. OAuth Client properties
  5. spring.security.oauth2.client.registration 是OAuth客户端属性的基础属性前缀。在基本属性的前缀后面是 ClientRegistration 的ID,如Google。
  6. 将 client-id 和 client-secret 属性中的值替换为你之前创建的OAuth 2.0凭证。

4、启动应用程序

启动Spring Boot 2.x 示例应用,进入 localhost:8080。然后你会被重定向到默认的自动生成的登录页面,其中显示一个Google的链接。

点击谷歌的链接,然后你会被转到谷歌进行认证。

在用你的谷歌账户凭证进行认证后,你会看到"同意界面"。"同意界面"要求你允许或拒绝访问你先前创建的OAuth客户端。点击 Allow,授权OAuth客户端访问你的电子邮件地址和基本个人资料信息。

此时,OAuth客户端从 UserInfo Endpoint 检索你的电子邮件地址和基本个人资料信息,并建立一个已认证的会话(Session)。

二、Spring Boot 2.x 属性映射

下表列出了Spring Boot 2.x OAuth客户端属性与 ClientRegistration 属性的映射。

|----------------------------------------------------------------------------------------------|--------------------------------------------------------|
| Spring Boot 2.x | ClientRegistration |
| spring.security.oauth2.client.registration.[registrationId] | registrationId |
| spring.security.oauth2.client.registration.[registrationId].client-id | clientId |
| spring.security.oauth2.client.registration.[registrationId].client-secret | clientSecret |
| spring.security.oauth2.client.registration.[registrationId].client-authentication-method | clientAuthenticationMethod |
| spring.security.oauth2.client.registration.[registrationId].authorization-grant-type | authorizationGrantType |
| spring.security.oauth2.client.registration.[registrationId].redirect-uri | redirectUri |
| spring.security.oauth2.client.registration.[registrationId].scope | scopes |
| spring.security.oauth2.client.registration.[registrationId].client-name | clientName |
| spring.security.oauth2.client.provider.[providerId].authorization-uri | providerDetails.authorizationUri |
| spring.security.oauth2.client.provider.[providerId].token-uri | providerDetails.tokenUri |
| spring.security.oauth2.client.provider.[providerId].jwk-set-uri | providerDetails.jwkSetUri |
| spring.security.oauth2.client.provider.[providerId].issuer-uri | providerDetails.issuerUri |
| spring.security.oauth2.client.provider.[providerId].user-info-uri | providerDetails.userInfoEndpoint.uri |
| spring.security.oauth2.client.provider.[providerId].user-info-authentication-method | providerDetails.userInfoEndpoint.authenticationMethod |
| spring.security.oauth2.client.provider.[providerId].user-name-attribute | providerDetails.userInfoEndpoint.userNameAttributeName |

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 你可以通过指定 spring.security.oauth2.client.provider.[providerId].issuer-uri 属性,使用发现OpenID Connect提供者的 Configuration endpoint 或授权服务器的 Metadata endpoint 来初始配置 ClientRegistration。 |

二、CommonOAuth2Provider

CommonOAuth2Provider 为一些知名的供应商预先定义了一套默认的客户端属性。如:谷歌、GitHub、Facebook和Okta。

例如,authorization-uri、token-uri 和 user-info-uri 对提供者来说不会经常改变。因此,提供默认值是有意义的,可以减少所需的配置。

正如之前所展示的,当我们 配置谷歌客户端时,只需要 client-id 和 client-secret 属性。

下面列出了一个例子。

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: google-client-id
            client-secret: google-client-secret

|-------------------------------------------------------------------------------------------|
| 客户端属性的自动默认在这里工作得天衣无缝,因为 registrationId(谷歌)与 CommonOAuth2Provider 中的 GOOGLE 枚举(不区分大小写)相匹配。 |

对于你可能想指定一个不同的 registrationId 的情况,如 google-login,你仍然可以通过配置 provider 属性来利用客户端属性的自动默认。

下面列出了一个例子。

spring:
  security:
    oauth2:
      client:
        registration:
          google-login:	
            provider: google	
            client-id: google-client-id
            client-secret: google-client-secret

|--------------------------------------------------------------------------------|
| registrationId 被设置为 google-login。 |
| 提供者属性被设置为 google,这将利用 CommonOAuth2Provider.GOOGLE.getBuilder() 中设置的客户端属性的自动默认。 |

三、配置自定义提供者(Provider)属性

有一些OAuth 2.0供应商支持多租户,这导致每个租户(或子域)都有不同的协议端点。

例如,在Okta注册的OAuth客户端被分配到一个特定的子域,并有他们自己的协议端点。

对于这些情况,Spring Boot 2.x为配置自定义提供者属性提供了以下基础属性:spring.security.oauth2.client.provider.[providerId]

下面列出了一个例子。

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-secret: okta-client-secret
        provider:
          okta:	
            authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
            token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
            user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
            user-name-attribute: sub
            jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys

|------------------------------------------------------------------|
| 基础属性(spring.security.oauth2.client.provider.okta)允许自定义配置协议的端点位置。 |

四、覆盖 Spring Boot 2.x 的自动配置

用于支持OAuth客户端的 Spring Boot 2.x 自动配置类是 OAuth2ClientAutoConfiguration。

它执行以下任务。

  • 注册一个由配置的OAuth客户端属性的 ClientRegistrationRepository @Bean 组成的 ClientRegistration。
  • 注册一个 SecurityFilterChain @Bean,并通过 httpSecurity.oauth2Login() 启用OAuth 2.0登录。

如果你需要根据你的具体要求覆盖自动配置,你可以通过以下方式进行。

  • 注册一个 ClientRegistrationRepository @Bean
  • 注册一个 SecurityFilterChain @Bean
  • 完全覆盖自动配置

五、注册一个 ClientRegistrationRepository @Bean

下面的例子显示了如何注册一个 ClientRegistrationRepository @Bean。

  • Java

    @Configuration
    public class OAuth2LoginConfig {

      @Bean
      public ClientRegistrationRepository clientRegistrationRepository() {
      	return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
      }
    
      private ClientRegistration googleClientRegistration() {
      	return ClientRegistration.withRegistrationId("google")
      		.clientId("google-client-id")
      		.clientSecret("google-client-secret")
      		.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
      		.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
      		.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
      		.scope("openid", "profile", "email", "address", "phone")
      		.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
      		.tokenUri("https://www.googleapis.com/oauth2/v4/token")
      		.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
      		.userNameAttributeName(IdTokenClaimNames.SUB)
      		.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
      		.clientName("Google")
      		.build();
      }
    

    }

六、注册一个 SecurityFilterChain @Bean

下面的例子展示了如何用 @EnableWebSecurity 注册一个 SecurityFilterChain @Bean,并通过 httpSecurity.oauth2Login() 启用OAuth 2.0登录。

OAuth2 Login Configuration

  • Java

    @Configuration
    @EnableWebSecurity
    public class OAuth2LoginSecurityConfig {

      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		.authorizeHttpRequests(authorize -> authorize
      			.anyRequest().authenticated()
      		)
      		.oauth2Login(withDefaults());
      	return http.build();
      }
    

    }

七、完全覆盖自动配置

下面的例子显示了如何通过注册一个 ClientRegistrationRepository @Bean 和一个 SecurityFilterChain @Bean 来完全覆盖自动配置。

Overriding the auto-configuration

  • Java

    @Configuration
    public class OAuth2LoginConfig {

      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		.authorizeHttpRequests(authorize -> authorize
      			.anyRequest().authenticated()
      		)
      		.oauth2Login(withDefaults());
      	return http.build();
      }
    
      @Bean
      public ClientRegistrationRepository clientRegistrationRepository() {
      	return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
      }
    
      private ClientRegistration googleClientRegistration() {
      	return ClientRegistration.withRegistrationId("google")
      		.clientId("google-client-id")
      		.clientSecret("google-client-secret")
      		.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
      		.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
      		.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
      		.scope("openid", "profile", "email", "address", "phone")
      		.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
      		.tokenUri("https://www.googleapis.com/oauth2/v4/token")
      		.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
      		.userNameAttributeName(IdTokenClaimNames.SUB)
      		.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
      		.clientName("Google")
      		.build();
      }
    

    }

八、不使用 Spring Boot 2.x 的 Java 配置

如果你不能使用 Spring Boot 2.x,并希望配置 CommonOAuth2Provider 中的一个预定义提供者(例如,谷歌),请应用以下配置。

OAuth2 Login Configuration

  • Java

    @Configuration
    @EnableWebSecurity
    public class OAuth2LoginConfig {

      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		.authorizeHttpRequests(authorize -> authorize
      			.anyRequest().authenticated()
      		)
      		.oauth2Login(withDefaults());
      	return http.build();
      }
    
      @Bean
      public ClientRegistrationRepository clientRegistrationRepository() {
      	return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
      }
    
      @Bean
      public OAuth2AuthorizedClientService authorizedClientService(
      		ClientRegistrationRepository clientRegistrationRepository) {
      	return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
      }
    
      @Bean
      public OAuth2AuthorizedClientRepository authorizedClientRepository(
      		OAuth2AuthorizedClientService authorizedClientService) {
      	return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
      }
    
      private ClientRegistration googleClientRegistration() {
      	return CommonOAuth2Provider.GOOGLE.getBuilder("google")
      		.clientId("google-client-id")
      		.clientSecret("google-client-secret")
      		.build();
      }
    

    }

相关推荐
2401_857439691 小时前
Spring Boot新闻推荐系统:用户体验优化
spring boot·后端·ux
hong_zc1 小时前
算法【Java】—— 二叉树的深搜
java·算法
进击的女IT2 小时前
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
java·spring boot·后端
Miqiuha2 小时前
lock_guard和unique_lock学习总结
java·数据库·学习
杨半仙儿还未成仙儿3 小时前
Spring框架:Spring Core、Spring AOP、Spring MVC、Spring Boot、Spring Cloud等组件的基本原理及使用
spring boot·spring·mvc
一 乐3 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
数云界3 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
阑梦清川3 小时前
Java继承、final/protected说明、super/this辨析
java·开发语言
快乐就好ya5 小时前
Java多线程
java·开发语言
IT学长编程5 小时前
计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·二手图书交易系统