Справочная информация заключается в том, что наша текущая инфраструктура использует два веб-приложения.Одно веб-приложение администрирует пользователей, а другие могут входить в систему и сбрасывать свои пароли.Из области администрирования мы должны иметь возможность инициировать сброс пароля, желательно без вызова действия API в другом домене.
Поскольку и имя для DpapiDataProtectionProvider
, и назначение для DataProtectorTokenProvider.Create
должны совпадать, чтобы сгенерированный токен сброса пароля работал, это оказалось проблемой.Мы не хотим использовать Owin в клиентском домене и поэтому создаем новые DpapiDataProtectionProvider
и DataProtectorTokenProvider
, которые соответствуют этим критериям, в веб-приложении администрирования.
Мы заработали, создав тот же 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);
}