Spring Boot + JWT实现安全认证

在现代Web应用中,安全性是一个至关重要的方面。而JWT(JSON Web Token)是一种非常流行的实现用户认证和信息交换的方式。本文将介绍如何在Spring Boot应用中集成JWT,并提供相应的代码示例。

什么是JWT?

JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于以JSON对象传递信息,信息可以被验证和信任。JWT的好处在于它可以方便地用于身份验证和信息交换,它具有以下特点:

  • 紧凑性:JWT的大小相对较小,可以通过URL、POST参数或者HTTP头部传输。
  • 自包含:JWT包含了用户的所有信息,避免了多次查询数据库。
  • 安全性:通过签名可以确保JWT的完整性和有效性。

Spring Boot项目设置

首先,我们需要在Spring Boot项目中添加相关依赖。我们可以在pom.xml文件中添加以下内容:

<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>

生成JWT

我们需要创建一个JWT工具类来生成和解析JWT:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "your_secret_key"; // 秘钥
    private static final long EXPIRATION = 864_000_00; // 过期时间,单位毫秒

    // 生成JWT
    public static String generateToken(String username) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        JwtBuilder builder = Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(new Date(nowMillis + EXPIRATION))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY);

        return builder.compact();
    }

    // 验证JWT
    public static Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }
}

实现用户认证

接下来,我们需要实现一个简单的用户认证功能。可以创建一个控制器来处理登录请求:

import org.springframework.web.bind.annotation.*;

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

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        // 此处应该查询数据库验证用户信息,这里为了简化直接返回token
        if ("user".equals(username) && "password".equals(password)) {
            return JwtUtil.generateToken(username);
        } else {
            throw new RuntimeException("用户名或密码错误");
        }
    }
}

添加过滤器验证JWT

为了保护需要认证的接口,我们可以添加JWT过滤器,验证请求中的JWT:

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.filter.OncePerRequestFilter;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");

        // 检查header中是否包含Bearer Token
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7); // 获取token
            try {
                Claims claims = JwtUtil.parseToken(token);
                // 可以将用户信息存储在上下文中,以备后用
                request.setAttribute("username", claims.getSubject());
            } catch (Exception e) {
                throw new RuntimeException("无效的token");
            }
        }

        filterChain.doFilter(request, response); // 继续过滤链
    }
}

配置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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/auth/login").permitAll() // 登录接口放行
            .anyRequest().authenticated() // 其他请求需要认证
            .and()
            .addFilter(new JwtAuthenticationFilter());
    }
}

总结

通过以上步骤,我们实现了一个简单的Spring Boot应用,利用JWT进行用户身份认证。用户在登录后会收到一个JWT,后续的请求需要在请求头中携带这个JWT进行身份验证。这种方式不仅简化了用户认证流程,还提高了应用的安全性。可以根据具体需求进一步扩展功能,如密码加密、黑名单策略等。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部