# Spring 中基于 OAuth2 的身份验证和授权

> 原文： [https://javatutorial.net/what-is-oauth2-based-authentication-and-authorization-in-spring](https://javatutorial.net/what-is-oauth2-based-authentication-and-authorization-in-spring)

OAuth2 允许第三方应用程序代表资源所有者或通过允许第三方应用程序代表自己获取对 HTTP 服务的有限访问权限，该服务是代表资源所有者的。 借助 OAuth2，服务提供商和消费者应用程序可以安全地相互交互。

![spring-featured-image](img/d2f73752d8ae931b119dec1eac866973.jpg)

## 工作流程

从外部应用程序访问用户的受保护数据之前，需要执行几个步骤。

1.  用户被带到服务提供商服务器
    1.  例如 Facebook 或 LinkedIn
2.  用户必须授予外部应用程序许可才能访问有关其数据的资源，例如读取甚至写入。
3.  授权服务器将访问令牌发送到消费者应用程序。
4.  现在，外部应用程序可以从资源服务器访问用户的受保护数据。

## 不同角色的术语

在 OAuth2 中，有 4 个角色：

1.  资源所有者
    1.  用户
2.  资源服务器
    1.  托管受保护资源并根据访问令牌提供对其访问权限的服务器
3.  客户
    1.  寻求许可的外部应用
4.  授权服务器
    1.  在验证用户身份后发出访问令牌

## 不同的令牌

有两种类型的令牌：

1.  访问令牌
    1.  授权服务器根据用户身份验证提供
    2.  允许第三方应用程序访问用户数据
2.  刷新令牌
    1.  用于在原始令牌到期时获取新的访问令牌，因此名称
    2.  但是由于安全原因，并非总是可能获得此令牌

## `@EnableOAuth2Sso`

```java
@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("/auth-server/**", "/login")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .logout()
            .permitAll()
            .logoutSuccessUrl("/");
    }
}
```

`@EnableOAuth2Sso`注释通知 Spring 配置[`OAuth2TokenRelayFilter`](https://github.com/spring-cloud/spring-cloud-security/blob/master/spring-cloud-security/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java)。 此过滤器从用户的 HTTP 会话中检索已获取的访问令牌，并填充它们。

`@Order`注解的工作是确保由我们的`WebSecurityConfigurerAdapter`创建的过滤器优先于由另一个`WebSecurityConfigurerAdapter`创建的过滤器。

## `@EnableResourceServer`

现在，让我们设置资源服务器。

```java
@SpringBootApplication
@EnableResourceServer
@Controller
@RequestMapping("/")
class ResourceServerImplementation {

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

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String greetPrincipal(Principal principal) {
        return "Greetings, " + principal.getName();
    }
}
```

该应用程序返回发起该请求的主体的名称。 同样，我们需要一个有效的访问令牌才能访问资源服务器的端点。

这 2 个代码段摘自[此处](https://www.baeldung.com/spring-security-oauth2-enable-resource-server-vs-enable-oauth2-sso)。