帐户被重置为未确认

时间:2014-12-10 16:13:07

标签: asp.net-mvc asp.net-identity asp.net-identity-2

我有一个场景,其中用户帐户被重置为未确认,并且其密码哈希和安全戳记被设置为null。每当我重新发送确认电子邮件时,我都会收到令牌无效的错误。这在创建新用户并发送确认电子邮件时非常适用。

System.Exception: Invalid token.
   at PRISMdev.Controllers.AccountController.AddErrors(IdentityResult result)
   at PRISMdev.Controllers.AccountController.<ConfirmEmail>d__d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)

ResendConfirmEmail

public async Task<ActionResult> ResendConfirmationEmail(string email)
        {
            ApplicationUser applicationUser = await UserManager.FindByEmailAsync(email);

            if (applicationUser == null)
            {
                return Json(new { success = false });
            }
            else
            {
                var code = Url.Encode(await UserManager.GenerateEmailConfirmationTokenAsync(applicationUser.Id));

                //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = applicationUser.Id, code = code }, protocol: Request.Url.Scheme);

                var callbackUrl = Url.Action("ConfirmEmail", "Account", new {area = "", userId = applicationUser.Id, code = code }, protocol: Request.Url.Scheme);

                //string callbackUrl = Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host + (Request.Url.IsDefaultPort ? "" : ":" + Request.Url.Port) + "/Account/ConfirmEmail?userId=" + Url.Encode(applicationUser.Id) + "&code=" + Url.Encode(code);

                EmailHelper newEmail = new EmailHelper();
                newEmail.To = applicationUser.Email;
                newEmail.Subject = "PRISM-Assoc Confirm Account";
                newEmail.BodyText = string.Format("Please click on this link to {0}: {1}", newEmail.Subject, callbackUrl);
                newEmail.BodyHtml = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.";

                newEmail.SendEmail();

                return Json(new { success = true });
            }

            return View();
        }

确认电子邮件

public async Task<ActionResult> ConfirmEmail(string userId, string code)
        {
            ViewBag.headerTitle = "Account Confirmed";
            if (userId == null || code == null) 
            {
                return View("Error");
            }


            IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);
            if (result.Succeeded)
            {
                //send email for reseting password.
                await SendResetPasswordEmail(userId);               

                return View("ConfirmEmail");
            }
            else
            {
                AddErrors(result);
                return View();
            }
        }

Startup.Auth.cs

public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}

身份模型

