将Java 8 Base64 JWT令牌转换为JSON [英] Java 8 Base64 JWT token into JSON

查看:185
本文介绍了将Java 8 Base64 JWT令牌转换为JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我在网上和此处在StackOverflow上对此进行了一些研究,并且尝试了很多发现的建议.问题是我正在登录运行良好的Oauth2服务之一.我得到一个Oath2 JWT令牌.我知道这是Base64编码的,可以将令牌放入jwt.io和www.base64decode.org中,并且这两个站点都可以正确解析令牌.

我正在使用Java 8 Base64工具,代码如下:

public String getTokenProperty(String token, String propertyName)
{
    byte[] bytes = Base64.getUrlDecoder().decode(token);
    String decodedString = new String(bytes, StandardCharsets.UTF_8);
    System.out.println("Decoded: " + decodedString);
    return (new JSONObject(decodedString)).getString(propertyName);
}

在解码器行上发生错误,如下所示:

java.lang.IllegalArgumentException: Illegal base64 character 2e

我使用Oauth2服务中的令牌尝试了此操作,我从Syncope获得了令牌,并从Auth0获得了令牌...所有返回的都是JWT Base64编码的令牌. 使用这些来自不同服务器的所有令牌,我得到了相同的错误.

我想使用标准的Java 8 Base64,但是我认为我可能需要使用外部第三方Base64解码器.

任何帮助都会很棒.谢谢!

令牌如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1qSTRRVFEwT1VRNU9VSXlSVEV6TlRBd05UVXpSVVExTlVOR05FVkVORGRDTlRnM016VXdRZyJ9.eyJodHRwczovL2JpdG9vbXRyYWRlci5uZXQvYXV0aG9yaXphdGlvbiI6eyJncm91cHMiOlsiQ29uc3VtZXJzIl0sInJvbGVzIjpbIlVzZXIiXX0sImlzcyI6Imh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWNhNTE5NzZjYzMzZjUxMTBhYWNkYmM0IiwiYXVkIjpbImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vYXBpL3YyLyIsImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNTU5MzIzNDI1LCJleHAiOjE1NTk0MDk4MjUsImF6cCI6IlliRGFSelRVQkFtZEFrSExqdjZ0bEI3U05xSTF1RlNtIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBhZGRyZXNzIHBob25lIHJlYWQ6Y3VycmVudF91c2VyIHVwZGF0ZTpjdXJyZW50X3VzZXJfbWV0YWRhdGEgZGVsZXRlOmN1cnJlbnRfdXNlcl9tZXRhZGF0YSBjcmVhdGU6Y3VycmVudF91c2VyX21ldGFkYXRhIGNyZWF0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIHVwZGF0ZTpjdXJyZW50X3VzZXJfaWRlbnRpdGllcyIsImd0eSI6InBhc3N3b3JkIn0.St7097L1ZAlBWcAPrie-8CGV2F3Fr8uNYpSDVKSPVPF4zBZrmm62_UAj7Ssux8AjUy0LhjiF3kLpNph2L7yrpUREw6TyGJwQasfdVtM5VzRYUcy-fOGyRSqPQorbzxJQZzs2pyDJm-2hMQ0McJ37ubKIWrHFD5McMedN6THK7g5TExX47XCRPcOuCEWm3bf3zdWF2LEGhCw_c-lcZDwlb4ePkO721XjSWtrXEBvxc8scFNaHDt7VOnrSze4XK_LO8eE8bHRq6qUrWf1csYucK--aHazBsvfdl-6QDRk-tOBM-LdXJMT7H8Ih6trxVmZofQjr2dQ4j_3DTVoU3eLdog

更新:

我从java,util.Base64切换到org.apache.commons.codec.binary.Base64 这似乎有些奏效,但现在我没有收到任何错误.

String decodedString = new String(bytes, StandardCharsets.UTF_8);

将标题,有效负载和签名数据的字符串返回给我.所以,当我这样做时:

JSONObject jsonObject = new JSONObject(decodedString);
    System.out.println("getTokenProperty: jsonObject = " + jsonObject.toString());

我只获取标头数据,而我真正需要的是有效载荷.

为了记录……我从概念验证"项目中继承的代码是:

public static String getTokenProperty(String token, String propertyName)
{
    return (new JSONObject(new String(Base64.getDecoder().decode(token)))).getString(propertyName);
}

,根本没有单元测试.因此,当我去进行单元测试时,它当然完全坏了.因此,现在我对如何解析此令牌有了更好的了解,并且我将在很长一段时间内牢记这一课.

非常感谢!

解决方案

之所以无法解析,是因为您正在尝试Base64URLDecode整个令牌.点".字符(十六进制为0x2e,十进制为46,HTML中为&#46-ASCII/UTF8)..

示例:

public static void decodeTokenParts(String token)
{
    String[] parts = token.split("\\.", 0);

    for (String part : parts) {
        byte[] bytes = Base64.getUrlDecoder().decode(part);
        String decodedString = new String(bytes, StandardCharsets.UTF_8);

        System.out.println("Decoded: " + decodedString);
    }
}

这是因为JWT令牌由以下部分组成:

例如

Base64URLEncode({HeaderJSON}) + "." + Base64URLEncode({PayloadJSON}) + "." + Signature ..

因此,要对其进行解码,您需要将其分隔为.".并解码每个部分.注意:签名通常是二进制的,编码为base64,因此一旦解码,就不要尝试打印它.它会打印字节.您需要验证签名.

