用于Owin的DpapiDataProtectionProvider的Asp.Net身份默认名称

时间:2018-09-20 16:01:16

标签: c# asp.net asp.net-identity asp.net-identity-2

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

由于DpapiDataProtectionProvider的名称和DataProtectorTokenProvider.Create的用途都必须匹配才能使生成的密码重置令牌起作用,因此事实证明这是一个问题。我们不会在客户端域上使用Owin,因此会在管理Web应用程序上创建与这些条件匹配的新DpapiDataProtectionProviderDataProtectorTokenProvider

我们通过使用相同的ApplicationUserManager创建相同的UserTokenProvider来使其正常工作,但是我们想在客户端使用Owin实例。

作品:

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 个答案:

答案 0 :(得分:0)

更新

根据https://github.com/aspnet/Identity/blob/master/src/Identity/DataProtectionTokenProvider.cs,在给出代码const sockend = new cote.Sockend(io, { name: 'Sockend', // key: 'a certain key' }); 的情况下应为const sockend = new cote.Sockend(io, { name: 'Sockend', namespace: '/cmd' });

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

原始

我没有找到Owin的名字,但是我测试了我的安全隐患。使用以下方法创建了两个Web应用程序。在WebApplication1中创建用户时,我也从该值中复制了用户ID,这也是为WebApplication2创建的用户,因此他们对方法DataProtectorTokenProvider具有相同的GUID。测试令牌时,即使用户具有相同的ID,并且Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider")manager.GeneratePasswordResetToken(identityUser.Id)的创建完全相同,令牌也仅适用于WebApplication1,而不适用于WebApplication2。

DpapiDataProtectionProvider