OAuth2 – @EnableResourceServer vs @EnableOAuth2Sso – OAuth2 – @EnableResourceServer vs @EnableOAuth2Sso

最后修改: 2018年 9月 12日

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

1. Overview

1.概述

In this tutorial, we’re going to talk about the @EnableResourceServer and @EnableOAuth2Sso annotations in Spring Security.

在本教程中,我们将讨论Spring Security中的@EnableResourceServer@EnableOAuth2Sso注释。

We’ll begin by explaining the differences between an OAuth2 Client and an OAuth2 Resource Server. Afterwards, we’ll talk a little about what these annotations can do for us and demonstrate their usage with an example using Zuul and a simple API.

我们将首先解释OAuth2客户端和OAuth2资源服务器之间的区别。之后,我们将谈一谈这些注释可以为我们做什么,并通过一个使用Zuul和一个简单的API的例子来演示其使用。

For the purpose of this article, we’re going to assume some pre-existing experience with Zuul and OAuth2.

在本文中,我们将假设对ZuulOAuth2已经有一些经验。

If you don’t have any or feel that a review of either one would be helpful, please refer to our quick overview on Zuul and our guide to OAuth2.

如果你没有,或者觉得对这两者的审查会有帮助,请参考我们的关于Zuul的快速概述和我们的OAuth2指南。

2. OAuth2 Client and Resource Server

2.OAuth2客户端和资源服务器

There are four different roles within OAuth2 we need to consider:

在OAuth2中,有四个不同的角色我们需要考虑。

  • Resource Owner — an entity that is able to grant access to its protected resources
  • Authorization Server — grants access tokens to Clients after successfully authenticating Resource Owners and obtaining their authorization
  • Resource Server — a component that requires an access token to allow, or at least consider, access to its resources
  • Client — an entity that is capable of obtaining access tokens from authorization servers

Annotating our configuration class with @EnableResourceServer, or @EnableOAuth2Sso, instructs Spring to configure components that transform our application into one of the latter two roles mentioned above.

@EnableResourceServer@EnableOAuth2Sso来注解我们的配置类,指示Spring配置将我们的应用程序转变为上述后两种角色之一的组件。

The @EnableResourceServer annotation enables our application to behave as a Resource Server by configuring an OAuth2AuthenticationProcessingFilter and other equally important components.

@EnableResourceServer注解通过配置OAuth2AuthenticationProcessingFilter和其他同样重要的组件,使我们的应用程序能够作为Resource Server行事。

Check out the ResourceServerSecurityConfigurer class to get a better idea on what’s being configured behind the scenes.

查看ResourceServerSecurityConfigurer类,以更好地了解幕后配置的内容。

Conversely, the @EnableOAuth2Sso annotation transforms our application into an OAuth2 client. It instructs Spring to configure an OAuth2ClientAuthenticationProcessingFilter, along with other components that our application needs to be capable of obtaining access tokens from an authorization server.

相反,@EnableOAuth2Sso注解将我们的应用程序转变为一个OAuth2客户端。它指示Spring配置一个OAuth2ClientAuthenticationProcessingFilter,以及我们的应用程序需要的其他组件,以便能够从授权服务器获得访问令牌。

Take a look at the SsoSecurityConfigurer class for further details on what Spring configures for us.

看看SsoSecurityConfigurer类,了解Spring为我们配置的进一步细节。

Combining these annotations with some properties enables us to get things up and running quickly. Let’s create two different applications to see them in action and how they can complement each other:

将这些注解与一些属性结合起来,使我们能够快速启动和运行。让我们创建两个不同的应用程序来看看它们是如何运作的,以及它们是如何相互补充的。

  • Our first application is going to be our edge node, a simple Zuul application that is going to use @EnableOAuth2Sso annotation. It’s going to be responsible for authenticating users (with the help of an Authorization Server) and delegate incoming requests to other applications
  • The second application is going to use @EnableResourceServer annotation and will allow access to protected resources if the incoming requests contain a valid OAuth2 access token

3. Zuul – @EnableOAuth2Sso

3. Zuul – @EnableOAuth2Sso.

Let’s start by creating a Zuul application that is going to act as our edge node and is going to be responsible for authenticating users using an OAuth2 Authorization Server:

让我们先创建一个Zuul应用程序,作为我们的边缘节点,负责使用OAuth2AuthorizationServer来验证用户。

