2

This is a continuation of this question.

If I override the 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)
    {
        var identity = new ClaimsIdentity();
        identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
        return Task.FromResult(identity);
    }
}

This doesn't throw any errors but will not log the user in, (log process happens but @Request.IsAuthenticated will always return false). If I don't override it then I get a "System.Security.Claims.Claim..ctor" error as described in the other question. To try and solve that my own userstore implemented IUserClaimStore but simply return a new list of claims.

I am not sure what the default usermanager does under the hood that differs. I am guessing it sets up some form of claim identity object that allows MVC to recognise someone as logged in.

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);            
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent}, identity); 

EDIT

Found out why the ctor error was occuring. 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.

FURTHER NOTE

So I installed VS2013 and copied the store and NHibernate repo across, all worked first time. I can only assume there is some sutble difference between creating it and updating MVC5 in VS2012 and doing it in VS2013.

Community
  • 1
  • 1
Jon
  • 15,110
  • 28
  • 92
  • 132

2 Answers2

0

So the main issue is that you aren't respecting the authentication type in your method, you need to create a ClaimsIdentity for DefaultAuthenticationType.ApplicationCookie, here's what the default claims factory does:

    public override Task<ClaimsIdentity> CreateIdentityAsync(TUser user, string authenticationType)
    {
        var id = new ClaimsIdentity(authenticationType, UserNameClaimType, RoleClaimType);
        id.AddClaim(new Claim(UserIdClaimType, ConvertIdToString(user.Id), ClaimValueTypes.String));
        id.AddClaim(new Claim(UserNameClaimType, user.UserName, ClaimValueTypes.String));
Hao Kung
  • 28,040
  • 6
  • 84
  • 93
0

I've faced the same problem implementing custom identity using ASP.NET 4.5. And the problem really was in adding null values into the Claims collection (see the comments):

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new AppUser { UserName = model.UserName };
        // after the UserManager creates a user, all the properties of 
        // AppUser except "UserName" are automatically discarded            
        var result = await UserManager.CreateAsync(new AppUser
            {
                UserRealName = model.UserRealName,
                UserName = model.UserName,
                Password = model.Password
            }, model.Password); 
        if (result.Succeeded)
        {
            // So we need to re-get the new user
            user = AppUser.GetByName(model.UserName); 
            await SignInAsync(user, false); // otherwise here we will add null values ...
            return RedirectToAction("Index", "Home");
        }
        AddErrors(result);
    }
    return View(model);
}

private async Task SignInAsync(AppUser user, Boolean isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
    var identity = await UserManager.CreateIdentityAsync(user, 
        DefaultAuthenticationTypes.ApplicationCookie);
    AuthenticationManager.SignIn(new AuthenticationProperties // ... into the list of 
    // claims for all AppUser properties except UserName
        { IsPersistent = isPersistent }, identity);
}
Oleg
  • 1,291
  • 13
  • 16