【问题标题】:Identity 2.0 Custom UserManager/RoleManager vs razor calling User.IsInRole("RoleName")Identity 2.0 自定义 UserManager/RoleManager 与 razor 调用 User.IsInRole("RoleName")
【发布时间】:2014-11-21 20:54:22
【问题描述】:

问题如下:通读以了解您需要帮助回答的内容...

我有

  • VS 2013
  • 带有 Razor 视图的 MVC 5
  • Dapper DAL 自定义 UserManager 和 UserStore/User : IUser

我构建了我自己的 UserManager、RoleManager、UserStore、RoleStore,所有这些都基于 CustomUser : IUser 和 CustomRole : IRole

我可以更改密码、找回忘记的密码、登录、注销...一切正常。

但是,在剃刀视图中,当我尝试使用时:

User.IsInRole("Administrators");

我从其他模块中得到一个 SQL 异常(可能发生在 iPrincipal Identity 类中???):

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>

但我可以打电话

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

在我的控制器服务器代码中......

问题:

  1. User.IsInRole 与 UserManager/UserStore 和/或 RoleManager 之间是什么关系

  2. 如何让 Razor 视图中的 User.IsInRole("Administrators") “了解”它需要使用我的自定义身份验证实现?

【问题讨论】:

  • 当您将@User.GetType().ToString() 放入视图时,您会看到什么?即UserIPrincipal是什么类型?
  • 我知道你在想什么。我通过派生自己的 IPrincipal 和 WebView 页面自己解决了这个问题。我在这里使用了解决方案来解决我的问题:*.com/questions/18366566/…
  • 啊,很好!正在输入一个答案,但你自己排序了!
  • 添加你的答案 - 我会给你分数 - 我讨厌回答我自己的问题!!

标签: asp.net-identity iprincipal isinrole


【解决方案1】:

我怀疑您的实现在用户登录时未提供ClaimsPrincipal

@User 应该是ClaimsPrincipalIsInRole (see source) 不会进入数据库,而是检查主体身份上设置的“角色”类型的声明。如果您看到此异常,则您的 IPrincipal 与“ClaimsPrincipal”不同。

我已阅读您链接的答案,我认为这不是与身份框架一起使用的最佳解决方案。 The answer 是 pre-Identity 并谈论 MembershipProvider。当您与 MembershipProvider 打交道时,您必须做这些事情。现在,Identity 为您提供了更好、更简洁的方式来执行自定义功能。

我建议不要实现 CustomPrincipal 并使用 .Net 框架提供的 ClaimsPrincipal。当您从 UserManager.CreateIdentityAsync 返回 IPrincipal 时,只需在您的主体上添加带有角色名称的 ClaimTypes.Role 类型的声明。

【讨论】:

  • 我会给你答案,因为我现在派生自 ClaimsPrincipal; public class MyCustomPrincipal : ClaimsPrincipal, IMyCustomPrincipal ...但是所有关于 CustomPrincipal 的其他代码在提供的链接中都被注释掉了,我还是删除了它,因为我不需要它。我什至删除了 IsInRole 的实现,因为它已在 ClaimsPrincipal 中处理。感谢您对我的东西的评论。说,这里不应该有一个“代码审查”部分吗?大声笑
  • 好!很高兴它成功了,你不必使用黑客。关于代码审查,有codereview.stackexchange.com,但我从未去过那里,所以不能说你是否会在那里找到你的用途。
最近更新 更多