1、概览 {#1概览}
本文将带你了解如何在 Spring Security 中针对不同的 URL 进行不同的安全配置。
2、设置 {#2设置}
创建应用,在 pom.xml
中添加 Web 和 Security 依赖:
<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 {#3创建-api}
创建一个包含两个 API 的 RESTful 服务:Product(产品) API 和 Customer(客户) API。
3.1、Product API {#31product-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、Customer API {#32customer-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、设置安全配置 {#4设置安全配置}
创建 SecurityConfiguration
:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/products/**")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/customers/**")
.hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build();
}
}
如上,创建了一个 SecurityFilterChain
Bean 来配置应用的安全设置。
此外,还需要为应用配置用户,用于 Basic Authentication(认证)。
4.1、允许请求 Product API {#41允许请求-product-api}
authorizeRequests()
:该方法告诉 Spring 在授权请求时使用以下规则。antMatchers("/products/**")
:这指定了安全配置适用的 URL 模式。将其与permitAll()
操作进行了链接。如果请求路径中包含/products
,则允许请求进入 Controller。- 可以使用
and()
方法在配置中添加更多规则。
这标志着一连串规则的结束。后面的其他规则也将应用于请求。因此,需要确保规则不会相互冲突。一个好的做法是在顶部定义通用规则,在底部定义更具体的规则。
4.2、仅允许 Admin 访问 Customer API {#42仅允许-admin-访问-customer-api}
现在来看看配置的第二部分:
- 使用
authorizeRequests()
方法开启新的规则。 antMatchers("/customers/**").hasRole("ADMIN")
:如果 URL 路径中包含/customers
,就会检查请求用户是否具有ADMIN
角色。
如果用户未通过身份认证,将导致 "401 Unauthorized" 错误。如果用户没有正确的角色,则会导致 "403 Forbidden" 错误。
4.3、默认规则 {#43默认规则}
现在已经添加了匹配某些请求的匹配项。现在,为其他请求定义一些默认行为。
anyRequest().authenticated()
- anyRequest()
为任何不符合前面规则的请求定义了一个规则链。在本例中,只要这些请求通过了身份认证,就会被通过。
注意,配置中只能有一条默认规则,而且必须放在最后。如果试图在添加默认规则后再添加规则,就会出现异常 - "Can't configure antMatchers after anyRequest"。
5、测试 {#5测试}
使用 cURL 测试这两个 API。
5.1、测试 Product API {#51测试-product-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、测试 Customer API {#52测试-customer-api}
$ curl -i http://localhost:8080/customers/1
响应体为空。
查看响应 Header,就会看到 "401 Unauthorized" 状态码。这是因为只有通过身份认证的 ADMIN
用户才能访问 Customer API。
现在,在请求中添加认证信息后再试一次:
$ curl -u admin:password -i http://localhost:8080/customers/1
{
"name": "Customer 1",
"address": "Address 1",
"phone": "Phone 1"
}
成功地访问了 Customer API。
6、总结 {#6总结}
本文介绍了如何在 Spring Boot 应用中设置 Spring Security,以及如何使用 antMatchers()
方法为不同的 URL 设置不同的认证、授权规则。
参考:https://www.baeldung.com/spring-security-configuring-urls