使用 Amazon AWS Cognito `.well-known/jwks.json` 数据无法对某些字段进行 base64 解码 [英] Using Amazon AWS Cognito `.well-known/jwks.json` data fails to base64 decode some fields

查看:43
本文介绍了使用 Amazon AWS Cognito `.well-known/jwks.json` 数据无法对某些字段进行 base64 解码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用 Amazon AWS Cognito 联合身份,并在以下位置解析数据时:
https://cognito-identity.amazonaws.com/.well-known/jwks_uri 看起来像:

When using Amazon AWS Cognito Federated Identities, and parsing the data at:
https://cognito-identity.amazonaws.com/.well-known/jwks_uri which looks like:

{"keys":[
    {"kty":"RSA",
     "alg":"RS512",
     "use":"sig",
     "kid":"ap-northeast-11",
     "n":"AI7mc1assO5n6yB4b7jPCFgVLYPSnwt4qp2BhJVAmlXRntRZ5w4910oKNZDOr4fe/BWOI2Z7upUTE/ICXdqirEkjiPbBN/duVy5YcHsQ5+GrxQ/UbytNVN/NsFhdG8W31lsE4dnrGds5cSshLaohyU/aChgaIMbmtU0NSWQ+jwrW8q1PTvnThVQbpte59a0dAwLeOCfrx6kVvs0Y7fX7NXBbFxe8yL+JR3SMJvxBFuYC+/om5EIRIlRexjWpNu7gJnaFFwbxCBNwFHahcg5gdtSkCHJy8Gj78rsgrkEbgoHk29pk8jUzo/O/GuSDGw8qXb6w0R1+UsXPYACOXM8C8+E=",
     "e":"AQAB"}, 
 ... }

使用此代码(Kotlin 调用 JDK 8 Base64 类)可以很好地解码 n 字段:

This works fine decoding the n field using this code (Kotlin calling JDK 8 Base64 class):

Base64.getDecoder().decode(encodedN.toByteArray())

但是当使用 Cognito 用户池时,其 URL 中的数据采用以下形式:
https://cognito-idp.${REGION}.amazonaws.com/${POOLID}/.well-known/jwks.json

But when using Cognito User Pools which has data at a URL in the form of:
https://cognito-idp.${REGION}.amazonaws.com/${POOLID}/.well-known/jwks.json

它具有相同类型的数据,但不会解码.相反,我最终会出现以下错误:

It has the same type of data, but it will not decode. Instead I end up with errors such as:

非法的 base64 字符 5f

Illegal base64 character 5f

由于这是一个下划线 _ 并且在 Base64 URL 字母表中,我尝试将解码更改为:

Since that is an underscore _ and in the Base64 URL alphabet, I tried changing my decoding to:

Base64.getUrlDecoder().decode(encodedN.toByteArray())

但是第一组数据不再正确解码,因为它包含 / 和其他用于 Base64 URL 编码的无效字符.

But then the first set of data no longer decodes correctly because it contains / and other invalid characters for Base64 URL encoding.

有没有一种方法可以用同一个解码器处理这两个 jwks 数据集?!?

Is there a method that can handle both of these jwks sets of data with the same decoder?!?

注意:这个问题是作者有意编写和回答的(自答题),以便在 SO 中共享有趣问题的解决方案.

Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that solutions for interesting problems are shared in SO.

推荐答案

问题是 Amazon AWS Cognito 团队使用两种不同的 Base64 编码字母表来处理基本相同的事情.因此,您需要检测正在使用哪个.

The issue is that the Amazon AWS Cognito team is using two different Base64 encoding alphabets for basically the same thing. So you will need to detect which is being used.

如果编码后的字符串以 = 结尾或包含 +/ 那么它肯定是正常的 Base64.getDecoder().如果它包含 -_ 那么它肯定是 Base64.getUrlDecoder().否则没有什么特别的,最好使用 Base64.getUrlDecoder() 因为你不知道长度是否需要填充.

If the encoded string ends with = or contains + or / then it is definitely the normal Base64.getDecoder(). If it contains a - or _ then it is definitely the Base64.getUrlDecoder(). Otherwise nothing special is there and it is best to use the Base64.getUrlDecoder() because you do not know if the length would need padding or not.

这转化为(在 Kotlin 中,但逻辑上适用于任何语言):

fun base64SafeDecoder(encoded: String): ByteArray {
    val decoder = if (encoded.endsWith('=') || encoded.any { it == '+' || it == '/' }) {
        Base64.getDecoder()
    }
    else {
        Base64.getUrlDecoder()
    }
    return decoder.decode(encoded.toByteArray())
}

这对于任何具有 Base64 解码的语言来说都是一个问题,因为它们可能是松散的并忽略无效字符(有些会),或者它们可能是严格的并抛出异常.一些 Base64 编码/解码的测试网站也表现出这两种行为,静默忽略无效字符是危险的.稍后使用解码结果时,您会遇到错误.

This would be a problem for any language that has Base64 decoding in that they might be loose and ignore the invalid character (some do), or they might be strict and throw an exception. Some test websites for Base64 encoding/decoding exhibit both of these behaviors as well, and the silent ignoring of invalid characters is dangerous. You would then have an error later using the results of the decoding later.

这篇关于使用 Amazon AWS Cognito `.well-known/jwks.json` 数据无法对某些字段进行 base64 解码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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