R
R
Refraction2014-08-06 23:45:03
ASP.NET
Refraction, 2014-08-06 23:45:03

Why is ClaimsPrincipal lost inside OWIN middleware?

Hello.

Faced the problem of losing the ClaimsPrincipal during the operation of OAuth2 middleware providers. Its essence is this:

For logging, I need to generate a Guid as an Activity Id. This guide is then used when calling different datasources so that all logs have a single ID within a single request. Since the OAuth middleare is registered first, it generates a new activity Id value and stores it in the claims:

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
    claimsPrincipal.Identities.First.AddClaim(new Claim("TestClaim", Guid.NewGuid().ToString()));

    // много различных асинхронных вызовов датасорсов которые логируются, например:
    await userDataSource.FindAsync(id);
    await tenantDataSource.FindAsync(id);
   //
}


When calling the datasource method, the claim is retrieved from the CurrentPrincipal and its value is passed to the logger.

And everything seems to be fine, but if before and during the call to userDataSource there is a claim, then after the call is completed and before the call to tenantDataSource, the claim is gone.
Deciding that owin starts all the middleware with ConfigureAwait(false) which leads to the loss of the context, moved datasource calls to a separate method, which called c ConfigureAwait(true) in the hope that the context would not be lost: But this did not help even after returning from the first asynchronous call the principal is lost. If I set the claim in the controller's Api method, then it is available throughout the call, no matter how many calls are inside.

await Grant().ConfigureAwait(true);

Is this some kind of special magic of working with OWIN? Can you please tell me why this is happening and how to prevent the loss of the principal with the brands I have installed?

PS. I found another interesting nuance for myself:

If you look at the Principal in the controller, then its Identity and Identities[0] refer to one object, while inside the middleware Identity and Identities[0] are two different instances. Moreover, unlike the controller, where Principal is ClaimsPrincipal, inside the middleware it is GenericPrincipal.
Unfortunately, I did not find any information why this is so. I would be glad if someone will throw a link to read.

update

Tumbling further, I came across that in the context of the barn Request.User == null. Having created a new principal and entered it in User, CurrentPrincipal is no longer lost, and moreover, it refers to the instance that I entered in Request.User.

But I still can’t find the information why this happens and why, when the context is returned from await, the principal is restored from Request.User.
I would be glad if someone could clarify this point.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question