Spring Security OAuth Login with WebFlux – 使用WebFlux的Spring Security OAuth登录

最后修改: 2018年 11月 6日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Spring Security added OAuth support for WebFlux starting with the 5.1.x GA.

Spring Security从5.1.x GA开始为WebFlux增加了OAuth支持。

We’ll discuss how to configure our WebFlux application to use OAuth2 Login support. We’ll also discuss how to use WebClient to access OAuth2 secured resources.

我们将讨论如何配置我们的WebFlux应用程序以使用OAuth2登录支持。我们还将讨论如何使用WebClient来访问OAuth2安全资源。

The OAuth Login configuration for Webflux is similar to the one for a standard Web MVC application. For more detail on this, also have a look at our article on Spring OAuth2Login element.

Webflux的OAuth登录配置与标准Web MVC应用程序的配置类似。关于这方面的更多细节,也可以看看我们关于Spring OAuth2Login元素的文章。

2. Maven Configuration

2.Maven配置

To begin with, we’ll create a simple Spring Boot application and add these dependencies to our pom.xml:

首先,我们将创建一个简单的Spring Boot应用程序,并将这些依赖项添加到我们的pom.xml中。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>

The spring-boot-starter-security, spring-boot-starter-webflux and spring-security-oauth2-client dependencies are available on Maven Central.

spring-boot-starter-securityspring-boot-starter-webfluxspring-security-oauth2-client依赖项在Maven中心提供。

3. Main Controller

3.主控制器

Next, we’ll add a simple controller to display the username on the home page:

接下来,我们将添加一个简单的控制器,在主页上显示用户名。

@RestController
public class MainController {
    
    @GetMapping("/")
    public Mono<String> index(@AuthenticationPrincipal Mono<OAuth2User> oauth2User) {
       return oauth2User
        .map(OAuth2User::getName)
        .map(name -> String.format("Hi, %s", name));
    }
}

Note that we’ll display the username obtained from OAuth2 client UserInfo endpoint.

注意,我们将显示从OAuth2客户端UserInfo端点获得的用户名

4. Login Using Google

4.使用Google登录

Now, we’ll configure our application to support login using Google.

现在,我们将配置我们的应用程序,以支持使用谷歌登录。

First, we need to create a new project at Google Developer Console

首先,我们需要在Google Developer Console创建一个新项目

Now, we need to add OAuth2 credentials (Create Credentials > OAuth Client ID).

现在,我们需要添加OAuth2凭证(创建凭证>OAuth客户端ID)。

Next, we’ll add this to “Authorized Redirect URIs”:

接下来,我们将把它添加到 “授权的重定向URI “中。

http://localhost:8080/login/oauth2/code/google

Then, we need to configure our application.yml to use the Client ID and Secret:

然后,我们需要配置我们的application.yml以使用客户端ID和秘密

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

As we have spring-security-oauth2-client in our path, our application will be secured.

由于我们的路径中有spring-security-oauth2-client,我们的应用程序将是安全的。

Users will be redirected to log in using Google before they can access our home page.

用户在访问我们的主页之前,将被重定向到使用谷歌进行登录。

5. Login Using Auth Provider

5.使用认证提供者登录

We can also configure our application to log in from a custom authorization server.

我们还可以配置我们的应用程序,使其从一个自定义的授权服务器上登录。

In the following example, we’ll use our authorization server from a previous article.

在下面的例子中,我们将使用来自前一篇文章的授权服务器。

This time, we need to configure more properties, not just the ClientID and Client Secret:

这一次,我们需要配置更多的属性,而不仅仅是ClientID和Client Secret。

spring:
  security:
    oauth2:
      client:
        registration:
          custom:
            client-id: fooClientIdPassword
            client-secret: secret
            scopes: read,foo
            authorization-grant-type: authorization_code
            redirect-uri-template: http://localhost:8080/login/oauth2/code/custom
        provider:
          custom:
            authorization-uri: http://localhost:8081/spring-security-oauth-server/oauth/authorize
            token-uri: http://localhost:8081/spring-security-oauth-server/oauth/token
            user-info-uri: http://localhost:8088/spring-security-oauth-resource/users/extra
            user-name-attribute: user_name

In this case, we also need to specify the scope, grant type and redirect URI for the OAuth2 client. We’ll also provide the authorization and token URI of the Authorization Server.

在这种情况下,我们还需要为OAuth2客户端指定范围,授予类型重定向URI。我们还将提供授权服务器的授权令牌URI

Finally, we need to configure the UserInfo endpoint as well to be able to get the user authentication details.

最后,我们还需要配置UserInfo端点,以便能够获得用户认证的详细信息。

6. Security Configuration

6.安全配置

By default, Spring Security secures all paths. Therefore, if we have only one OAuth client, we’ll be redirected to authorize this client and log in.

默认情况下,Spring Security会确保所有路径的安全。因此,如果我们只有一个OAuth客户端,我们会被重定向到授权这个客户端并登录。

If multiple OAuth clients are registered, then a login page will be automatically created to choose the login method.

如果注册了多个OAuth客户端,那么就会自动创建一个登录页面来选择登录方式。

We can change that if we like and provide a detailed security configuration:

如果我们愿意,我们可以改变这一点,并提供一个详细的安全配置

@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {
        return http.authorizeExchange()
          .pathMatchers("/about").permitAll()
          .anyExchange().authenticated()
          .and().oauth2Login()
          .and().build();
    }
}

In this example, we’ve secured all paths except for “/about”.

在这个例子中,我们确保了除”/about “之外的所有路径。

7. WebClient

7.WebClient

We can also do more than just authenticate users using OAuth2. We can use WebClient to access OAuth2 secured resources using OAuth2AuthorizedClient.

我们还可以做得更多,而不仅仅是使用OAuth2验证用户。我们可以使用WebClient,通过OAuth2AuthorizedClient来访问OAuth2的安全资源。

Now, let’s configure our WebClient:

现在,让我们来配置我们的WebClient

@Bean
public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepo, 
  ServerOAuth2AuthorizedClientRepository authorizedClientRepo) {
    ServerOAuth2AuthorizedClientExchangeFilterFunction filter = 
      new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepo, authorizedClientRepo);
    
    return WebClient.builder().filter(filter).build();
}

Then, we can retrieve an OAuth2 secured resource:

然后,我们可以检索到一个OAuth2安全资源。

@Autowired
private WebClient webClient;

@GetMapping("/foos/{id}")
public Mono<Foo> getFooResource(@RegisteredOAuth2AuthorizedClient("custom") 
  OAuth2AuthorizedClient client, @PathVariable final long id){
    return webClient
      .get()
      .uri("http://localhost:8088/spring-security-oauth-resource/foos/{id}", id)
      .attributes(oauth2AuthorizedClient(client))
      .retrieve()
      .bodyToMono(Foo.class); 
}

Note that we retrieved the remote resource Foo using AccessToken from OAuth2AuthorizedClient.

请注意,我们使用AccessTokenOAuth2AuthorizedClient检索了远程资源Foo

8. Conclusion

8.结论

In this quick article, we learned how to configure our WebFlux application to use OAuth2 Login support and how to use WebClient to access OAuth2 secured resources.

在这篇快速文章中,我们学习了如何配置我们的WebFlux应用程序以使用OAuth2登录支持,以及如何使用WebClient来访问OAuth2安全资源。

As always, the full source code is available over on GitHub.

一如既往,完整的源代码可在GitHub上获得