引言
在现代 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安全认证的资料请关注代码网其它相关文章!
发表评论