OAuth 无效的 Bas64

Posted

技术标签:

【中文标题】OAuth 无效的 Bas64【英文标题】:OAuth Invalid Bas64 【发布时间】:2021-04-14 17:52:52 【问题描述】:

我正在尝试实现 OAuth 流程,并且在我的客户服务中我有以下代码行:

services.AddAuthentication(config => 
            // We check the cookie to confirm that we are authenticated
            config.DefaultAuthenticateScheme = "ClientCookie";
            // When we sign in we will deal out a cookie
            config.DefaultSignInScheme = "ClientCookie";
            // use this to check if we are allowed to do something.
            config.DefaultChallengeScheme = "OurServer";
        )
            .AddCookie("ClientCookie")
            .AddOAuth("OurServer", config => 
                config.ClientId = "client_id";
                config.ClientSecret = "client_secret";
                config.CallbackPath = "/oauth/callback";
                config.AuthorizationEndpoint = "https://localhost:44360/oauth/authorize";
                config.TokenEndpoint = "https://localhost:44360/oauth/token";
                config.SaveTokens = true;

                config.Events = new OAuthEvents()
                
                    OnCreatingTicket = context =>
                    
                        var accessToken = context.AccessToken;
                        var base64payload = accessToken.Split('.')[1];
                        var modified = base64payload.Replace(" ", "");
                        var bytes = Convert.FromBase64String(base64payload);
                        var jsonPayload = Encoding.UTF8.GetString(bytes);
                        var claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonPayload);

                        foreach (var claim in claims)
                        
                            context.Identity.AddClaim(new Claim(claim.Key, claim.Value));
                        

                        return Task.CompletedTask;
                    
                ;
            );

当它尝试从其 base64 表示转换字符串时,它会抛出:System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

这让我感到困惑,因为我正在关注 YouTube 上的一个教程,据我所知,关注它并查看 github 代码是相同的。据称无效的 Base64 字符串是:

eyJzdWIiOiJzb21lX2lkIiwiR3Jhbm55IjoiQ29va2llIiwibmJmIjoxNjEwMTYwMjE5LCJleHAiOjE2MTAyNDY2MTksImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNjAvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM2MC8ifQ

这很奇怪,因为在 https://www.base64decode.org/ 上检查它会正确返回以下内容:

"sub":"some_id","Granny":"Cookie","nbf":1610160219,"exp":1610246619,"iss":"http://localhost:44360/","aud":"http://localhost:44360/"

这似乎是有效的,因为它与我在服务器端的控制器中设置的 JWT 令牌的声明和内容相匹配。我到底做错了什么?我检查了其他处理令牌问题的地方,但我没有看到任何无效字符,例如 -、+ 等。

编辑:

解决方法是执行以下操作,感谢 LinkedListT 提到它不是 4 的倍数。

private string AddPaddingToBase64(string base64)
        
            if(base64.Length % 4 == 0) 
                return base64;
            else
            
                var builder = new StringBuilder(base64);
                builder.Append("=");
                return AddPaddingToBase64(builder.ToString());
             

        

然后我们首先解析字符串,让它通过那个方法,然后将修改后的 base64 传递给转换器。这也是在 3 年多的专业发展中,递归实际上比迭代更简单、更直接的第一次。

【问题讨论】:

我没有看到任何无效字符,例如 -、+ 等 - - 在 Base64 中有效,+ 在 Base64Url 编码中有效。问题的真正原因是 JWT 使用 Base64Url 编码而不是 Base64。有关详细信息,请参阅 my answer here。因此仅添加填充也是不够的,因为还有两个字符替换。 【参考方案1】:

问题是您的 base64 字符串无效。

base64 编码字符串的长度始终是 4 的倍数。如果不是 4 的倍数,则追加 = 字符,直到它是。 ?name=value 形式的查询字符串在值包含 = 字符时会出现问题(其中一些将被删除,我不记得确切的行为)。在进行 base64 解码之前,您可能可以通过附加正确数量的 = 字符来摆脱困境。 https://***.com/a/2925959/9936356

因此,您需要将“==”附加到有问题的 base64 字符串。即

Convert.FromBase64String("eyJzdWIiOiJzb21lX2lkIiwiR3Jhbm55IjoiQ29va2llIiwibmJmIjoxNjEwMTYwMjE5LCJleHAiOjE2MTAyNDY2MTksImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNjAvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM2MC8ifQ==");

【讨论】:

确实是这样,我在阅读了有关 base64 的更多信息后发现了这一点。我想问题是它为什么没有正确转换为base64。哦,好吧,修复很容易。我将使用修复程序编辑我的答案并将您的答案标记为正确。我希望 C#s 转换器足够智能,只需将“=”附加到它以使其有效,因为“=”在 base64 中没有意义(最后),除了我理解的长度之外

以上是关于OAuth 无效的 Bas64的主要内容,如果未能解决你的问题,请参考以下文章

添加 Flickr API 参数时的 oAuth “无效签名”

OAuth“验证码格式无效”

来自 Youtube API 的 OAUTH 凭据无效

刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)

更改密码时如何使 OAuth 令牌无效?

Spring oauth2 / oauth / token无效凭据