【问题标题】:Can you store UserId inside Owin OAUTH 2 token?您可以将 UserId 存储在 Owin OAUTH 2 令牌中吗?
【发布时间】:2016-07-06 00:40:05
【问题描述】:

我需要从 Asp.Net 用户授权系统获取 UserId,因为我的大部分数据都存储在 SQL 中,并且使用 UserId 作为用户拥有该数据的标记。使用 Owin OAuth 2.0 我无法使用身份获取 UserId,它返回 null。所以我想出了这个解决方案:

令牌提供者

identity.AddClaim(new Claim("user_id", user.Id));

API

ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
var userName = principal.Claims.Where(c => c.Type == "user_id").Single().Value;

更简单的 API 代码

var userName = ClaimsPrincipal.Current.Claims.First(c => c.Type == "user_id").Value;

这种方法是否适合企业业务级应用程序,是否安全、可靠和健壮?或者你会(也许)提供其他建议吗?

当此功能(可能)由 Microsoft.AspNet.Identity(.NET 本身)提供时,我只是不喜欢在令牌中传递 UserId 的想法,但由于我无法使其工作,这是我的目前唯一的选择。

无论如何,我部分使用来自this great tutorial repository 的代码。如您所见,此控制器已注释了使用 Identity 获取 UserId 的行。但这对我不起作用,所以我使用了另一条使用声明的注释行。

【问题讨论】:

  • 你把这两行代码放在哪里,在控制器或过滤器中?
  • 在控制器(ApiController)中
  • 每个控制器都有 User 属性,所以修改你的第一行代码:ClaimsPrincipal principal = User as ClaimPrincipal; 然后它就可以工作了

标签: c# asp.net .net asp.net-mvc owin


【解决方案1】:

既然您使用的是 OWIN,我将假设您也使用 ASP.NET Identity。您不需要将用户 ID 存储为声明。您可以随时通过以下方式获取它:

User.Identity.GetUserId()

如果 Intellisense 出现问题,您只需添加 Microsoft.AspNet.Identity 命名空间。

【讨论】:

  • 嗯,我试过很多次了。这包括多次重新安装 Microsoft.AspNet.Identity.Core 包,也使用 Microsoft.AspNet.Identity,问题是 User.Identity.GetUserId() 返回 null。是的,我的控制器受到 [Authorize] 的完全保护。刚才我也试过安装Microsoft.AspNet.Identity.Owin包,结果一样。
  • 如果返回 null,则表示用户是匿名的,即未经过身份验证。干净利落。尝试从声明中获取 id 无济于事,因为它也会在那里为 null。
  • 另外如果是null可能是你在startup.cs中正确配置了认证
  • 刚刚记住了 OAuth 相关性,所以让我重新表述一下。当您通过 OAuth 向第三方进行身份验证时,这不会在 ASP.NET Identity 中对您进行身份验证。仍然必须有一个与该 OAuth 登录相关联的 ASP.NET 身份用户。如果您不采取实际创建/登录 ASP.NET 身份用户的步骤,那么无论您向多少第三方进行身份验证,您仍然是匿名的。也许这就是问题所在?
  • 不知道该告诉你什么,但 Identity 工作得很好。它已经发布了一年多,它是第 2 版,它被包括我自己在内的所有开发人员使用,没有任何问题。如果GetUserId 返回 null,则您未通过身份验证。时期。句号。至于为什么您可能无法通过身份验证,这是一个完全不同的问题。
【解决方案2】:

我假设以下代码中的 identity 对象属于 ClaimsIdentity 类型。你是如何以及在哪里初始化这个对象的?

identity.AddClaim(new Claim("user_id", user.Id));

如果您查看在 Visual Studio 中为 Web 应用程序生成的默认模板,将会有一个 IdentityModel 类,您可以在其中看到如下代码,当您登录 ASP.Net Identity 时会调用它。

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

这还负责添加默认声明数据,您还可以扩展它以添加其他信息,例如用户电话号码(主要是为了避免往返数据库并将其他用户信息存储为声明)。

那么你什么时候创建 identity 对象?

如果您有疑问,是否可以添加更多信息作为声明,我想应该可以。还有

的输出是什么
identity.GetUserId();

在你的情况下?

您可以按照http://anthonychu.ca/post/aspnet-identity-20---logging-in-with-email-or-username/ 中的说明进一步编写自己的 IdentityExtensions 类

更新 1 -

当您使用 ASP.Net 身份系统登录时,它会调用 GenerateUserIdentityAsync,后者在内部调用在 UserClaimsPrincipalFactory 类中定义的 CreateAsync 方法。这是代码https://github.com/aspnet/Identity/blob/daa50df87feb9f1b59858a22f00a2984996738c6/src/Microsoft.AspNet.Identity/UserClaimsPrincipalFactory.cs。如果你看一下这个方法,它实际上会做你正在做的事情

var id = new ClaimsIdentity(Options.Cookies.ApplicationCookieAuthenticationScheme, Options.ClaimsIdentity.UserNameClaimType, Options.ClaimsIdentity.RoleClaimType); 
id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId)); . 

所以我相信你也需要这样做

【讨论】:

  • GetUserId() 的输出是null。我有点想出如何简化我的代码:ClaimsPrincipal.Current.Claims.First(c =&gt; c.Type == "userId").Value; 也可以。而且我没有在任何地方创建身份对象,也没有在任何地方声明它,我什至在我的 API 控制器中没有数据库连接。 API 和 Token server 是完全解耦的, Token server(带有数据库连接和 AccountController)是提供 token 和声明,API server 只是提供基于 Token 的授权(资源访问)
  • 那么你的代码identity.AddClaim中的身份对象类型是什么?
  • ClaimsIdentity(OAuthGrantResourceOwnerCredentialsContext context.Options.AuthenticationType)
  • 好的。所以我要问的是这是用什么初始化的?在身份的情况下,我们有这样的东西var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
  • 这就是问题所在。当您使用 ASP.Net 身份系统登录时,它会调用 GenerateUserIdentityAsync,它会在内部调用在 UserClaimsPrincipalFactory 类中定义的 CreateAsync 方法。这是代码github.com/aspnet/Identity/blob/…。如果您查看此方法,它实际上会明确执行您正在执行的操作。
猜你喜欢
  • 2023-03-05
  • 2018-08-02
  • 2014-10-05
  • 2021-01-14
  • 2020-12-12
  • 2018-05-27
  • 2019-03-21
  • 2011-09-12
  • 2019-08-08
相关资源
最近更新 更多