Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use new ASP.NET Identity 2.0 Roles and Authorize Attribute?

I am using the new ASP.NET Identity 2.0 system. I know I can check if a user is in a role like this:

bool isAdmin = UserManager.IsInRole(User.Identity.GetUserId(), 
   "Customer Account Admin");

I guess this code can be written to check before certain code is run but what about the [Authorize] attribute. I used to be able say:

[Authorize(Role="Customer Account Admin")]

This doesn't work anymore because I am not using the old membership or Role Management anymore. How can I put the two together? Or how do I guard against certain parts of the application not being available to members of the right role?

Edit1: I don't believe that it's working. I put the following Authorize attribute on an Admin page and I am able to execute the code as a "Customer Account User"

   [Authorize(Roles = "Customer Service Admin, Savitas Admin")]
    public partial class _default : System.Web.UI.Page

Also, I would like to block that page from being seen by unauthorized users. We have code to block the menu but I can still type the URL to the Admin page and it can be seen by unauthorized users

 if (HttpContext.Current.User.IsInRole("Customer Account Admin"))
                    //
                    {
                    }
                    else
                    {
                        mi = radmenu1.Items.FindItemByText("Admin");
                        radmenu1.Items.Remove(mi);
                    }

EDIT2: We created the roles manually in the ASpNetRoles table and mapped users to roles in the ASPNetUsersToRoles table. There is a mapping from users to roles like "Customer Service Admin." We add users to roles with the following but I don't believe it works:

if (manager.AddToRole(manager.FindByName(UserName.Text).Id, "Customer Account Admin").Succeeded)
                                {
                                    c.logActivity("Register.aspx.cs", "REG_USER_ROLE", "Setting user to Admin role succeeded");
                                }

When a regular user logs in they don't get an Admin menu to the Admin page by typing into the address bar:

http://localhost:53620/Admin/default

How do I stop that?

Edit3: I tried to block all users to the Admin page per your example Eric but once again, I can log in as a Customer User and still type the above in the address bar and get to the page. What's wrong with this:

    <configuration>
  <configSections>

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <connectionStrings>
    ...
  </connectionStrings>
  <location path="~/Admin/default.aspx">
    <system.web>
      <authorization>
        <allow roles="Customer Service Admin" />
        <deny users="*"/>
      </authorization>

Edit4: Switching to path="Admin/default.aspx" gives the following config file error:

Configuration Error 
  Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. 

 Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

Source Error: 



Line 66:         </controls>
Line 67:       </pages>
Line 68:       <membership>
Line 69:         <providers>
Line 70:           <!--        ASP.NET Membership is disabled in this template. Please visit the following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn about the ASP.NET Membership support in this template
like image 693
user2471435 Avatar asked Apr 23 '14 16:04

user2471435


4 Answers

I've performed several tests and I have not been able to recreate your problem. I've used roles with and without spaces, and multiple roles. And everything works as expected.

How are you adding the roles? Here's how I'm doing it.

var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>());
roleManager.Create(new IdentityRole("This Is A Test"));
UserManager.AddToRole(user.Id, "This Is A Test");

UPDATE:

ASP.NET has three major components.. WebForms, MVC, and Web Pages. You're using WebForms (not classic asp.net or any other term).

There are several ways to secure a page by role, but the easiest is to do it in the web.config using a location element. Once again, this has nothing whatsoever to do with the fact of it being ASP.NET Identity or old style roles or whatever... it all works off the generic IPrincipal and IIdentity interfaces that are part of the base asp.net. For instance the following allows all administrators to acess the site and denies all other users, but allows users in the MyUsers role to access CoolStuff.aspx:

<configuration>    
 <system.web>    
      <authorization>    
           <allow roles="Administrators" />    
           <deny users="*"/>    
      </authorization>    

 </system.web>

 <!-- Allow all "MyUsers" role users to access CoolStuff.aspx -->    
 <location path="CoolStuff.aspx">    
      <system.web>    
           <authorization>    
                <allow roles="MyUsers" />    
           </authorization>    
      </system.web>    
 </location>    
</configuration>

Please be aware however, if you're using routing, it's possible that that the same page can be routed to two different url's, which means that it could be accessible from one url, but not another if you are not careful with your permissions.

like image 65
Erik Funkenbusch Avatar answered Sep 22 '22 22:09

Erik Funkenbusch


In Identity 3 you can use this:

[Authorize(ClaimTypes.Role, "Administrator")]
like image 45
Master19 Avatar answered Sep 24 '22 22:09

Master19


If you have a roleManager enabled in a Web.config file like this: <roleManager enabled="true"/> you need to remove it.

like image 27
Ruslan Zharyi Avatar answered Sep 25 '22 22:09

Ruslan Zharyi


I've got the same problem. I want to use AuthorizeAttribute to allow some web api calls to admin user. [Authorize] works, but [Authorize(Roles="Admin")] doesn't. API calls with [Authorize(Roles="Admin")] execution are very long, and then I've got an SQL Exception (unable to connect).

I've added the role with the role manager. In my data tables, the Admin role is linked to my user.

There's something weird : the role is in claims.

If I do :

var claimIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
var roleClaims = claimIdentity.Claims.Where(c => c.Type == ClaimTypes.Role);

I've got a claim with "Admin" value. I'm using it in an API call to return a different result to admin users, and it works fine.

The other weird thing is that I've tried to use instead User.IsInRole("Admin") and it doesn't work. So I guess AuthorizeAttribute uses IsInRole.

I'm going to write my own AuthorizeAttribute, using claim checking, but I'd prefer using the native solution.

Clément

like image 26
Clément Picou Avatar answered Sep 26 '22 22:09

Clément Picou