当前位置: 代码网 > it编程>编程语言>Java > 使用Spring Security和JWT实现安全认证机制

使用Spring Security和JWT实现安全认证机制

2024年11月04日 Java 我要评论
引言在现代 web 应用中,安全认证和授权是保障数据安全和用户隐私的核心机制。spring security是spring 框架下专为安全设计的模块,具有高度的可配置性和扩展性。而jwt(json w

引言

在现代 web 应用中,安全认证和授权是保障数据安全和用户隐私的核心机制。spring security 是 spring 框架下专为安全设计的模块,具有高度的可配置性和扩展性。而 jwt(json web token) 则是当前流行的认证解决方案,因其无状态、可扩展性强等特点被广泛应用于微服务和移动应用中。

本文将从以下几个部分详细介绍如何使用 spring security 和 jwt 实现一个完整的认证机制:

  1. jwt 认证流程概述
  2. spring security 的基本配置
  3. jwt 生成与解析
  4. 基于 spring security 的 jwt 安全配置
  5. 实现用户登录和认证

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. 测试与验证

  1. 获取 token:使用客户端(例如 postman)请求 /login 接口,得到包含 jwt token 的响应头。
  2. 访问受保护接口:将 token 添加到请求头 authorization 中,再次请求受保护接口,验证是否可以成功访问。

结论

通过以上步骤,我们实现了一个基于 spring security 和 jwt 的安全认证系统。在实际项目中,可以进一步扩展此功能,例如集成数据库实现用户管理、配置 jwt 自动续签等。这种基于 jwt 的无状态认证适用于分布式系统和微服务架构,有助于提高系统的安全性和可扩展性。

以上就是使用spring security和jwt实现安全认证机制的详细内容,更多关于spring security jwt安全认证的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com