Search code examples
c#asp.net-mvcwcfasp.net-identityasp.net-identity-2

Make ASP.NET Identity 2.0 Email confirm token work for WCF and MVC


I have a service project (WCF) and MVC project which uses same database, to handle service part for Mobile and Interface part. I have to set up email confirmation on both.

I have used OWIN ASP.NET 2.0 library for authentication, and both projects have separate UserManagers.

For MVC

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
  var dataProtectionProvider = options.DataProtectionProvider;
  if (dataProtectionProvider != null)
  {
    manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>dataProtectionProvider.Create("ASP.NET"));
  }
}

For WCF

var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET");
UserManager.UserTokenProvider =new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<ApplicationUser>(
provider.Create("EmailConfirm"));
var code = idManager.UserManager.GenerateEmailConfirmationToken(appuser.Id);

The Problem The email confirmation token generated in MVC works fine.

In WCF when i create an email confirmation token, it needs to be verified from MVC website. Here it gives me "Invalid Token".

I think it is due to the Token Codes not matching, I tried to make them same as i can, but don't really know which one goes where between Wcf and MVC.

btw. I am testing on localhost from Visual studio.


Solution

  • I found the solution. The problem was the DataProtectionProvider.

    On MVC, it was getting from:

    public static ApplicationUserManager    
        Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
          var dataProtectionProvider = **options.DataProtectionProvider**;
    

    On WCF, it was from:

    var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET");
    

    So I used same as WCF in MVC:

    var dataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET");
    

    Also, the key point is:

    • Provider name. It should be the same on both.
    • While creating the URL from WCF, we need to use HttpUtility.UrlEncode to encode the token code.

    Example:

    var code = UserManager.GenerateEmailConfirmationToken(appuser.Id);    
    var callbackUrl = string.Format("http://MVCSite/Account/ConfirmEmail?userId={0}&code={1}",    HttpUtility.UrlEncode(appuser.Id), HttpUtility.UrlEncode(code));
    

    Update

    For anyone trying to host multiple projects, you need one of these two things to be the same to still be able to use the confirmation code:

    • Application Pool
    • Machine Key

    Email Confirmation Error Invalid Token AspNet Identity

    http://gunaatita.com/Blog/How-to-Generate-Machine-Key-using-IIS/1058