返回

极简入门!在 Spring Security 项目中集成了 JWT 令牌,畅通无阻地访问 API

后端

在现代网络环境中,安全可靠的用户身份验证至关重要。JSON Web Token (JWT) 令牌提供了一种基于 JSON 的轻量级且可扩展的身份验证机制,使开发者能够轻松安全地管理用户访问权限。本文将详细介绍如何在 Spring Security 项目中集成 JWT 令牌,确保您的 API 通行无阻。

一、概述

JWT 令牌由头部、载荷和签名三部分组成。头部包含元数据,如令牌类型和签名算法;载荷包含用户声明,如用户名、角色和到期时间;签名则是头部和载荷的哈希值生成的唯一签名。JWT 令牌的优点包括易用性、跨平台支持、安全性和轻量级。

二、Spring Security 中集成 JWT

1. 导入 Spring Security 依赖项

pom.xml 文件中添加 Spring Security 和 JWT 相关的依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

2. 配置 Spring Security 安全配置类

创建一个配置类,启用 Spring Security 并配置 JWT 过滤器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public UsernamePasswordAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter();
        filter.setAuthenticationManager(authenticationManagerBean());
        return filter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

3. 生成 JWT 令牌

创建一个工具类,用于生成 JWT 令牌:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JWTGenerator {

    public String generateToken(String username) {
        long now = System.currentTimeMillis();
        long exp = now + (30 * 60 * 1000); // 30 分钟后过期

        String secretKey = "mySecretKey";

        return Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(exp))
                .signWith(SignatureAlgorithm.HS512, secretKey)
                .compact();
    }
}

4. 在请求头中包含 JWT 令牌

在控制器中,从请求头中获取 JWT 令牌并进行验证:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    @GetMapping("/api/data")
    public String getData(@RequestHeader("Authorization") String token) {
        if (token != null && token.startsWith("Bearer ")) {
            String jwtToken = token.substring(7);
            if (JWTVerifier.verifyToken(jwtToken)) {
                return "Access granted!";
            }
        }
        return "Access denied!";
    }
}

5. 验证 JWT 令牌

在上面的代码示例中已经包含了验证 JWT 令牌的逻辑。JWTVerifier.verifyToken 方法会检查令牌的签名是否有效。

三、常见问题解答

  • JWT 令牌是否可以存储敏感数据?
    不建议在 JWT 载荷中存储高度敏感的数据。

  • JWT 令牌如何防止重放攻击?
    使用到期时间来限制令牌的生命周期,防止重放攻击。

  • 如何确保 JWT 令牌的安全性?
    选择强健的签名算法和密钥,并定期轮换密钥以增强安全性。

  • JWT 令牌是否支持授权?
    JWT 令牌主要用于身份验证,但可以通过在载荷中包含角色或权限信息来实现授权。

  • 在哪些场景中使用 JWT 令牌比较合适?
    JWT 令牌适用于需要轻量级、安全和跨平台的身份验证的场景,例如 API 访问控制和单点登录。

四、结论

JWT 令牌提供了一种高效且安全的机制,用于在现代网络应用中管理用户身份验证。通过集成 JWT 令牌,开发者可以增强 API 的安全性,并简化用户访问管理。拥抱 JWT 令牌,让您的应用更加安全可靠。