Spedo De La Rossa
Spedo De La Rossa

Reputation: 127

Upgrade Application Authentication to Core 2.0+

We are switching form .NET 4x to .NET Core and now I have problem with the authentication.

The main problem is, that the authentication is in an assembly and I am pretty new to Core, but read into it. There are some problems occuring, for example IPrincipal.

So I created my middleware and registered it in the StartUp.cs. After that I am Invoking it to start the authentication process.

In .NET i used this:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            NameValueCollection header = new NameValueCollection();
            header.Add(Request.Headers);
            IPrincipal princ = new CompanyPortalPrincipal(header);

            Context.User = princ;
            CompanyPortalPrincipal pp = Context.User as CompanyPortalPrincipal;
...

In Core I cannot use this.

First of all my MW:

private void BeginInvoke(HttpContext context)
        {
            NameValueCollection header = new NameValueCollection();
            header.Add(context.Request.Headers);

            IPrincipal principal = new CompanyPortalPrincipal(header);
            context.User = principal;
...

The first problem is in header.Add(context.Request.Headers); because it says that it cannot convert from Microsoft.AspNetCore.Http.IHeaderDictionary to Collection.Specialized.NameValueCollection.

The second problem is that in Core you use something like ClaimsPrincipal? Which I cannot use, because I am not allowed to touch the CompanyPortalPrincipal and this is using IPrincipal. Thus I cannot do context.User because in short it cannot convert from IPrincipal to ClaimsPrincipal

Upvotes: 0

Views: 367

Answers (1)

itminus
itminus

Reputation: 25370

The first problem is in header.Add(context.Request.Headers); because it says that it cannot convert from Microsoft.AspNetCore.Http.IHeaderDictionary to Collection.Specialized.NameValueCollection.

ASP.NET Core now uses the IHeaderDictionary to store headers. You could convert IHeaderDictionary to a NameValueCollection in following way:

NameValueCollection header = ctx.Request.Headers
    .SelectMany( kvp => kvp.Value, (kvp, value) => (kvp.Key,value))
    .Aggregate( new NameValueCollection(), (seed, current) =>{
        seed.Add(current.Key,current.value);
        return seed;
    });

// now you get the header
IPrincipal principal = new CompanyPortalPrincipal(header);

The second problem is that in Core you use something like ClaimsPrincipal? Which I cannot use, because I am not allowed to touch the CompanyPortalPrincipal and this is using IPrincipal. Thus I cannot do context.User because in short it cannot convert from IPrincipal to ClaimsPrincipal

Not sure how your CompanyPortalPrincipal is defined. But the ClaimsPrincipal constructor accepts a parameter of IIdentity, so you could create a new ClaimsPrincipal as below:

var userPrincipal =  new ClaimsPrincipal(principal.Identity);
// if you have multiple identity, invoke :
// ... userPrincipal.AddIdentity(...)
context.User = principal;

There's no magic in the ClaimsPrincipal( source) or ClaimsIdentity(source) . You could modify the principal as you like,for example, add claim add identities.

Upvotes: 1

Related Questions