我正在使用Fluent NHibernate。我已经设置了自己的Userstore,并传递一个仓储对象来访问NHibernate会话对象。我将我的存储传递给默认的aspnet usermanager提供程序。这最终适用于本地注册和登录。我现在尝试连接/注册Facebook。
它成功获取帐户信息。在用户表中添加一个用户,在登录表中添加一条记录,然后出现错误。我没有在用户存储中实现claims,也没有在用户对象中放置claims collection。(不确定是否实际上需要这样做,我正在剥离所有可能引起问题的内容以查找问题的来源)。
在账户控制器中,出现错误的代码是:
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; }
}
如果需要,我可以包含我的用户存储代码:我没有把它放进去,因为它是一个很大的文件,可能会分散注意力。
我不确定为什么它甚至要尝试创建claim对象并为什么会出错。由于我只有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”错误。
编辑
找出了为什么会发生构造函数错误。用户对象返回时没有ID,因此默认的感到不满。解决了这个问题并使用了默认的,它现在不再抛出错误,但仍无法登录用户。从我所看到的来看,它返回的标识对象很好。