Java 8 Base64 JWT-токен в JSON - PullRequest
0 голосов
/ 31 мая 2019

Итак, я провел некоторое исследование по этому вопросу в сети и здесь, в 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);
}

и модульное тестирование вообще не проводилось.Поэтому, когда я отправился на юнит-тест, он полностью сломался.Итак, теперь я лучше понимаю, как анализировать этот токен, и запомню этот урок на долгое время.

Большое спасибо!

1 Ответ

4 голосов
/ 31 мая 2019

Причина, по которой он не анализируется, заключается в том, что вы пытаетесь Base64URLD закодировать ВСЕЙ токен. Но вы должны декодировать ЧАСТИ токена, разделенные точкой "." символ (0x2e в шестнадцатеричном формате, 46 в декабре, & # 46 в html - 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.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Вы увидите, как кодируется каждая «часть». Он имеет цветовую кодировку.

...