我正在使用 MVC5 Identity 2.0 供用户登录我的网站,其中身份验证详细信息存储在 SQL 数据库中。 Asp.net Identity 已经以标准方式实现,可以在许多在线教程中找到。

IdentityModels 中的 ApplicationUser 类已扩展为包括一些自定义属性,例如整数 OrganizationId。这个想法是为了数据库关系的目的,可以创建许多用户并将其分配给一个公共(public)组织。

public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        //Extended Properties
        public DateTime? BirthDate { get; set; }
        public long? OrganizationId { get; set; }

        //Key Mappings
        [ForeignKey("OrganizationId")]
        public virtual Organization Organization { get; set; }
    }

如何从 Controller 中检索当前登录用户的 OrganizationId 属性?
一旦用户登录,这是否可以通过方法获得,或者每次执行 Controller 方法时,我是否总是根据 UserId 从数据库中检索 OrganizationId?

在网上阅读我看到我需要使用以下内容来获取登录的 UserId 等。
using Microsoft.AspNet.Identity;
...
User.Identity.GetUserId();

但是,OrganizationId 不是 User.Identity 中可用的属性。我是否需要扩展 User.Identity 以包含 OrganizationId 属性?如果是这样,我该怎么做。

我经常需要 OrganizationId 的原因是许多表查询依赖于 OrganizationId 来检索与登录用户关联的组织相关的数据。

最佳答案

每当您想使用任何其他属性(如上述问题)扩展 User.Identity 的属性时,首先将这些属性添加到 ApplicationUser 类中,如下所示:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    // Your Extended Properties
    public long? OrganizationId { get; set; }
}

然后你需要的是创建一个像这样的扩展方法(我在一个新的扩展文件夹中创建我的):
namespace App.Extensions
{
    public static class IdentityExtensions
    {
        public static string GetOrganizationId(this IIdentity identity)
        {
            var claim = ((ClaimsIdentity)identity).FindFirst("OrganizationId");
            // Test for null to avoid issues during local testing
            return (claim != null) ? claim.Value : string.Empty;
        }
    }
}

在 ApplicationUser 类中创建 Identity 时,只需添加 Claim -> OrganizationId ,如下所示:
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here => this.OrganizationId is a value stored in database against the user
        userIdentity.AddClaim(new Claim("OrganizationId", this.OrganizationId.ToString()));

        return userIdentity;
    }

添加声明并设置扩展方法后,要使其作为 User.Identity 的属性可用, 在要访问它的页面/文件上添加 using 语句 :

就我而言: Controller 中的 using App.Extensions; 和 .cshtml View 文件中的 @using. App.Extensions

编辑:

为了避免在每个 View 中添加 using 语句,您还可以做的是转到 Views 文件夹,并在其中找到 Web.config 文件。
现在查找 <namespaces> 标记并在那里添加您的扩展命名空间,如下所示:
<add namespace="App.Extensions" />

保存你的文件,你就完成了。现在每个 View 都会知道您的扩展。

您可以访问扩展方法:
var orgId = User.Identity.GetOrganizationId();

关于asp.net-mvc - 如何扩展 User.Identity 的可用属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28335353/

10-12 17:10
查看更多