asp.net-mvc - 如何扩展 User.Identity 的可用属性

标签 asp.net-mvc asp.net-mvc-5 asp.net-identity asp.net-identity-2

我使用 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; }
}

然后您需要创建一个像这样的扩展方法(我在新的 Extensions 文件夹中创建我的):

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 语句 :

就我而言:using App.Extensions;在 Controller 内和 @using. App.Extensions使用 .cshtml View 文件。

编辑:

为了避免在每个 View 中添加 using 语句,您还可以转到 Views 文件夹,并在其中找到 Web.config 文件。 现在寻找<namespaces>标记并在那里添加您的扩展 namespace ,如下所示:

<add namespace="App.Extensions" />

保存文件即可完成。现在每个 View 都会知道您的扩展。

您可以访问扩展方法:

var orgId = User.Identity.GetOrganizationId();

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

相关文章:

c# - MVC Controller ,将参数作为类

jquery 1.7.1 - 由查询字符串中的括号 "("引起的语法错误

asp.net-mvc - 如何使用Ajax.ActionLink?

c# - 如何在 ASP.NET MVC 中显示具有相同 ID 的所有行?

c# - 属性不适用于模型 ASP.NET MVC 5

asp.net-mvc - 我们可以个性化 ASP.NET MVC 5 中角色的 session 超时吗

c# - Asp.NET MVC 5 中 Controller 的继承

visual-studio-2013 - Visual Studio 2013 IntelliSense 停止为 ASP.NET MVC5 Controller 工作

asp.net - 在同一请求中调用PasswordSignIn和SendTwoFactorCode

c# - 如何使用新的 ASP.NET Identity 2.0 角色和授权属性?