使用Java JWT实现无状态认证和授权功能

JSON Web Token(JWT)是一种用于身份验证和授权的开放标准,可以实现无状态的RESTful API认证。在这篇文章中,我们将介绍如何使用Java JWT库实现无状态认证和授权功能。

一、JWT的基础知识

JWT包含三个部分:头部、载荷和签名。头部指定算法类型和签名类型。常用的算法有:HMAC、RSA和ECDSA。载荷包含一些声明,例如:发布者、过期时间、主题、受众等。签名是由头部和载荷使用指定的算法生成的,可以验证消息是否被篡改。当客户端向服务器发送请求时,它应发送JWT作为 Authorization 头的值。

二、使用Java JWT实现JWT生成和验证

使用Java JWT库可以方便地生成和验证JWT。以下是生成JWT的示例代码:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JWTGenerator {

    public static String generateToken(String issuer, String subject, long ttlMillis, Map claims) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 使用随机数作为JWT的ID
        String jwtId = UUID.randomUUID().toString();

        JwtBuilder builder = Jwts.builder()
                .setId(jwtId)
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuer)
                .claim("data", claims)
                .signWith(SignatureAlgorithm.HS256, "secret");

        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        return builder.compact();
    }

}

使用Java JWT库验证JWT非常简单。下面是一个示例代码:

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

public class JWTVerifier {
    
    public static Claims verifyToken(String jwtToken) {
        Claims claims = Jwts.parser()
        	.setSigningKey("secret")
        	.parseClaimsJws(jwtToken)
        	.getBody();
        return claims;
    }
    
}

三、使用JWT实现无状态认证和授权功能

通常,使用JWT的有状态应用程序可以使用JWT来实现无状态RESTful API认证。以下是一个实现JWT认证和授权的示例代码:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;

public class JWTFilter {

    // 在这里替换成您的密钥
    private static final String SECRET = "mySecretKey";

    public void filter(ContainerRequestContext requestContext) throws JwtException {

        // 从头部获取JWT
        MultivaluedMap headers = requestContext.getHeaders();
        List authHeader = headers.get("Authorization");

        if (authHeader == null || authHeader.isEmpty()) {
            throw new JwtException("Missing or invalid authorization header");
        }

        String jwtToken = authHeader.get(0).split(" ")[1];

        // 如果token验证不成功则不会添加security context
        if (isTokenValid(jwtToken)) {
            // 获取JWT中的声明信息
            Claims claims = JWTVerifier.verifyToken(jwtToken);

            // 获取JWT中用户数据
            String user = claims.getSubject();

            // 添加用户身份到请求属性中
            requestContext.setProperty("user", user);

            // 添加角色信息到请求属性列表
            String roles = (String) claims.get("roles");
            List roleList = Arrays.asList(roles.split(","));
            requestContext.setProperty("roles", roleList);
        }
    }

    private boolean isTokenValid(String jwtToken) {
        boolean isValid = false;

        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(jwtToken)
                    .getBody();

            Date now = new Date();
            if (now.before(claims.getExpiration())) {
                isValid = true;
            }
        } catch (Exception e) {
            isValid = false;
            throw new JwtException("Invalid JWT token");
        }

        return isValid;
    }
}

四、小结

在本文中,我们学习了如何使用Java JWT库实现无状态JWT认证和授权功能。我们了解了JWT的基础知识,并实现了JWT生成和验证方法。我们还提供了一个示例代码来说明如何将JWT用于无状态认证和授权功能。使用JWT可以大大简化身份验证和授权的复杂性,同时提高应用程序的安全性。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/311212.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2025-01-05 13:23
下一篇 2025-01-05 13:23

相关推荐

  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29
  • Java判断字符串是否存在多个

    本文将从以下几个方面详细阐述如何使用Java判断一个字符串中是否存在多个指定字符: 一、字符串遍历 字符串是Java编程中非常重要的一种数据类型。要判断字符串中是否存在多个指定字符…

    编程 2025-04-29
  • VSCode为什么无法运行Java

    解答:VSCode无法运行Java是因为默认情况下,VSCode并没有集成Java运行环境,需要手动添加Java运行环境或安装相关插件才能实现Java代码的编写、调试和运行。 一、…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29
  • Java 8 Group By 会影响排序吗?

    是的,Java 8中的Group By会对排序产生影响。本文将从多个方面探讨Group By对排序的影响。 一、Group By的概述 Group By是SQL中的一种常见操作,它…

    编程 2025-04-29

发表回复

登录后才能评论