【发布时间】:2014-03-21 23:56:48
【问题描述】:
我正在尝试为 MVC5 站点(在 VS2012 中)设置 OAuth。
我正在使用 Fluent NHibernate。我已经设置了自己的 Userstore 并传入了一个存储库对象来访问 NHibernate 会话对象。我将我的商店传递给默认的 aspnet 用户管理器提供程序。这最终适用于本地注册和登录。我不想设置连接/注册 Facebook。
它获得了一个成功的帐户。在 user 表中添加一个用户,在 logins 表中添加一条记录,然后炸毁。我没有在用户存储中实现声明,也没有在用户对象中放置声明集合。 (不确定这是否真的需要,我正在剥离可能出错的所有内容以找到问题的根源)。
爆炸的那一行是,(在帐户控制器中):
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
在这个方法中:
private async Task SignInAsync(IdentityUser user, bool isPersistent)
这是堆栈跟踪的结尾
[ArgumentNullException: Value cannot be null.
Parameter name: value]
System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue) +14108789
System.Security.Claims.Claim..ctor(String type, String value, String valueType) +62
Microsoft.AspNet.Identity.<CreateAsync>d__0.MoveNext() +481
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +49
Web.Controllers.<SignInAsync>d__42.MoveNext() in d:\Google Drive\Development\GoalManagement\Web\Controllers\AccountController.cs:375
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
Web.Controllers.<ExternalLoginConfirmation>d__35.MoveNext() in d:\Google Drive\Development\GoalManagement\Web\Controllers\AccountController.cs:311
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
public class IdentityUser : IUser
{
public IdentityUser()
{
Logins = new List<IdentityUserLogin>();
}
public string Id { get; set; }
public string UserName { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public IList<IdentityUserLogin> Logins { get; set; }
}
public class IdentityUserLogin
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
}
如果需要,我可以包含我的用户存储代码:我没有将其放入,因为它是一个大文件,可能会影响问题。
我不确定为什么它甚至试图创建声明对象以及它为什么会爆炸。因为我只有VS2012,所以我主要是从网上的例子修补起来的。
正如@Shoe 所建议的,我继承自UserManager:
public class NHibernateAspnetUserManager<TUser> : UserManager<TUser> where TUser : IdentityUser
{
public NHibernateAspnetUserManager(IUserStore<TUser> store) : base(store)
{
}
public override Task<ClaimsIdentity> CreateIdentityAsync(TUser user, string authenticationType)
{
ClaimsIdentity identity = new ClaimsIdentity();
return Task.FromResult(identity);
}
}
它现在不再抛出错误,但实际上并没有对我使用 Facebook 注册/登录多少次进行身份验证。
总结一下。使用@Shoe 的信息,我尝试使用以下方法覆盖UserManager.CreateIdentityAsync:
public override Task<ClaimsIdentity> CreateIdentityAsync(TUser user, string authenticationType)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
return Task.FromResult(identity);
}
并且还尝试使用返回的默认值(空列表)来实现 IUserClaimStore。
第一个不会通过错误但最终不会通过身份验证。后者仍然会通过奇怪的声明“System.Security.Claims.Claim..ctor”错误
编辑
找出发生 ctor 错误的原因。用户对象在没有 ID 的情况下返回,因此默认的 UserManager 变得不安。修复了这个问题并使用了默认的UserManager,它现在不再引发错误,但仍然不会让用户登录。据我所知,它返回的身份对象看起来不错。
【问题讨论】:
-
我使用了内置的用户管理器...尝试使用 resharper 对其进行反编译,但没有任何 readbale 出现在另一端。
标签: asp.net asp.net-mvc-5 asp.net-identity identity claims-based-identity