public class ApplicationUser : IdentityUser
    {
        // Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model. https://gridmvc.codeplex.com/
        [Display(Name = "Name")]
        [GridColumn(Title = "Name", SortEnabled = true, FilterEnabled = true, Width = "100")]
        public string Name { get; set; }

        [Display(Name = "Position")]
        [GridColumn(Title = "Position", SortEnabled = true, FilterEnabled = true, Width = "50")]
        public string Position { get; set; }

        [NotMappedColumn]
        public DateTime? RegisteredDate { get; set; }

        [Display(Name = "Last Date Visited")]
        [GridColumn(Title = "Last Visited", SortEnabled = true, FilterEnabled = true, Width = "40")]
        public DateTime? LastVisitDate { get; set; }

        [GridColumn(Title = "Org.", SortEnabled = true, Width = "100")]
        public int? MemberOrgId { get; set; }

        [NotMappedColumn]
        public int? SponsorOrgId { get; set; }

        [Display(Name = "Profile Picture")]
        //[GridColumn(Title = "Profile Pic.", SortEnabled = true, FilterEnabled = true)]
        [NotMappedColumn]
        public string ProfilePictureSrc { get; set; }

        [Display(Name = "Forum Username")]
        //[GridColumn(Title = "Forum Username", SortEnabled = true, FilterEnabled = true, Width = "30")]
        [NotMappedColumn]
        public string ForumUsername { get; set; }

        [Display(Name = "Receive System Emails")]
        //[GridColumn(Title = "Rec. Sys Emails", SortEnabled = true, Width = "30")]
        [NotMappedColumn]
        public Boolean ReceiveSystemEmails { get; set; }

        //////[ForeignKey("MemberOrgId")]
        [NotMappedColumn]
        public virtual MemberOrganizations Organization { get; set; }

        //////[ForeignKey("SponsorOrgId")]
        [NotMappedColumn]
        public virtual SponsorOrganizations Sponsor { get; set; }


        [Display(Name = "User Img")]
        [UIHint("ProfPictureEdit")]
        public virtual string ProfilePictureUrl
        {
            get
            {

                //TODO: update the folder when it isn't null to the blob location
                if (string.IsNullOrEmpty(this.ProfilePictureSrc))
                {
                    return "/Content/Images/userThumb.png";
                }
                else
                {
                    BlobHelper helper = new BlobHelper();
                    string url = helper.getImageUrl(this.ProfilePictureSrc, "profilepicture");

                    return url;
                }
            }
        }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        //public DbSet<Users> Users { get; set; }
        public DbSet<MemberOrganizations> MemberOrganizations { get; set; }
        public DbSet<ServiceCategories> ServiceCategories { get; set; }
        public DbSet<SponsorOrganizations> SponsorOrganizations { get; set; }
        public DbSet<SponsorServiceCategories> SponsorServiceCategories { get; set; }
        public DbSet<MemberProjects> MemberProjects { get; set; }
        public DbSet<MemberRFPs> MemberRFPs { get; set; }
        public DbSet<OptionTypes> OptionTypes { get; set; }
        public DbSet<Options> Options { get; set; }
        public DbSet<MemberOrganizationsFundTypes> MemberOrganizationsFundTypes { get; set; }
        public DbSet<MemberOrganizationsPlanTypes> MemberOrganizationsPlanTypes { get; set; }
        public DbSet<MemberOrganizationsOperatingSystems> MemberOrganizationsOperatingSystems { get; set; }
        public DbSet<MemberOrganizationsDatabases> MemberOrganizationsDatabases { get; set; }
        public DbSet<BoardAndDirectors> BoardAndDirectors { get; set; }
        public DbSet<Pages> Pages { get; set; }
        public DbSet<SiteFiles> SiteFiles { get; set; }
        public DbSet<Surveys> Surveys { get; set; }
        public DbSet<BoardEvents> BoardEvents { get; set; }
        public DbSet<PRISMEvent> PRISMEvents { get; set; }
        public DbSet<PRISMEventGuestAttendees> PRISMEventGuestAttendees { get; set; }
        public DbSet<PRISMEventMemberAttendees> PRISMEventMemberAttendees { get; set; }
        public DbSet<PRISMEventSponsorAttendees> PRISMEventSponsorAttendees { get; set; }
        public DbSet<CustomEmailsAndMessages> CustomEmailsAndMessages { get; set; }
        public DbSet<NonSiteMemberProfile> NonSiteMemberProfile { get; set; }
        public DbSet<MemberDues> MemberDues { get; set; }
        public DbSet<MemberDuesReceived> MemberDuesReceived { get; set; }
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

identityconfig.cs

public class ApplicationUserManager : UserManager<ApplicationUser>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser> store)
            : base(store)
        {
        }

        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
        {
            var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
            // Configure validation logic for usernames
            manager.UserValidator = new UserValidator<ApplicationUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };
            // Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 8,
                RequireNonLetterOrDigit = true,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };
            // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
            // You can write your own provider and plug in here.
            manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
            {
                MessageFormat = "Your security code is: {0}"
            });
            manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
            {
                Subject = "Security Code",
                BodyFormat = "Your security code is: {0}"
            });
            manager.EmailService = new EmailService();
            manager.SmsService = new SmsService();
            var dataProtectionProvider = options.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
            }
            return manager;
        }
    }

0 个答案:

没有答案