如何使用Spring Security和JSON Web保护您的REST API

作者:API传播员 · 2026-01-12 · 阅读时间:5分钟
本文详细介绍了如何使用Spring Security和JSON Web Token (JWT) 保护REST API,包括配置Spring Boot应用程序、生成JWT密钥、设置OAuth2资源服务器以及测试API安全性的完整步骤,帮助开发者实现用户身份验证和资源访问控制。

使用 Spring Security 和 JSON Web Token (JWT) 保护 REST API

在现代Spring Boot 应用程序,使其能够通过 JWT 验证用户身份,并保护 API 资源的访问


什么是 JSON Web Token (JWT)?

JWT 是一种开放标准(RFC 7519),用于在双方之间以安全的方式传递信息。它的结构由三部分组成:

  1. Header(标头):包含令牌的元信息,例如所使用的签名算法(如 HS256)。
  2. Payload(有效载荷):存储实际数据,例如用户信息和声明。
  3. Signature(签名):通过对标头和有效载荷进行加密生成,用于验证令牌的完整性。

JWT 的格式如下:

HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)

最终生成的 JWT 是一个由 . 分隔的字符串,包含上述三部分。


构建安全的 REST API

在本文的示例中,我们将创建一个 Spring Boot 应用程序,其中包含以下功能:

  1. 一个客户端应用程序(例如前端或命令行工具)通过 REST API 调用服务器。
  2. 服务器应用程序通过 JWT 验证客户端请求的合法性。
  3. 保护三个 REST 控制器资源:产品、订单和客户。

当客户端未提供有效的身份验证令牌时,服务器将返回 401 Unauthorized 响应。


配置 Spring Security 和 OAuth2 资源服务器

添加依赖项

在 Spring Boot 项目中添加以下依赖项:


  org.springframework.boot
  spring-boot-starter-oauth2-resource-server

该依赖项包含了 Spring Security 的所有必要组件。

创建自定义安全配置

config 包中创建一个名为 SecurityConfig 的类,用于配置安全规则:

  1. 禁用 CSRF(跨站请求伪造)。
  2. 要求所有请求都必须经过身份验证。
  3. 配置 HTTP Basic 身份验证。
  4. 配置 OAuth2 资源服务器以支持 JWT。

示例代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2ResourceServer()
                .jwt();
    }
}

使用 JWT 进行身份验证

生成公钥和私钥

为了使用 JWT,您需要生成一对公钥和私钥。以下是使用 OpenSSL 生成密钥的命令:

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
openssl pkcs8 -topk8 -inform PEM -outform PEM -in private.pem -out private_key.pem -nocrypt

将生成的密钥文件存储在项目的 src/main/resources/certs 目录下。

配置 JWT 解码器

config 包中创建一个名为 RsaKeyProperties 的类,用于加载密钥配置:

@ConfigurationProperties(prefix = "rsa")
public record RsaKeyProperties(Resource privateKey, Resource publicKey) {}

application.properties 文件中添加以下配置:

rsa.private-key=classpath:certs/private_key.pem
rsa.public-key=classpath:certs/public.pem

然后,在 SecurityConfig 中定义一个 JwtDecoder Bean:

@Bean
public JwtDecoder jwtDecoder(RsaKeyProperties rsaKeyProperties) {
    return NimbusJwtDecoder.withPublicKey(rsaKeyProperties.publicKey()).build();
}

创建身份验证控制器

controller 包中创建一个名为 AuthController 的类,用于处理用户登录并生成 JWT:

@RestController
@RequestMapping("/auth")
public class AuthController {

    private final JwtEncoder jwtEncoder;    public AuthController(JwtEncoder jwtEncoder) {
        this.jwtEncoder = jwtEncoder;
    }    @PostMapping("/token")
    public ResponseEntity generateToken(@RequestBody AuthRequest authRequest) {
        // 验证用户名和密码
        // 如果验证成功,生成 JWT
        String token = jwtEncoder.encode(...);
        return ResponseEntity.ok(token);
    }
}

测试 JWT 保护的 API

使用 Postman 测试

  1. /auth/token 端点发送 POST 请求,提供用户名和密码。
  2. 将返回的 JWT 复制到 Authorization 标头中,并向受保护的资源发送请求。

使用命令行工具测试

使用 curlhttpie 工具测试 API:

http POST :8080/auth/token username=user password=pass
http GET :8080 Authorization:"Bearer "

自动化测试

为确保安全配置的正确性,建议编写自动化测试。添加以下依赖项:


  org.springframework.security
  spring-security-test
  test

在测试中,可以使用 @WithMockUser 注解模拟身份验证用户,并验证受保护资源的访问逻辑。


总结

通过本文的教程,您已经学会了如何使用 Spring Security 和 JSON Web Token (JWT) 来保护 REST API 的安全性。无论是配置资源服务器、生成和验证 JWT,还是测试 API 的安全性,这些步骤都为构建安全的应用程序提供了坚实的基础。

原文链接: https://www.danvega.dev/blog/spring-security-jwt