Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asp.net core bad request headers to long #3179

Closed
darewreck54 opened this issue May 31, 2018 · 14 comments
Closed

Asp.net core bad request headers to long #3179

darewreck54 opened this issue May 31, 2018 · 14 comments

Comments

@darewreck54
Copy link

darewreck54 commented May 31, 2018

Hi,

I'm not sure what repo to post this issue in, so please bear with me.

At this time, I have an application that uses openIDConnect to server side authenticate with AzureActiveDirectory. The application is built onto of Asp.net core 2. There are times where when you load the page, you experience a "Bad Request - header to long" error when authenticating. I believe this issue is related to the fact that whenever the cookie expires it will append to the existing cookie when it refreshes. As a result, eventually the request headers will be to big and throw the error. The only way to recover from it is to clear the cookies.

In Asp.net, this problem can be resolved by implementing a middleware where you would clear out the cookie and then re-add it; preventing the append. However, with asp.net core the interface has changed and the way to do it has changed to.

I was wondering if there is any guidance on how to address this problem,
Thanks,
Derek

@Tratcher
Copy link
Member

Can you share the headers for a failing request?

A new auth cookie should replace the old one, not append to the existing one.

@darewreck54
Copy link
Author

@Tratcher The problem happens randomly. I'll post it once i'm able to get a the header info.

@darewreck54
Copy link
Author

darewreck54 commented Jun 1, 2018

This is what people have been seeing: Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi#10 I believe this is what I'm seeing.

I'll attach my specific situation when I'm able to reproduce it.

@Tratcher
Copy link
Member

Tratcher commented Jun 1, 2018

Those look like AAD cookies, not app cookies, you'll have to take that up with them.

@darewreck54
Copy link
Author

The problem just occurred again.

debug.txt

So your saying it deals with how AAD is returning the cookie?

Thanks,
Derek

@Tratcher
Copy link
Member

Tratcher commented Jun 1, 2018

@darewreck54 Your debug.txt is quite different form the Azure-Samples issue you linked to. These are cookies from your own site, not AAD. I see one set of auth cookies, there's no appending happening here, but I also see a dozens of random cookies in there unrelated to auth. Where did those all come from?

@darewreck54
Copy link
Author

darewreck54 commented Jun 1, 2018

@Tratcher Sorry about that confusion. If you look a the first request in the log -> entries you will see that it's a failed request.

The limit for a header is 16k. In the file there are three ASP.net cookies that are 4k each. So that is 12k already. So it only leaves room for 4k. (.AspNetCore.Cookies, .AspNetCore.CookiesC1, .AspNetCore.CookiesC3)

So in our case we are just above 16k total and that is why the bad request is sent.

Why is the aspnet cookie take up 14k?

@Tratcher
Copy link
Member

Tratcher commented Jun 2, 2018

Because your user has a lot of claims/roles/groups. You can hook into the OIDC events and slim that down as needed.

@darewreck54
Copy link
Author

@Tratcher can you give me an example or point me to a location where i can read more of what you mean by passing it into OIDC events to slim it down?

I found an example for asp.net but not for asp.net core: https://dzone.com/articles/applying-cookie-stored-sessions-in-web-farms-with

Also in my use case, i'm supporting a multi-tenant scenario. So if i'm understanding you correctly, when OIDC gets the AAD response in the middleware, It will then create the cookie based on the claims. At that point, I should be stripping out any claims that belong to a tenant that I don't care about.

You mentioned event, but not sure which one:
public virtual Task AuthenticationFailed(AuthenticationFailedContext context);
public virtual Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context);
public virtual Task MessageReceived(MessageReceivedContext context);
public virtual Task RedirectToIdentityProvider(RedirectContext context);
public virtual Task RedirectToIdentityProviderForSignOut(RedirectContext context);
public virtual Task RemoteSignOut(RemoteSignOutContext context);
public virtual Task TokenResponseReceived(TokenResponseReceivedContext context);
public virtual Task TokenValidated(TokenValidatedContext context);
public virtual Task UserInformationReceived(UserInformationReceivedContext context);

THanks,
Derek

@Tratcher
Copy link
Member

Tratcher commented Jun 4, 2018

@darewreck54
Copy link
Author

darewreck54 commented Jun 4, 2018

Thanks!

Interesting, when i strip out all the claims the size of the asp.net cookies decrease from 11k to 7.5k. I'm guessing that is the smallest you can decrease it to by removing claims.

Any other ways to decrease the size?

I went the route of just replacing the principal.

     OnTicketReceived = e => {
               e.Principal = TransformClaims(e.Principal);
               return Task.CompletedTask;
      }
        private ClaimsPrincipal TransformClaims(ClaimsPrincipal claimsPrincipal) {
            ClaimsIdentity identity = (ClaimsIdentity)claimsPrincipal.Identity;
            var tenantId = identity.FindFirst(Constants.AzureADClaimTypes.TenantId);
            var firstName = identity.FindFirst(Constants.AzureADClaimTypes.FirstName);
            var lastName = identity.FindFirst(Constants.AzureADClaimTypes.LastName);
            var objectId = identity.FindFirst(Constants.AzureADClaimTypes.ObjectId);
            var email = identity.FindFirst(Constants.AzureADClaimTypes.Email);
            var name = identity.FindFirst(Constants.AzureADClaimTypes.Name);
            var claimsToKeep = new List<Claim> { tenantId, firstName, lastName, objectId, email, name};

            var newIdentity = new ClaimsIdentity(claimsToKeep, identity.AuthenticationType);
            ClaimsPrincipal newClaims = new ClaimsPrincipal(newIdentity);

            return newClaims;
        }

@Tratcher
Copy link
Member

Tratcher commented Jun 5, 2018

You can also check the Identity.BootstrapContext and the AuthenticationProperties collection for extra stuff.

@evan2k
Copy link

evan2k commented Jul 5, 2018

I have a similar issue where the ".AspNetCore.Cookies" are sent twice in a request. Have to delete the cookies in order to work. As a result I get an HTTP 400 error (request too long). Can anybody comment under which circumstances this can occur? I am calling a Signalr hub (not sure if it matters). Thanks Evan.

@Eilon
Copy link
Member

Eilon commented Jul 13, 2018

@evan2k that seems like it might be an unrelated issue. Can you please file a new issue with details so that we can take a look?

I'm closing this issue because it seems like the main problem has been resolved. Thanks!

@Eilon Eilon closed this as completed Jul 13, 2018
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants