11

I'm trying to rewrite some authorization I currently have for ASP.NET 4.6 in ASP.NET Core.

I understand that Authorization has changed a bit, and I find it difficult to implement my very simple auth strategy in ASP.NET Core.

My requirements:

Every request to the server should include a header called "key". Based on the value of that key, I will be able to query the database and check whether that key represents a regular user or an admin user. If the request does not contain a valid key, the request is not authorized.

How would I implement this in ASP.NET Core? Every example I find seems totally overkill for my needs.

In ASP.NET 4.6 I used my own custom AuthorizeAttributes to use on my controllers, e.g.

[User]
public IHttpActionResult DoSomethingOnlyUsersCanDo() {}

and

[Admin]
public IHttpActionResult DoSomethingOnlyAdminsCanDo() {}

Can I do the same in ASP.NET Core?

msk
  • 872
  • 2
  • 13
  • 28

1 Answers1

9

In ASP.NET Core, it is recommended that you do not inherit from AuthorizeAttribute. Instead, you can make custom authorization policies: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims.

You will need to have an authentication handler that creates a ClaimsIdentity for the user based on the header. Then you can make policies that assert the existence of certain claims on the user.

You can find an implementation of Basic authentication here: https://github.com/blowdart/idunno.Authentication. Note Barry's comment there of course:

It is meant as a demonstration of how to write authentication middleware and not as something you would seriously consider using.

Its core is in BasicAuthenticationHandler, which inherits from AuthenticationHandler<BasicAuthenticationOptions>.

The principal in this implementation is created in the developer-made event callback, in the sample it is here:

if (context.Username == context.Password)
{
    var claims = new[]
    {
        new Claim(ClaimTypes.NameIdentifier, context.Username, ClaimValueTypes.String, context.Options.ClaimsIssuer),
        new Claim(ClaimTypes.Name, context.Username, ClaimValueTypes.String, context.Options.ClaimsIssuer)
    };

    context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
    context.Success();
}

The authentication ticket is then created in the handler after calling this callback based on the principal:

var ticket = new AuthenticationTicket(validateCredentialsContext.Principal, Scheme.Name);
return AuthenticateResult.Success(ticket);

I also made an article on implementing custom authentication schemes: Creating an authentication scheme in ASP.NET Core 2.0.

juunas
  • 41,356
  • 5
  • 86
  • 118