如何扩展 User.Identity 的可用属性 [英] How to extend available properties of User.Identity

查看:29
本文介绍了如何扩展 User.Identity 的可用属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

公共类 ApplicationUser : IdentityUser{公共异步任务GenerateUserIdentityAsync(UserManager manager){//注意 authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的匹配var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);//在此处添加自定义用户声明返回用户身份;}//扩展属性公共日期时间?出生日期 { 得到;放;}公长?组织 ID { 获取;放;}//键映射[ForeignKey("OrganizationId")]公共虚拟组织 Organization { get;放;}}

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

在网上阅读我看到我需要使用以下内容来获取登录的 UserId 等.

使用 Microsoft.AspNet.Identity;...User.Identity.GetUserId();

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

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

解决方案

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

>

公共类 ApplicationUser : IdentityUser{公共异步任务GenerateUserIdentityAsync(UserManager manager){//注意 authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的匹配var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);//在此处添加自定义用户声明返回用户身份;}//你的扩展属性公长?组织 ID { 获取;放;}}

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

命名空间 App.Extensions{公共静态类 IdentityExtensions{公共静态字符串 GetOrganizationId(此 IIdentity 身份){var claim = ((ClaimsIdentity)identity).FindFirst("OrganizationId");//测试 null 以避免在本地测试期间出现问题返回(声明!= null)?声明.值:字符串.空;}}}

当您在 ApplicationUser 类中创建 Identity 时,只需像这样添加 Claim -> OrganizationId:

 公共异步任务GenerateUserIdentityAsync(UserManager manager){//注意 authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的匹配var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);//在此处添加自定义用户声明 =>this.OrganizationId 是存储在数据库中针对用户的值userIdentity.AddClaim(new Claim("OrganizationId", this.OrganizationId.ToString()));返回用户身份;}

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

在我的例子中:using App.Extensions; 在控制器和 @using 中.App.Extensions 带有 .cshtml 视图文件.

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

保存您的文件,您就完成了.现在每个视图都会知道您的扩展.

您可以访问扩展方法:

var orgId = User.Identity.GetOrganizationId();

I'm using MVC5 Identity 2.0 for users to log into my website, where the authentication details are stored in an SQL database. Asp.net Identity has been implemented in a standard way as can be found in many online tutorials.

The ApplicationUser class in IdentityModels has been extended to include some custom properties, such as an integer OrganizationId. The idea is that many users can be created and assigned to a common Organization for database relationship purposes.

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; }
    }

How can I retrieve the OrganizationId property of the currently logged in user from within a controller? Is this available via a method once a user is logged in or do I always have the retrieve the OrganizationId from the database, based on the UserId, every time a controller method executes?

Reading around on the web I have seen I need to use the following to get the logged in UserId etc.

using Microsoft.AspNet.Identity;
...
User.Identity.GetUserId();

However, OrganizationId is not a property available in User.Identity. Do I need to extend User.Identity to include the OrganizationId property? If so, how do I go about this.

The reason I need the OrganizationId so often is that many table queries are reliant on the OrganizationId to retrieve data relevant to the Organization that's associated to the logged in user.

解决方案

Whenever you want to extend the properties of User.Identity with any additional properties like the question above, add these properties to the ApplicationUser class first like so:

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; }
}

Then what you need is to create an extension method like so (I create mine in an new Extensions folder):

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;
        }
    }
}

When you create the Identity in the ApplicationUser class, just add the Claim -> OrganizationId like so:

    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;
    }

Once you added the claim and have your extension method in place, to make it available as a property on your User.Identity, add a using statement on the page/file you want to access it:

in my case: using App.Extensions; within a Controller and @using. App.Extensions withing a .cshtml View file.

EDIT:

What you can also do to avoid adding a using statement in every View is to go to the Views folder, and locate the Web.config file in there. Now look for the <namespaces> tag and add your extension namespace there like so:

<add namespace="App.Extensions" />

Save your file and you're done. Now every View will know of your extensions.

You can access the Extension Method:

var orgId = User.Identity.GetOrganizationId();

这篇关于如何扩展 User.Identity 的可用属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