引言
在现代 web 应用中,安全认证和授权是保障数据安全和用户隐私的核心机制。spring security 是 spring 框架下专为安全设计的模块,具有高度的可配置性和扩展性。而 jwt(json web token) 则是当前流行的认证解决方案,因其无状态、可扩展性强等特点被广泛应用于微服务和移动应用中。
本文将从以下几个部分详细介绍如何使用 spring security 和 jwt 实现一个完整的认证机制:
- jwt 认证流程概述
- spring security 的基本配置
- jwt 生成与解析
- 基于 spring security 的 jwt 安全配置
- 实现用户登录和认证
1. jwt 认证流程概述
jwt 的认证流程如下:
- 用户登录:用户通过用户名和密码发送请求给服务器。
- 服务器验证:服务器验证用户身份,验证通过后生成 jwt token。
- token 下发:服务器将生成的 token 返回给客户端。
- 后续请求携带 token:客户端在后续请求中将 jwt token 添加到请求头中,服务器通过解析和验证 token 确认请求的合法性。
这种方式的核心优势在于 token 是无状态的,服务器无需维护用户的会话信息,且 jwt 可在分布式系统中实现共享认证。
2. spring security 的基本配置
创建一个简单的 spring boot 项目,并添加 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>
配置 securityconfig 类
创建 securityconfig 类以配置 spring security 基本设置:
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder;
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("/login").permitall()
.anyrequest().authenticated();
}
}
上面的配置指定 /login 接口公开访问,其余接口需要认证后才能访问。
3. jwt 生成与解析
使用 jwt 库生成和解析 token。创建 jwtutil 工具类,实现生成和验证 jwt 的方法:
import io.jsonwebtoken.claims;
import io.jsonwebtoken.jwts;
import io.jsonwebtoken.signaturealgorithm;
import java.util.date;
public class jwtutil {
private static final string secret_key = "mysecretkey";
// 生成 jwt
public static string generatetoken(string username) {
return jwts.builder()
.setsubject(username)
.setissuedat(new date())
.setexpiration(new date(system.currenttimemillis() + 86400000)) // 24小时有效期
.signwith(signaturealgorithm.hs256, secret_key)
.compact();
}
// 解析 jwt
public static claims parsetoken(string token) {
return jwts.parser()
.setsigningkey(secret_key)
.parseclaimsjws(token)
.getbody();
}
}
4. 基于 spring security 的 jwt 安全配置
在 spring security 过滤链中添加 jwt 过滤器。实现一个 jwtauthenticationfilter 类,在每次请求时拦截并验证 token:
import javax.servlet.filterchain;
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
import org.springframework.security.authentication.usernamepasswordauthenticationtoken;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.security.web.authentication.www.basicauthenticationfilter;
import io.jsonwebtoken.claims;
public class jwtauthenticationfilter extends basicauthenticationfilter {
public jwtauthenticationfilter(authenticationmanager authmanager) {
super(authmanager);
}
@override
protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain chain)
throws ioexception, servletexception {
string token = request.getheader("authorization");
if (token == null || !token.startswith("bearer ")) {
chain.dofilter(request, response);
return;
}
claims claims = jwtutil.parsetoken(token.replace("bearer ", ""));
string username = claims.getsubject();
if (username != null) {
usernamepasswordauthenticationtoken auth = new usernamepasswordauthenticationtoken(username, null, new arraylist<>());
securitycontextholder.getcontext().setauthentication(auth);
}
chain.dofilter(request, response);
}
}
将 jwtauthenticationfilter 过滤器添加到 securityconfig 中:
@override
protected void configure(httpsecurity http) throws exception {
http.csrf().disable()
.authorizerequests()
.antmatchers("/login").permitall()
.anyrequest().authenticated()
.and()
.addfilter(new jwtauthenticationfilter(authenticationmanager()));
}
5. 实现用户登录和认证
创建一个登录控制器 authcontroller,验证用户后生成 jwt:
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.httpservletresponse;
@restcontroller
public class authcontroller {
@postmapping("/login")
public void login(@requestparam string username, @requestparam string password, httpservletresponse response) {
// 这里简单校验用户名密码
if ("user".equals(username) && "password".equals(password)) {
string token = jwtutil.generatetoken(username);
response.setheader("authorization", "bearer " + token);
} else {
response.setstatus(httpservletresponse.sc_unauthorized);
}
}
}
以上代码实现了一个简单的登录接口,用户登录成功后将返回 jwt token,并将该 token 存储在响应头中。
6. 测试与验证
- 获取 token:使用客户端(例如 postman)请求
/login接口,得到包含 jwt token 的响应头。 - 访问受保护接口:将 token 添加到请求头
authorization中,再次请求受保护接口,验证是否可以成功访问。
结论
通过以上步骤,我们实现了一个基于 spring security 和 jwt 的安全认证系统。在实际项目中,可以进一步扩展此功能,例如集成数据库实现用户管理、配置 jwt 自动续签等。这种基于 jwt 的无状态认证适用于分布式系统和微服务架构,有助于提高系统的安全性和可扩展性。
以上就是使用spring security和jwt实现安全认证机制的详细内容,更多关于spring security jwt安全认证的资料请关注代码网其它相关文章!
发表评论