MVC5 (VS2012) Identity CreateIdentityAsync - Value cannot be null

Jon picture Jon · Feb 20, 2014 · Viewed 24.1k times · Source

I am trying to setup OAuth for a an MVC5 site (in VS2012).

I am using Fluent NHibernate. I have setup my own Userstore and pass in a repository object to access NHibernate session object. I pass my store into the default aspnet usermanager provider. This eventually worked for local registration and logging in. I am not trying to setup connecting / registering with Facebook.

It gets a successful account. Adds a user in the user table, adds a record in the logins table and then blows up. I have not implements claims in the user store, or put a claims collection in the user object. (not sure if this is actually required, I was stripping everything back that might be going wrong to find the source of the issue).

The line that blows up is, (in the account controller):

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);            

within this method:

private async Task SignInAsync(IdentityUser user, bool isPersistent)

this is the end of the stack trace

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

I can include my userstore code if wanted: I didn't put it in as it's a large file and might detract from the issue.

I am not sure why it is even trying to create the claim object and why it is blowing up. As I only have VS2012 I have been patching it all together from examples online mainly.


As suggested by @Shoe I inherited from 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);
    }
}

It now no longer throws an error but doesn't actually authenticate me how ever many times I use the Facebook register / login.


To summarize. With @Shoe's info I tried both overriding UserManager.CreateIdentityAsync with:

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

and also trying to implement IUserClaimStore with the returning default (empty list).

The first will not through an error but does not end up authenticated. The later will still through the odd claim "System.Security.Claims.Claim..ctor" error

EDIT

Found out why the ctor error was occurring. The user object was coming back without the ID so the default UserManager was getting upset. Fixed that and used the default UserManager which now no longer throws an error, but still doesn't log the user in. The identity object it returns looks good from what I can tell.

Answer

Patrick Desjardins picture Patrick Desjardins · Apr 29, 2014

I had the same error in the past but only when I created user with Entity Framework Migration Tool. When creating a user and signing withing the website, I had not error.

My error was that I was not providing a SecurityStamp with migration.

SecurityStamp = Guid.NewGuid().ToString()

This property set, everything worked.