2015-10-14 85 views
2

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

令牌提供商

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的行。但是这对我不起作用,所以我正在使用另一条使用声明的注释行。

+0

你在哪里把这个代码两行,在控制器或过滤器? –

+0

在控制器(ApiController) – EwanCoder

+0

每个控制器都会有'用户'属性,所以改变你的第一行代码:'ClaimsPrincipal principal = User作为ClaimPrincipal;'然后它工作 –

回答

4

因为您使用的是OWIN,所以我会假设您使用的是ASP.NET Identity。您不需要将用户标识作为索赔存储。你可以把它任何时候你需要通过:

User.Identity.GetUserId() 

如果智能感知怪胎,你只需要添加Microsoft.AspNet.Identity命名空间。

+1

好吧,我**多次尝试**。这包括多次重新安装Microsoft.AspNet.Identity.Core包,同时使用Microsoft.AspNet.Identity,事情是'User.Identity.GetUserId()'返回null。是的,我的控制器完全由[Authorize]保护。 我也尝试过安装Microsoft.AspNet.Identity.Owin软件包,结果相同。 – EwanCoder

+0

如果它返回null,这意味着用户是匿名的,即未验证。干净利落。试图从索赔中获得ID不会有帮助,因为它在那里也是空的。 –

+0

另外,如果它是'null',它可能是你已经在'startup.cs'中正确配置了认证。 –

0

我假设身份对象在下面的代码是ClaimsIdentity。你如何以及在哪里初始化这个对象?

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

如果你看一下这是一种Web应用程序在Visual Studio中会有一个IdentityModel类在这里你可以看到如下的代码生成的,当你在ASP.Net身份签到这就是所谓的默认模板。

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

而且这是负责添加默认权利要求数据并且还可以扩展这个添加像用户PHONENUMBER附加信息(主要是为了避免往返于数据库,并存储附加用户信息,如权利要求)。

那么你什么时候创建标识对象?

如果你是问题是否可以添加更多的信息作为索赔我想这应该是好的。还有什么输出

identity.GetUserId(); 

在你的情况?使用ASP.Net识别系统调用GenerateUserIdentityAsync在内部调用UserClaimsPrincipalFactory类中定义的方法CreateAsync

当您注册 -

http://anthonychu.ca/post/aspnet-identity-20---logging-in-with-email-or-username/

更新1说明,您可以进一步编写自己的IdentityExtensions类。这里是代码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)); . 

所以我相信这就是你还需要做

+0

GetUserId()的输出为null。我有点想出如何简化我的代码:'ClaimsPrincipal.Current.Claims.First(c => c.Type ==“userId”)。Value;'也可以。我不是在任何地方创建身份对象,也不是在任何地方声明,我甚至在我的API控制器中没有数据库连接。 API和令牌服务器完全分离,其中令牌服务器(带有数据库连接和AccountController)给出令牌和声明,API服务器仅提供基于令牌的授权(资源访问) – EwanCoder

+0

那么代码中的身份对象的类型是什么? identity.AddClaim? –

+0

ClaimsIdentity(OAuthGrantResourceOwnerCredentialsContext context.Options.AuthenticationType) – EwanCoder