如何使用 Apache Commons Codec 在 Java 中解码 JWT(标题和正文)?

Posted

技术标签:

【中文标题】如何使用 Apache Commons Codec 在 Java 中解码 JWT(标题和正文)?【英文标题】:How to decode JWT (Header and Body) in java using Apache Commons Codec? 【发布时间】:2016-12-19 09:44:19 【问题描述】:

我正在寻找使用Apache Commons Codec 解码以下JWT。我们怎样才能做到这一点?

    eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0Iiwicm9sZXMiOiJST0xFX0FETUlOIiwiaXNzIjoibXlzZ
WxmIiwiZXhwIjoxNDcxMDg2MzgxfQ.1EI2haSz9aMsHjFUXNVz2Z4mtC0nMdZo6bo3-x-aRpw

这应该检索HeaderBodySignature 部分。代码是什么?

【问题讨论】:

【参考方案1】:

给你:

import org.apache.commons.codec.binary.Base64;
@Test
    public void testDecodeJWT()
        String jwtToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0Iiwicm9sZXMiOiJST0xFX0FETUlOIiwiaXNzIjoibXlzZWxmIiwiZXhwIjoxNDcxMDg2MzgxfQ.1EI2haSz9aMsHjFUXNVz2Z4mtC0nMdZo6bo3-x-aRpw";
        System.out.println("------------ Decode JWT ------------");
        String[] split_string = jwtToken.split("\\.");
        String base64EncodedHeader = split_string[0];
        String base64EncodedBody = split_string[1];
        String base64EncodedSignature = split_string[2];

        System.out.println("~~~~~~~~~ JWT Header ~~~~~~~");
        Base64 base64Url = new Base64(true);
        String header = new String(base64Url.decode(base64EncodedHeader));
        System.out.println("JWT Header : " + header);


        System.out.println("~~~~~~~~~ JWT Body ~~~~~~~");
        String body = new String(base64Url.decode(base64EncodedBody));
        System.out.println("JWT Body : "+body);        
    

下面的输出:

------------ Decode JWT ------------
~~~~~~~~~ JWT Header ~~~~~~~
JWT Header : "alg":"HS256"
~~~~~~~~~ JWT Body ~~~~~~~
JWT Body : "sub":"test","roles":"ROLE_ADMIN","iss":"myself","exp":1471086381

【讨论】:

【参考方案2】:

这是一种非包导入方式:

            java.util.Base64.Decoder decoder = java.util.Base64.getUrlDecoder();
            String[] parts = jwtToken.split("\\."); // split out the "parts" (header, payload and signature)

            String headerJson = new String(decoder.decode(parts[0]));
            String payloadJson = new String(decoder.decode(parts[1]));
            //String signatureJson = new String(decoder.decode(parts[2]));

不管(这个替代 org.apache.commons.codec.binary.Base64 SiKing'sanswer )...您可能还想将这些 json 片段推送到 pojo's。

然后您可以将这些 json 片段转换为 pojo。

标头是“动态的”(例如,您事先并不知道所有标头名称),因此您可能希望转换为键值对(在 java 中也称为“映射”)

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

public class JwtTokenHeaders 

    private final Map<String, Object> jsonMap; // = new HashMap<String, Object>();

    public JwtTokenHeaders(String jsonString) 

        ObjectMapper mapper = new ObjectMapper();
        //String jsonString = "\"name\":\"JavaInterviewPoint\", \"department\":\"blogging\"";

        //Map<String, Object> jsonMap = new HashMap<String, Object>();
        try 
            // convert JSON string to Map
            this.jsonMap = mapper.readValue(jsonString,
                    new TypeReference<Map<String, String>>() 
                    );
         catch (Exception ex) 
            throw new RuntimeException(ex);
        
    

    @Override
    public String toString() 
        return org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString(this);
    

payload(也就是body)定义更明确,所以你可以映射到一个pojo.....你可以在这里获取json并创建一个匹配的pojo:

http://pojo.sodhanalibrary.com/

在您使用在线工具(或自己手工制作 pojo)之后......创建类似“MyPojo(.java)”的东西......

你会得到这样的结果:

//import com.fasterxml.jackson.databind.DeserializationFeature;
//import com.fasterxml.jackson.databind.ObjectMapper;
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            MyPojo tp = mapper.readValue(payloadJson, MyPojo.class);

如果http://pojo.sodhanalibrary.com/ 将来不复存在,只需在互联网上搜索“online json to pojo”,您可能会找到一些东西。

【讨论】:

以上是关于如何使用 Apache Commons Codec 在 Java 中解码 JWT(标题和正文)?的主要内容,如果未能解决你的问题,请参考以下文章

Apache Commons-Codec的使用

org.apache.commons.codec.DecoderException:奇数个字符

apache commons codec

无法引用 org.apache.commons.codec.binary.Base64;

线程“主”java.lang.NoClassDefFoundError 中的异常:org/apache/commons/codec/DecoderException

java 调用apache.commons.codec的包简单实现MD5加密