Search code examples
asp.net-identityiprincipalisinrole

Identity 2.0 Custom UserManager/RoleManager vs razor calling User.IsInRole("RoleName")


Questions are below: read through to see what you need to help answer...

I have

  • VS 2013
  • MVC 5 with Razor views
  • Dapper DAL Custom UserManager and UserStore/User : IUser< int >

I build my own UserManager, RoleManager, UserStore, RoleStore, and all based on CustomUser : IUser< int > and CustomRole : IRole< int >

I can change passwords, recover forgotten passwords, login, logout... all works well.

However, in the razor view, when I try to use :

User.IsInRole("Administrators");

I get a SQL exception, (which probably happens in iPrincipal Identity class ???) from some other module:

System.Data.SqlClient.SqlException occurred
  _HResult=-2146232060
  _message=A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
  Source=.Net SqlClient Data Provider
  ErrorCode=-2146232060
  _doNotReconnect=false
  Class=20
  LineNumber=0
  Number=-1
  Server=""
  State=0
  StackTrace:
       at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
  InnerException: <null>

But I can call

var user = AsyncHelpers.RunSync<CloudUser>(() => UserManager.FindByNameAsync(User.Identity.Name));
ViewBag.IsInAdminRole = AsyncHelpers.RunSync<bool>(() => UserManager.IsInRoleAsync(user.Id, "Administrators"));

In my controller server code....

Questions:

  1. What is the relationship between User.IsInRole and the UserManager/UserStore and/or RoleManager

  2. How do I get User.IsInRole("Administrators") in the Razor View to 'understand' that it needs to use my custom Identity authentication implementation?


Solution

  • I suspect that your implementation does not provide ClaimsPrincipal when user is signed in.

    @User should be ClaimsPrincipal and IsInRole (see source) does not reach into database, but rather checks for claims of type "Role" set on the principal's identity. If you see this exception, your IPrincipal is different form 'ClaimsPrincipal'.

    I've read through the answer you linked and I don't think this is the best solution to use with Identity framework. The answer is pre-Identity and talks about MembershipProvider. You had to do these kind of things when you were dealing with MembershipProvider. Now Identity gives you much better and cleaner way to do custom functionality.

    I would advise against implementing CustomPrincipal and use ClaimsPrincipal provided by the .Net framework. Just add Claims of type ClaimTypes.Role with role names on your principal when you return IPrincipal from your UserManager.CreateIdentityAsync.