Asp.Net Identity имя по умолчанию для DpapiDataProtectionProvider для Оуэна - PullRequest
0 голосов
/ 20 сентября 2018

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

1 Ответ

0 голосов
/ 21 сентября 2018

Обновление:

Согласно https://github.com/aspnet/Identity/blob/master/src/Identity/DataProtectionTokenProvider.cs это должно быть DataProtectorTokenProvider с кодом Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider")

Если токен создан, он нуждается вбыть использованным тем же Application Pool !Когда код тестировался на разных пользователях пула приложений, код не проходил, когда пользователь пула приложений был таким же, он работал нормально.

Оригинал:

Я не нашел имени Овина, но проверил имеющуюся проблему безопасности.Создал два веб-приложения с помощью методов ниже.Когда пользователь был создан в WebApplication1, я также скопировал идентификатор пользователя из этого значения, созданного пользователем для WebApplication2, чтобы у них был тот же идентификатор идентификатора guid для метода manager.GeneratePasswordResetToken(identityUser.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);
}
...