代码之家  ›  专栏  ›  技术社区  ›  Ogglas

owin的dpapidataProtectionProvider的ASP.NET标识默认名称

  •  0
  • Ogglas  · 技术社区  · 6 年前

    背景是我们当前的基础设施使用两个Web应用程序。一个Web应用程序管理用户,其他用户可以登录并重置其密码。从管理区域,我们需要能够启动密码重置,最好不要在另一个域上调用API操作。

    因为这两个名字 DpapiDataProtectionProvider 以及目的 DataProtectorTokenProvider.Create 需要匹配才能使生成的密码重置令牌工作,这已被证明是一个问题。我们不想在客户机域上使用owin,因此创建一个新的 DPAPIDataProtectionProvider(DPAPIDataProtectionProvider) DataProtectorTokenProvider 与管理Web应用程序上的这些条件相匹配。

    我们通过创建相同的 ApplicationUserManager 用同样的方法 UserTokenProvider 但我们希望在客户端使用toown实例。

    作品:

    var db = new ApplicationDbContext();
    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db));
    var provider = new DpapiDataProtectionProvider("ASP.NET Identity");
    manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
        provider.Create("ASP.NET Identity"));
    

    看着 App_Start -> IdentityConfig.cs -> 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 Identity"));
    }
    

    但是我找不到它的名字 DataProtectionProvider 那是类型的 IDataProtectionProvider 被设置。接口只有一个方法,即 IDataProtector Create(params string[] purposes); 我怎么知道这个名字?这会以某种方式影响安全吗?我想下面唯一缺少的就是 new DpapiDataProtectionProvider("<MISSING>"); 应该有的。

    [HttpGet]
    [AllowAnonymous]
    [Route("testReset")]
    public IHttpActionResult TestResetAdminDomain()
    {
        var db = new ApplicationDbContext();
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db));
        var provider = new DpapiDataProtectionProvider("ASP.NET Identity");
        manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
            provider.Create("ASP.NET Identity"));
    
        var email = "test@test.com";
    
        var user = new ApplicationUser() { UserName = email, Email = email };
    
        var identityUser = manager.FindByEmail(email);
    
        if (identityUser == null)
        {
            manager.Create(user);
            identityUser = manager.FindByEmail(email);
        }
    
        var token = manager.GeneratePasswordResetToken(identityUser.Id);
        return Ok(HttpUtility.UrlEncode(token));
    }
    
    [HttpGet]
    [AllowAnonymous]
    [Route("testResetWithOwin")]
    public IHttpActionResult TestResetWithOwinClientDomain(string token)
    {
        var manager = Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
    
        var email = "test@test.com";
        var identityUser = manager.FindByEmail(email);
        var valid = Task.Run(() => manager.UserTokenProvider.ValidateAsync("ResetPassword", token, manager, identityUser)).Result;
        var result = manager.ResetPassword(identityUser.Id, token, "TestingTest1!");
        return Ok(result);
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Ogglas    6 年前

    更新:

    根据 https://github.com/aspnet/Identity/blob/master/src/Identity/DataProtectionTokenProvider.cs 应该是 DataProtectorTokenProvider 给定代码 Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider")

    如果创建了一个令牌,它需要被相同的令牌使用 应用程序池 !当在不同的应用程序池用户上测试代码时,代码没有通过,当应用程序池用户相同时,代码正常工作。

    原件:

    我没有找到欧文的名字,但我测试了我的安全问题。使用以下方法创建了两个Web应用程序。在webapplication1中创建用户时,我也从该值中复制了用户ID,即为webapplication2创建的用户,因此他们对该方法具有相同的guid ID。 manager.GeneratePasswordResetToken(identityUser.Id) . 测试令牌时,仅适用于WebApplication1,而不适用于WebApplication2,即使用户具有相同的ID和 DpapiDataProtectionProvider 数据保护TortokenProvider 创建完全相同。

    [HttpGet]
    [AllowAnonymous]
    [Route("testReset")]
    public IHttpActionResult TestResetAdminDomain()
    {
        var db = new ApplicationDbContext();
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db));
        var provider = new DpapiDataProtectionProvider("ASP.NET Identity");
        manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
            provider.Create("ASP.NET Identity"));
    
        var email = "test@test.com";
    
        var user = new ApplicationUser() { UserName = email, Email = email };
    
        var identityUser = manager.FindByEmail(email);
    
        if (identityUser == null)
        {
            manager.Create(user);
            identityUser = manager.FindByEmail(email);
        }
    
        var token = manager.GeneratePasswordResetToken(identityUser.Id);
        return Ok(HttpUtility.UrlEncode(token));
    }
    
    [HttpGet]
    [AllowAnonymous]
    [Route("testReset")]
    public IHttpActionResult TestResetClientDomain(string token)
    {
        var db = new ApplicationDbContext();
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db));
        var provider = new DpapiDataProtectionProvider("ASP.NET Identity");
        manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
            provider.Create("ASP.NET Identity"));
        var email = "test@test.com";
        var identityUser = manager.FindByEmail(email);
        var valid = Task.Run(() => manager.UserTokenProvider.ValidateAsync("ResetPassword", token, manager, identityUser)).Result;
        var result = manager.ResetPassword(identityUser.Id, token, "TestingTest1!");
        return Ok(result);
    }