1. 概述

在这个教程中,我们将探讨如何配置Spring Security,以便为不同的URL模式使用不同的安全配置。这对于应用程序需要对某些操作进行更严格的安全控制,而其他操作则对所有用户开放的情况非常有用。

2. 设置

让我们从设置应用开始。

我们需要添加websecurity依赖来创建这个服务。首先,在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-security</artifactId> 
</dependency> 

3. 创建API

我们将创建一个RESTful web服务,包含两个API:产品API和客户API。为此,我们将设置两个控制器。

3.1. 产品API

创建ProductController。它包含一个方法getProducts,返回产品列表:

@RestController("/products")
public class ProductController {
    
    @GetMapping
    public List<Product> getProducts() {
        return new ArrayList<>(Arrays.asList(
          new Product("Product 1", "Description 1", 1.0),
          new Product("Product 2", "Description 2", 2.0)
        ));
    }
}

3.2. 客户API

同样地,定义CustomerController

@RestController("/customers")
public class CustomerController {
    
    @GetMapping("/{id}")
    public Customer getCustomerById(@PathVariable("id") String id) {
        return new Customer("Customer 1", "Address 1", "Phone 1");
    }
}

在典型的Web应用中,包括访客在内的所有用户都可以获取产品列表。但是,通过ID获取客户详细信息似乎只有管理员才能做。因此,我们将以一种方式定义我们的安全配置,使其能够实现这一点。

4. 配置安全设置

当我们向项目中添加Spring Security时,它会默认禁用对所有API的访问。因此,我们需要配置Spring Security以允许访问API。

创建SecurityConfiguration类:

@Configuration
public class SecurityConfiguration {

     @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http.authorizeHttpRequests(request -> request.requestMatchers(new AntPathRequestMatcher("/products/**"))
                .permitAll())
            .authorizeHttpRequests(request -> request.requestMatchers(new AntPathRequestMatcher("/customers/**"))
                .hasRole("ADMIN")
                .anyRequest()
                .authenticated())
            .httpBasic(Customizer.withDefaults())
            .build();
    }
}

在这里,我们创建了一个SecurityFilterChain bean来配置应用的安全性。此外,为了支持基本身份验证,我们需要为我们的应用配置用户

我们将逐行理解代码。

4.1. 允许请求到产品API

  • authorizeRequests():此方法告诉Spring在授权请求时使用以下规则。
  • antMatchers("/products/**"):指定安全配置适用的URL模式。我们将其与permitAll()操作链接。如果请求路径包含“*/products”*,则允许请求到达控制器。
  • 我们可以使用and()方法添加更多的规则到配置中。

这标志着规则链的结束。接下来的规则也将应用于请求。因此,我们需要确保我们的规则之间没有冲突。一个好的做法是将通用规则放在顶部,具体规则放在底部。

4.2. 只允许管理员访问客户API

现在来看看配置的第二部分:

  • 要开始新的规则,我们可以再次使用authorizeRequests()方法。
  • antMatchers("/customers/**").hasRole("ADMIN"):如果URL路径包含“*/customers"`,我们将检查发出请求的用户是否具有"ADMIN"角色。

如果用户未经过身份验证,这将导致“401未经授权”错误。如果用户没有正确的角色,这将导致“403禁止”错误。

4.3. 默认规则

我们已经添加了匹配某些请求的规则。现在,我们需要为其余请求定义一些默认行为。

anyRequest().authenticated() - anyRequest()定义了一个规则链,适用于所有未匹配先前规则的请求。在我们的例子中,只要请求经过身份验证,这些请求就会被通过。

请注意,配置中只能有一个默认规则,并且它必须位于最后。如果我们尝试在添加默认规则后添加规则,我们将收到错误消息 - *"不能在anyRequest之后配置antMatchers"*。

5. 测试

现在使用cURL测试两个API。

5.1. 测试产品API

$ curl -i http://localhost:8080/products
[
  {
    "name": "Product 1",
    "description": "Description 1",
    "price": 1.0
  },
  {
    "name": "Product 2",
    "description": "Description 2",
    "price": 2.0
  }
]

我们如预期收到了两个产品响应。

5.2. 测试客户API

$ curl -i http://localhost:8080/customers/1

响应体为空。

如果我们查看头信息,我们会看到“401未经授权”的状态。这是因为客户API只允许具有"ADMIN"角色的已认证用户访问。

现在让我们尝试在请求中添加身份验证信息:

$ curl -u admin:password -i http://localhost:8080/customers/1 
{
  "name": "Customer 1",
  "address": "Address 1",
  "phone": "Phone 1"
}

太棒了!现在我们可以访问客户API了。

6. 总结

在这篇教程中,我们学习了如何在Spring Boot应用中设置Spring Security。我们还涵盖了使用antMatchers()方法根据URL模式进行特定配置的方法。

如往常一样,本教程的代码可以在GitHub上找到