SpringSecurity整合OAuth2授权的简单示例

 2023-02-03
原文作者:公子奇 原文地址:https://juejin.cn/post/7094806710811885575

Spring Security为响应式应用提供OAuth2和WebFlux集成。

OAuth2登录

使用OAuth2或OpenID进行认证。

OAuth 2.0登录功能为应用程序提供了一个功能,用户可以使用他们在OAuth 2.0提供商(如GitHub)或OpenID连接1.0提供商(如谷歌)的现有账户登录应用程序。OAuth 2.0登录实现了用例:“使用谷歌登录”或“使用GitHub登录”。

OAuth 2.0登录通过 认证码授权 实现,具体请参见OAuth 2.0授权框架OpenID连接核心1.0

核心配置

创建SpringBoot项目

SpringBoot2.x为OAuth 2.0登录带来了完整的自动配置功能。

本节展示了如何使用谷歌作为认证提供者来配置OAuth 2.0 Login WebFlux示例,包括以下主题:

说明 :官网提供的是谷歌认证实现,由于国内无法访问谷歌相关服务,所以我们下面改为GitHub的实现。

除了引入SpringSecurity和WebFlux基础依赖以外,实现OAuth2登录还需要引入OAuth2的依赖。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
登录到GitHub

本节展示了如何使用GitHub作为身份验证提供者来配置样例应用程序,包括以下主题:

注册OAuth应用程序

要使用GitHub的OAuth 2.0认证系统登录,您必须注册一个新的OAuth应用程序

注册OAuth应用程序时,确保 授权回调URL 设置为http://127.0.0.1:8080/login/oauth2/code/github

注册之后将看到以下两个信息:

202301012021468311.png

授权回调URL(重定向URI)是应用程序中的路径,终端用户的用户代理在通过GitHub验证并在授权应用程序页面上授予对OAuth应用程序的访问权后,被重定向回该路径。

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

重要: 如果应用程序在代理服务器后运行,建议检查“代理服务器配置”以确保应用程序已正确配置。另外,请参阅redirect-uri支持的URI模板变量

配置 application.yml / application.properties

现在你有了一个带有GitHub的新的OAuth应用程序,你需要配置应用程序来使用OAuth应用程序来进行身份验证流程。这样做:

1 去application.properties设置以下配置

    spring.security.oauth2.client.registration.github.client-id=636f6778593548198b32
    spring.security.oauth2.client.registration.github.client-secret=a0fec898d5c89f36dc1a5cbe85193c528fe9574f

spring.security.oauth2.client.registration是OAuth Client属性的基本属性前缀。

基本属性前缀后面是ClientRegistration的ID,例如github。

启动应用程序

启动应用程序并访问http://127.0.0.1:8080。然后你被重定向到默认的自动生成的登录页面,它显示一个GitHub的链接。

202301012021473312.png

点击GitHub链接,然后你被重定向到GitHub进行身份验证。

通过GitHub认证后,下一页显示的是“授权应用程序”。此页将要求您对在上一步中创建的应用程序授权。单击“授权应用程序”以允许OAuth应用程序访问您的个人用户数据信息。

此时,OAuth客户端从UserInfo端点检索您的个人用户信息,并建立一个经过身份验证的会话。

Tip : 有关从UserInfo端点返回的详细信息,请参阅API文档中的“获取认证用户”。

Spring Boot 2.x 属性映射

下表概述了Spring Boot 2.x OAuth Client属性到ClientRegistration属性的映射。

SpringBoot2.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
CommonOAuth2Provider [通用OAuth2提供商]

CommonOAuth2Provider为许多知名的提供商预定义了一组默认的客户端属性:Google,GitHub, Facebook和Okta。

例如,提供商的authorization-uri, token-uri, and user-info-uri不会经常更改。因此,提供缺省值以减少所需的配置是有意义的。

如前所述,在配置GitHub客户端时,只有client-idclient-secret属性是必须的。

配置自定义提供程序属性

在上一节CommonOAuth2Provider,我们了解了SpringSecurity提供了一组预定义的提供商,不过在实际环境下,上面都是不满足我们需要的,此时就需要我们自定义做相关配置。我们这里以国内的Gitee来实践。

前置步骤

登录到Gitee、注册OAuth应用程序

Gitee OAuth 文档

配置 application.properties
    spring.security.oauth2.client.registration.gitee.client-id=26511dbc353a90b647fbab9e24341d3a36a5bd7cf261b846c41fbd4e8500dcdf
    spring.security.oauth2.client.registration.gitee.client-secret=4230307032d2739d92541b0bf97b242660f24dfaf6d96c545310bbcfd276b702
    spring.security.oauth2.client.registration.gitee.authorization-grant-type=authorization_code
    spring.security.oauth2.client.registration.gitee.redirect-uri=http://127.0.0.1:8080/login/oauth2/code/gitee
    spring.security.oauth2.client.registration.gitee.provider=gitee
    spring.security.oauth2.client.registration.gitee.client-name=gitee
    ​
    spring.security.oauth2.client.provider.gitee.authorization-uri=https://gitee.com/oauth/authorize
    spring.security.oauth2.client.provider.gitee.token-uri=https://gitee.com/oauth/token
    spring.security.oauth2.client.provider.gitee.user-info-uri=https://gitee.com/api/v5/user
    spring.security.oauth2.client.provider.gitee.user-name-attribute=name

配置完成后,启动项目,登录 http://127.0.0.1:8080,直接跳转到授权页面

202301012021479553.png

创建一个Controller
    package com.hz.ss.controller;
    ​
    import org.springframework.security.core.annotation.AuthenticationPrincipal;
    import org.springframework.security.oauth2.core.user.OAuth2User;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    ​
    import java.util.Collections;
    import java.util.Map;
    ​
    /**
     * @author Dong
     * @version 1.0
     * @date 2022/5/6
     */
    @RestController
    public class OAuth2CallbackController {
    ​
        @GetMapping("/user")
        public Map<String, Object> user(@AuthenticationPrincipal OAuth2User principal) {
            return Collections.singletonMap("name", principal.getAttribute("name"));
        }
    }
验证

访问 http://127.0.0.1:8080/user

202301012021485004.png