【问题标题】:How to implement a TokenProvider in ASP.NET Identity 1.1 nightly build?如何在 ASP.NET Identity 1.1 nightly build 中实现 TokenProvider?
【发布时间】:2013-11-01 14:31:01
【问题描述】:

我正在尝试使用每晚构建的 ASP.NET Identity 1.1 来实现密码重置功能。有一个 UserManager.GetPasswordResetToken 方法,但它会引发异常“未注册 ITokenProvider”。 ASP.NET Identity 中是否有内置的令牌提供程序?如果是,我该如何注册?如果没有,我该如何实施?将是 1.1 中的默认 Token Provider。发布?最后一个问题,有估计的 1.1 发布日期吗?

【问题讨论】:

    标签: c# asp.net asp.net-mvc-5 asp.net-identity


    【解决方案1】:

    默认令牌提供程序实现在 Microsoft.Identity.Owin 包中:

    /// <summary>
    /// Token provider that uses a DataProtector to generate encrypted tokens
    /// </summary>
    public class DataProtectorTokenProvider : ITokenProvider {
        public DataProtectorTokenProvider(IDataProtector protector)
    

    然后您使用 OWIN IAppBuilder 中的默认数据保护提供程序进行这样的操作来连接一个。

    IDataProtectionProvider provider = app.GetDataProtectionProvider();
    if (provider != null)
    {
        manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("PasswordReset"));
        manager.UserConfirmationTokens = new DataProtectorTokenProvider(provider.Create("ConfirmUser"));
    }
    

    【讨论】:

    • 谢谢,看起来很有希望。只有一个问题:如何从我初始化 UserManager 的地方(例如,从 AccountController)访问 IAppBuilder 应用程序?
    • 这是在哪个夜间版本中?我正在使用 1.1.0-alpha1-131024 (Prerelease) 软件包,但没有看到 GetDataProtectionProvider 方法。如果有默认令牌提供程序,为什么没有使用它初始化 PasswordResetTokensUserConfirmationTokens 属性,所以我们不必跳过这些箍来使用它们?除非您需要更改令牌的生成方式,否则这应该“开箱即用”,无需任何额外工作,或者(至少对我而言)创建默认提供程序实际上没有意义。跨度>
    • 所以它们不是Identity.Core的一部分并且存在于Identity.Owin中的原因是Core不能依赖Owin,并且默认实现来自Owin。我相信 GetDataProtectionProvider 作为 IAppBuilder 的扩展方法存在于 Microsoft.Owin.Security.DataProtection 中。
    • 在您指定的命名空间中找到了方法。我仍然认为所有这些都应该开箱即用。除非我想更改令牌提供者的工作方式,否则我不应该设置任何这些。
    • 看来,对于 ASP.NET Identity 2.0 alpha 中的帐户确认/忘记密码功能,您需要为 UserManager 等重新设计所有初始化代码。只需查看此示例 MVC 应用程序@987654321 @ Samples->Identity->Identity-PasswordPolicy 并将其与默认的 RTM MVC 5 应用程序进行比较,您将看到不同之处。初始化内容(例如检查 Startup.Auth.cs)存在巨大差异,并且将对使用 ASP.NET Identity 1.0(当前 RTM)的任何 MVC 应用程序产生重大影响。不太好!
    【解决方案2】:

    好的,根据@hao-kung 的回复回答我自己的问题。首先将静态构造函数和UserManagerFactory添加到Statrup类(startup.auth.cs)

    public partial class Startup
    {
        static Startup()
        {
            UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
        }
    
        public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; }
    
        public void ConfigureAuth(IAppBuilder app)
        {
            var manager = UserManagerFactory();
            IDataProtectionProvider provider = app.GetDataProtectionProvider();
            if (provider != null)
            {
                manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("PasswordReset"));
                manager.UserConfirmationTokens = new DataProtectorTokenProvider(provider.Create("ConfirmUser"));
            }
    
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        }
    }
    

    然后使用该 UserManagerFactory 在 AccountController 中初始化 UserManager

    public AccountController() : this(Startup.UserManagerFactory())
    {
    }
    
    public AccountController(UserManager<IdentityUser> userManager)
    {
        UserManager = userManager;
    }
    
    public UserManager<IdentityUser> UserManager { get; private set; }
    

    【讨论】:

      【解决方案3】:

      另一种方法(建立在其他答案的基础上,但对其进行了一些简化)是更改Startup.Auth.cs,使其看起来类似于:

      public partial class Startup
      {
          internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
      
          public void ConfigureAuth(IAppBuilder app)
          {
              DataProtectionProvider = app.GetDataProtectionProvider();
          }
      }
      

      然后,修改AccountController.cs 中的默认构造函数,使其看起来像这样:

       public AccountController()
           : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
       {
           if (Startup.DataProtectionProvider != null)
           {
               this.UserManager.PasswordResetTokens = new DataProtectorTokenProvider(Startup.DataProtectionProvider.Create("PasswordReset"));
               this.UserManager.UserConfirmationTokens = new DataProtectorTokenProvider(Startup.DataProtectionProvider.Create("ConfirmUser"));
           }
       }
      

      【讨论】:

        【解决方案4】:

        如果有人在 AspNet.Identity 2.0 beta1 版本下寻找解决方案。

        只有这个需要修改。

        UserManager.UserTokenProvider = new DataProtectorTokenProvider
        <SecurityUser, string>(provider.Create("UserToken")) 
        as IUserTokenProvider<SecurityUser, string>;
        

        PasswordResetTokensUserConfirmationTokens 合并到 UserTokenProvider 属性中,令牌提供者类也被修改。

        【讨论】:

        • DataProtectorTokenProvider 来自哪里?
        • 来自Microsoft.AspNet.Identity.Owin命名空间。
        • 不,它不在里面。
        • 我不确定您使用的是哪个版本。你可以看这门课link
        • @jtsan 令牌生命周期是一个公共属性,因此您可以在每次调用之前设置它。新 DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")){ TokenLifespan = new TimeSpan() };
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-21
        • 2018-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多