Asp.Net Owin 的 DpapiDataProtectionProvider 的标识默认名称
Asp.Net Identity default name for DpapiDataProtectionProvider for Owin
背景是我们目前的基础设施使用两个网络应用程序。一个 Web 应用程序管理用户,而在另一个 Web 应用程序中,用户可以登录并重置他们的密码。从管理区域,我们需要能够启动密码重置,最好不要在其他域上调用 API 操作。
由于 DpapiDataProtectionProvider
的名称和 DataProtectorTokenProvider.Create
的用途都需要匹配才能使生成的密码重置令牌起作用,这已被证明是一个问题。我们不想在客户端域上使用 Owin,因此在管理 Web 应用程序上创建一个符合这些条件的新 DpapiDataProtectionProvider
和 DataProtectorTokenProvider
。
我们通过使用相同的 UserTokenProvider
创建相同的 ApplicationUserManager
使其工作,但我们想在客户端使用 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"));
}
但是我找不到 IDataProtectionProvider
类型的 DataProtectionProvider
名称的设置位置。该接口只有一个方法,那就是 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);
}
更新:
根据 https://github.com/aspnet/Identity/blob/master/src/Identity/DataProtectionTokenProvider.cs 给定代码 Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider")
应该是 DataProtectorTokenProvider
如果创建了一个令牌,它需要被同一个 应用程序池 使用!当代码在不同的应用程序池用户上测试时,代码没有通过,当应用程序池用户相同时,它正常工作。
原文:
我没有找到 Owin 的名字,但我测试了我的安全问题。使用以下方法创建了两个 Web 应用程序。在 WebApplication1 中创建用户时,我也从为 WebApplication2 创建的用户复制了该值中的用户 ID,因此它们对方法 manager.GeneratePasswordResetToken(identityUser.Id)
具有相同的 guid ID。测试时,令牌仅适用于 WebApplication1 而不适用于 WebApplication2,即使用户具有相同的 ID 并且 DpapiDataProtectionProvider
和 DataProtectorTokenProvider
的创建完全相同。
[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);
}
背景是我们目前的基础设施使用两个网络应用程序。一个 Web 应用程序管理用户,而在另一个 Web 应用程序中,用户可以登录并重置他们的密码。从管理区域,我们需要能够启动密码重置,最好不要在其他域上调用 API 操作。
由于 DpapiDataProtectionProvider
的名称和 DataProtectorTokenProvider.Create
的用途都需要匹配才能使生成的密码重置令牌起作用,这已被证明是一个问题。我们不想在客户端域上使用 Owin,因此在管理 Web 应用程序上创建一个符合这些条件的新 DpapiDataProtectionProvider
和 DataProtectorTokenProvider
。
我们通过使用相同的 UserTokenProvider
创建相同的 ApplicationUserManager
使其工作,但我们想在客户端使用 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"));
}
但是我找不到 IDataProtectionProvider
类型的 DataProtectionProvider
名称的设置位置。该接口只有一个方法,那就是 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);
}
更新:
根据 https://github.com/aspnet/Identity/blob/master/src/Identity/DataProtectionTokenProvider.cs 给定代码 Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider")
DataProtectorTokenProvider
如果创建了一个令牌,它需要被同一个 应用程序池 使用!当代码在不同的应用程序池用户上测试时,代码没有通过,当应用程序池用户相同时,它正常工作。
原文:
我没有找到 Owin 的名字,但我测试了我的安全问题。使用以下方法创建了两个 Web 应用程序。在 WebApplication1 中创建用户时,我也从为 WebApplication2 创建的用户复制了该值中的用户 ID,因此它们对方法 manager.GeneratePasswordResetToken(identityUser.Id)
具有相同的 guid ID。测试时,令牌仅适用于 WebApplication1 而不适用于 WebApplication2,即使用户具有相同的 ID 并且 DpapiDataProtectionProvider
和 DataProtectorTokenProvider
的创建完全相同。
[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);
}