Morema
Morema

Reputation: 145

Extend IPrincipal in .NET Core 2.1 with Windows Authentication

I'm trying to extend IPrincipal in .NET Core with Windows Authentication.

In a previous project (using .NET Framework 4.6.1) on Application_Start() I added the code below to extend IPrincipal:

protected void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
    if (e.Identity != null && e.Identity.IsAuthenticated)
    {
        NgUser opPrincipal = CustomStaticMethod.GetUserAD();
        HttpContext.Current.User = opPrincipal;
     }
 }

And this is my custom class

public class NgUser : IPrincipal
{
    // code removed for abbr ...
}

Then every time in a controller casting HttpContext.Current.User as CustomPrincipal I'd have access to the custom properties without having to use claims or using static extensions or storing an object in session.

Now in .NET Core I've seen you can customize claims transformation and I've also read this and they basically extended IPrincipal.

I'd prefer to extend IPrincipal with my custom class, register it in Startup.cs and be able to access it in my controllers.

Surely this is doable, question is how?

I hope this is clear and some one can help me. Many thanks

Upvotes: 1

Views: 499

Answers (1)

Balah
Balah

Reputation: 2540

It's very doable. The easiest way is to add a piece of middleware, which behaves similar to OnAuthenticate, to the Configure() pipeline in .NET Core. Here you'll swap out the IPrincipal. Note, this only works if the web app is set to run with Windows Authentication only in IIS/IIS Express. Anonymous authentication adds extra overhead.

If you have this simple Win auth setup, in your Startup.cs put this near the top of your Configure(IApplicationBuilder app) method:

// Because IIS automatically captures the user login, by the time the app is touched
// in any request, the context (ctx) User is already present.
app.Use(async (ctx, next) =>
{
  if (ctx.User?.Identity?.IsAuthenticated == true)
  {
    NgUser opPrincipal = CustomStaticMethod.GetUserAD();
    ctx.User = opPrincipal;
  }

  // be sure to continue the rest of the pipeline!
  await next.Invoke();
});

```

Upvotes: 1

Related Questions