例如,如果你去: https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwiiwibmFtZSI6IkpvaG4gRG9lIiwiaWF@JfQJ_QFQJ4K

您将看到每个部分"的编码方式.它是彩色编码的.

So, I have done some research on this on the Net and here on StackOverflow, and I have tried many, multiple suggestions that I have found. The problem is that I am logging into one of our Oauth2 services which is working well. I get an Oath2 JWT token. I know this is Base64 encoded, and I can drop the token into jwt.io and www.base64decode.org and both of these sites parse the token correctly.

I am using Java 8 Base64 tools, and the code looks as follows:

public String getTokenProperty(String token, String propertyName)
{
    byte[] bytes = Base64.getUrlDecoder().decode(token);
    String decodedString = new String(bytes, StandardCharsets.UTF_8);
    System.out.println("Decoded: " + decodedString);
    return (new JSONObject(decodedString)).getString(propertyName);
}

The error occurs on the decoder line as follows:

java.lang.IllegalArgumentException: Illegal base64 character 2e

I tried this with a token from my Oauth2 Service, I got a token from Syncope, and I got a token from Auth0 ... all return with JWT Base64 encoded tokens. With ALL these tokens from these different servers, I get the same error.

I would like to use the Java 8 Base64 which is standard, but I am thinking that I may need to use an external third-party Base64 decoder.

Any help would be great. Thanks!

The token is as follows:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1qSTRRVFEwT1VRNU9VSXlSVEV6TlRBd05UVXpSVVExTlVOR05FVkVORGRDTlRnM016VXdRZyJ9.eyJodHRwczovL2JpdG9vbXRyYWRlci5uZXQvYXV0aG9yaXphdGlvbiI6eyJncm91cHMiOlsiQ29uc3VtZXJzIl0sInJvbGVzIjpbIlVzZXIiXX0sImlzcyI6Imh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWNhNTE5NzZjYzMzZjUxMTBhYWNkYmM0IiwiYXVkIjpbImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vYXBpL3YyLyIsImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNTU5MzIzNDI1LCJleHAiOjE1NTk0MDk4MjUsImF6cCI6IlliRGFSelRVQkFtZEFrSExqdjZ0bEI3U05xSTF1RlNtIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBhZGRyZXNzIHBob25lIHJlYWQ6Y3VycmVudF91c2VyIHVwZGF0ZTpjdXJyZW50X3VzZXJfbWV0YWRhdGEgZGVsZXRlOmN1cnJlbnRfdXNlcl9tZXRhZGF0YSBjcmVhdGU6Y3VycmVudF91c2VyX21ldGFkYXRhIGNyZWF0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIHVwZGF0ZTpjdXJyZW50X3VzZXJfaWRlbnRpdGllcyIsImd0eSI6InBhc3N3b3JkIn0.St7097L1ZAlBWcAPrie-8CGV2F3Fr8uNYpSDVKSPVPF4zBZrmm62_UAj7Ssux8AjUy0LhjiF3kLpNph2L7yrpUREw6TyGJwQasfdVtM5VzRYUcy-fOGyRSqPQorbzxJQZzs2pyDJm-2hMQ0McJ37ubKIWrHFD5McMedN6THK7g5TExX47XCRPcOuCEWm3bf3zdWF2LEGhCw_c-lcZDwlb4ePkO721XjSWtrXEBvxc8scFNaHDt7VOnrSze4XK_LO8eE8bHRq6qUrWf1csYucK--aHazBsvfdl-6QDRk-tOBM-LdXJMT7H8Ih6trxVmZofQjr2dQ4j_3DTVoU3eLdog

UPDATE:

I switched from java,util.Base64 to org.apache.commons.codec.binary.Base64 and this seems to work somewhat, I don't get an error now.

String decodedString = new String(bytes, StandardCharsets.UTF_8);

gives me back a string of the header, payload, and signature data. So, when I do:

JSONObject jsonObject = new JSONObject(decodedString);
    System.out.println("getTokenProperty: jsonObject = " + jsonObject.toString());

I am only getting back the header data, and what I really need is the payload.

For the record ... the code I inherited from a "proof of concept" project was:

public static String getTokenProperty(String token, String propertyName)
{
    return (new JSONObject(new String(Base64.getDecoder().decode(token)))).getString(propertyName);
}

and there was no unit testing at all. So, when I went to unit test it, of course it completely broke. So, now I have a better understanding of how to parse this token, and I will remember this lesson for a long time.

Thanks very much!

解决方案

The reason it doesn't parse is because you are trying to Base64URLDecode the ENTIRE token.. But you have to decode PARTS of the token which is separated by a DOT "." character (0x2e in hex, 46 in dec, &#46 in html -- ASCII/UTF8) ..

Example:

public static void decodeTokenParts(String token)
{
    String[] parts = token.split("\\.", 0);

    for (String part : parts) {
        byte[] bytes = Base64.getUrlDecoder().decode(part);
        String decodedString = new String(bytes, StandardCharsets.UTF_8);

        System.out.println("Decoded: " + decodedString);
    }
}

This is because a JWT token is made up of parts:

Base64URLEncode({HeaderJSON}) + "." + Base64URLEncode({PayloadJSON}) + "." + Signature for example..

So to decode it.. you need to split it by "." and decode each part. Note: The signature will usually be binary that is encoded as base64 so once you decode it, don't try printing it.. it'll print bytes. You'd need to verify the signature.

For example, if you go to: https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

You will see how each "part" is encoded. It is colour coded.

这篇关于将Java 8 Base64 JWT令牌转换为JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