Closed ioeifcss closed 2 years ago
If you have a tool like fiddler available, is it possible to capture the headers that your client is sending in the request? If you don't want to post it here, I can give you an email address to send it to.
Please provide an email address and I'll capture the headers from Postman and my single page app send them both to you
jon.lester@microsoft.com
Hi Jon. Any chance you've been able to look into this?
OK, I've been debugging the codebase to try and get to the bottom of this.
So far, I've modified ModelExtensions.cs to add some debug lines
internal static void AppendResponseHeaders(this UserInfoPayload payload, IHeaderDictionary headers,
EasyAuthConfigurationOptions configOptions, ILogger logger)
{
if (headers == null)
{
return;
}
void addHeader(string name, string value)
{
string headerName = SanitizeHeaderName($"{configOptions.ResponseHeaderPrefix}{name}");
string encodedValue = EncodeValue(value, configOptions.ClaimEncodingMethod);
logger.LogInformation($"[DEBUG] Raw name is [{name}] and parsed name is [{headerName}]");
logger.LogInformation($"[DEBUG] Raw value is [{value}] and parsed value is [{encodedValue}]");
//nginx will only forward the first header of a given name,
//so we must combine them into a single comma-delimited value
if (headers.ContainsKey(headerName))
{
logger.LogInformation("[DEBUG] headers.ContainsKey is TRUE");
headers[headerName] = string.Concat(headers[headerName], "|", encodedValue);
}
else
{
logger.LogInformation("[DEBUG] headers.ContainsKey is FALSE");
headers.Add(headerName, encodedValue);
}
};
if (configOptions.HeaderFormatOption == EasyAuthConfigurationOptions.HeaderFormat.Combined)
{
string serialized = JsonSerializer.Serialize<UserInfoPayload>(payload);
addHeader("userinfo", serialized);
}
else
{
addHeader("name", payload.name);
addHeader("oid", payload.oid);
addHeader("preferred-username", payload.preferred_username);
addHeader("sub", payload.sub);
addHeader("tid", payload.tid);
addHeader("email", payload.email);
addHeader("groups", payload.groups);
addHeader("scp", payload.scp);
foreach (ClaimValue claim in payload.otherClaims)
{
addHeader(claim.name, claim.value);
}
foreach (string role in payload.roles)
{
addHeader("roles", role);
}
foreach (string graph in payload.graph)
{
addHeader("graph", graph);
}
}
}
The output from those debug lines is fairly benign, but the final debug triplet looks to be the culprit:
[DEBUG] Raw name is [http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier] and parsed name is [x-injected-http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier]
[DEBUG] Raw value is [iaNEmI...F2V7L1ExY] and parsed value is [iaNEmI...F2V7L1ExY]
[DEBUG] headers.ContainsKey is FALSE
In other words, I think the culprit is x-injected-http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
This would also tally up with the details in my first post which mentions
Invalid non-ASCII or control character in header: 0x003A
and 0x003A is unicode hex for :
My next question is therefore, where is this nameidentifier property coming from? Is it because I've misconfigured my app registration or is it because of how our AAD instance is setup (on-premises AD synced to AAD)?
@ioeifcss Thank you for your help on this. The fact that you are syncing identities from on-prem wasn't the direct cause of this, but it did help expose a regression bug because it introduced a claim name that we hadn't tested with before.
I have an endpoint protected using the latest release of EasyAuthForK8S
When using a cookie, I am able to reach the endpoint without issues
When enabling bearer token mode and using a Bearer token to make the same call, I get an HTTP 500 in Postman and in my SPA.
I'm not really sure how to debug the issue, but I did capture the following from the easyauth pod logs:
Any thoughts what might be causing this invalid character to come from?