ASP.NET Identity - Confusion about [Authorize] And

2019-05-13 06:47发布

问题:

I have been following this post on creating a custom "storage provider" for the new ASP.NET Identity system, and so far it has proven very informative;

Creating a custom MySQL Identity Provider

I am not using MySQL, I am using RavenDB - and yes, I have already looked at the available RavenDB Identity Providers out there - that isn't really my issue. My issue comes with the IUserRoleStore<IdentityUser> and then the IdentityRole, as well as RoleStore.

I see them get created - I even see how they access data to see if a user is in a role, etc. But then later, I just see this ..

[Authorize(Roles = "Admin")]
public AccountController : Controller { 
    /// ... etc .etc..
}

This is where I am getting outright lost. I have looked up dozens and dozens and dozens of tutorials on the new ASP.NET Identity system and I cannot figure out at what point something becomes associated with the AuthorizeAttribute. How does it know to use the RoleStore I made? How does it know to use the IdentityRole I made? What is it verifying against?

These are all things I cannot find anywhere, and it is driving me kind of batty. Everything I find keeps plugging into Entity Framework, which isn't what I want to use - and it is just that way out of the box, and they seem to stop without telling you how to make sure the Authorize works like you want it to.

回答1:

The Authorize attribute doesn't know anything about ASP.NET Identity, or any other identity system. It simply works with IPrincipal and IIdentity interfaces that the MVC framework sets up for you.

ASP.NET Identity uses a ClaimsIdentity object, which implements IIdentity.

So the Framework, via the UserManager creates an authentication ticket. When a page loads, it loads this authentication ticket, decrypts it, and creates the necessary principal and identity and role objects.

Then, the Authorize attribute just basically checks User.IsInRole("Blah") when you say

[Authorize(Roles="Blah")]



回答2:

It's actually a little bit simpler than that. When a user logs in, these lines in the AccountController creates a ClaimsIdentity and the auth middleware sets a cookie...

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);

The roles information is read from the database when the ClaimsIdentity is created. The identity (including the roles) is serialized and encrypted into the cookie. On subsequent requests, the ClaimsIdentity is decrypted and deserialized from the cookie by the middleware. The identity is attached to the thread, and that's what the AuthorizeAttribute uses to determine if the user is in a role. You can also programmatically access the ClaimsIdentity using User.Identity in a controller.