OAuth 无效的 Bas64
OAuth Invalid Bas64
我正在尝试实施 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/ 正确 returns 以下内容:
{"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 字符串无效。
The length of a base64 encoded string is always a multiple of 4. If it is not a multiple of 4, then = characters are appended until it is. A query string of the form ?name=value has problems when the value contains = characters (some of them will be dropped, I don't recall the exact behavior). You may be able to get away with appending the right number of = characters before doing the base64 decode.
因此您需要将“==”附加到相关的 base64 字符串。即
Convert.FromBase64String("eyJzdWIiOiJzb21lX2lkIiwiR3Jhbm55IjoiQ29va2llIiwibmJmIjoxNjEwMTYwMjE5LCJleHAiOjE2MTAyNDY2MTksImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNjAvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM2MC8ifQ==");
我正在尝试实施 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/ 正确 returns 以下内容:
{"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 字符串无效。
The length of a base64 encoded string is always a multiple of 4. If it is not a multiple of 4, then = characters are appended until it is. A query string of the form ?name=value has problems when the value contains = characters (some of them will be dropped, I don't recall the exact behavior). You may be able to get away with appending the right number of = characters before doing the base64 decode.
因此您需要将“==”附加到相关的 base64 字符串。即
Convert.FromBase64String("eyJzdWIiOiJzb21lX2lkIiwiR3Jhbm55IjoiQ29va2llIiwibmJmIjoxNjEwMTYwMjE5LCJleHAiOjE2MTAyNDY2MTksImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNjAvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM2MC8ifQ==");