@Configuration
@EnableZuulProxy
@EnableOAuth2Sso
@Order(value = 0)
public class AppConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices 
      resourceServerTokenServices;

    @Override
    public void configure(HttpSecurity http) throws Exception { 
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authorization-server-1/**",
              "/login").permitAll()
            .anyRequest().authenticated().and()
            .logout().permitAll().logoutSuccessUrl("/");
    }
}

Annotating our Zuul application with @EnableOAuth2Sso also notifies Spring to configure an OAuth2TokenRelayFilter filter. This filter retrieves previously obtained access tokens from users’ HTTP sessions and propagates them downstream.

@EnableOAuth2Sso来注释我们的Zuul应用程序也通知Spring配置OAuth2TokenRelayFilter过滤器。这个过滤器从用户的HTTP会话中检索先前获得的访问令牌,并将其传播到下游。

Note that we’re also using the @Order annotation in our AppConfiguration configuration class. This is to make sure that Filters created by our WebSecurityConfigurerAdapter take precedence over Filters created by other WebSecurityConfigurerAdapters.

请注意,我们在AppConfiguration配置类中也使用了@Order注释。这是为了确保由我们的WebSecurityConfigurerAdapter创建的Filters优先于由其它WebSecurityConfigurerAdapters创建的Filters

For example, we could annotate our Zuul application with @EnableResourceServer to support both HTTP Session identifiers and OAuth2 access tokens. However, doing so creates new Filters that by default, take precedence over the ones created by AppConfiguration class. This happens because ResouceServerConfiguration, a configuration class triggered by @EnableResourceServer, specifies a default order of 3 while WebSecurityConfigureAdapter has a default order of 100.

例如,我们可以用@EnableResourceServer注释我们的Zuul应用程序,以支持HTTP会话标识符和OAuth2访问令牌。然而,这样做会创建新的Filters,默认情况下,它优先于AppConfiguration类创建的Filters。这是因为ResouceServerConfiguration,一个由@EnableResourceServer触发的配置类,指定的默认顺序为3,而WebSecurityConfigureAdapter的默认顺序为100。

Before we move onto our Resource Server, we need to configure some properties:

在我们转向我们的资源 服务器之前,我们需要配置一些属性。

zuul:
  routes:
    resource-server-mvc-1: /resource-server-mvc-1/**
    authorization-server-1:
      sensitiveHeaders: Authorization
      path: /authorization-server-1/**
      stripPrefix: false
  add-proxy-headers: true

security:
  basic:
    enabled: false
  oauth2:
    sso:
      loginPath: /login
    client:
      accessTokenUri: http://localhost:8769/authorization-server-1/oauth/token
      userAuthorizationUri: /authorization-server-1/oauth/authorize
      clientId: fooClient
      clientSecret: fooSecret
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      serviceId: ${PREFIX:}resource

Without going into too much detail, using this config, we are:

不谈太多细节,使用这个配置,我们是。

  • Configuring our Zuul routes and saying which headers should be added/removed before sending requests downstream.
  • Setting some OAuth2 properties for our application to be able to communicate with our Authorization Server and configuring JWT with symmetric encryption.

4. API – @EnableResourceServer

4.API – @EnableResourceServer

Now that we have our Zuul application in place, let’s create our Resource Server:

现在我们有了Zuul应用程序,让我们创建我们的ResourceServer

@SpringBootApplication
@EnableResourceServer
@Controller
@RequestMapping("/")
class ResourceServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ResourceServerApplication.class, args);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String helloWorld(Principal principal) {
        return "Hello " + principal.getName();
    }
}

It’s a simple application that exposes a single endpoint to return the name of the Principal that initiated the request.

这是一个简单的应用程序,它暴露了一个端点,以返回发起请求的Principalname

Let’s wrap up by configuring some properties:

让我们通过配置一些属性来进行总结。

security:
  basic:
    enabled: false
  oauth2:
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      service-id: ${PREFIX:}resource

Keep in mind that we need a valid access token (which is stored in the HTTP Session of the user in our edge node) to access the endpoint of our Resource Server.

请记住,我们需要一个有效的访问令牌(它存储在我们边缘节点的用户的HTTP会话中)访问我们的ResourceServer的端点。

5. Conclusion

5.总结

In this article, we explained the differences between the @EnableOAuth2Sso and @EnableResourceServer annotations. We also demonstrated how to use them with a practical example using Zuul and a simple API.

在这篇文章中,我们解释了@EnableOAuth2Sso@EnableResourceServer注释之间的区别。我们还通过一个使用Zuul和一个简单API的实际例子演示了如何使用它们。

The full implementation of this example can be found over on Github.

这个例子的完整实现可以在Github上找到over

When running locally, we can run and test the application at http://192.168.1.67:8765/resource-server-mvc-1

在本地运行时,我们可以在http://192.168.1.67:8765/resource-server-mvc-1上运行和测试应用程序。