ASP.Net удостоверение 2 с Windows службы и MVC, токены проблемы - PullRequest
0 голосов
/ 11 ноября 2019

У меня есть служба Windows, приложение MVC и веб-приложение Webforms в одном решении. С Webforms я пытаюсь отправить пароль подтверждения электронной почты пользователю. Приложение Webforms отправляет сообщение через MSMQ в службу Windows (потребители сообщений). Служба Windows затем создает пользователя, его токен подтверждения и отправляет электронное письмо.

Пользователь, нажимая на ссылку, затем подтверждает свое электронное письмо в приложении MVC. Все это прекрасно работает на моей машине для разработки.

Всякий раз, когда я внедряюсь в производство, у меня появляются проблемы с некорректными токенами.

Некоторые соответствующие коды в моей настройке:

В службе Windows:

Конфигурация Autofac

builder.Register(c => new UserManager<User, long>(new UserStore(new DbEntities()))).InstancePerLifetimeScope();

Внутри метода, который создает токен и электронную почту

Конструктор

    private readonly UserManager<User, long> _usermanager;
    private readonly IUnitOfWork _uow;
    public ConfiguratorUserService(IUnitOfWork uow)
    {
        _uow = uow;
        _usermanager = new UserManager<User, long>(new UserStore((DeronEntities)_uow.Context));
        var provider = new DpapiDataProtectionProvider("DeronConfigurator");
        _usermanager.UserTokenProvider = new DataProtectorTokenProvider<User, long>(provider.Create("Passwords"));
    }

Метод

 var user = new User
 {
     ... more props setting
     UserName = contact.Emailadres,
 };
 _usermanager.Create(user);
 var provider = new DpapiDataProtectionProvider("Configurator");
 _usermanager.UserTokenProvider = new DataProtectorTokenProvider<User, long>(provider.Create("Passwords"));
 var token = _usermanager.GenerateEmailConfirmationToken(user.Id);
 var data = Encoding.UTF8.GetBytes(token);
 var base64EncodedToken = System.Convert.ToBase64String(data);
 // And sending the e-mail here

Тогда на стороне MVC у меня есть

Autofac

builder.Register(c => new UserManager<User, long>(new UserStore(new DeronEntities()))).InstancePerLifetimeScope();

Authнастройка (запуск)

var provider = new DpapiDataProtectionProvider("Configurator");

app.CreatePerOwinContext(() => new UserManager(new UserStore(new DeronEntities()))
{
     UserTokenProvider = new DataProtectorTokenProvider<User, long>(provider.Create("Passwords"))
});

AccountController

var data = Convert.FromBase64String(code);
var base64Decoded = Encoding.UTF8.GetString(data);

var result = await UserManager.ConfirmEmailAsync(userId, base64Decoded);

Что я попробовал и обнаружил ":

  • Работает нормально на локальном хосте (среда разработки)
  • Я попробовал много предложений от So и других ресурсов, перечисленных ниже
  • Сам токен в порядке, когда я вхожу в систему. Windows Service и AccountController. Они совпадают при их регистрации
  • Я проверил именование DataProtectionProvider AppName и Purposes
  • Я Base 64токены кодирования, поэтому здесь нет проблем с кодировкой URL и т. д., как указывалось во многих ответах SO
  • Единственное истинное отличие, которое я сейчас вижу, состоит в том, что производство работает по SSL, а localhost не
  • В производственной среде есть все приложения на одном компьютере, нет настройки балансировки нагрузки или тому подобное

Пробные решения: http://www.gunaatita.com/blog/Invalid-Token-Error-on-Email-Confirmation-in-Aspnet-Identity/1056

MachineKeyDataProtector - недействительная ссылка при отправке электронного письма с подтверждениемчерез фоновое задание

Я не уверен, как настроить использование ключа компьютера для службы Windows

1 Ответ

0 голосов
/ 11 ноября 2019

Я решил проблему. Именно с помощью настройки ключа машины.

Соответствующие сообщения, которые помогли мне решить эту проблему:

MachineKeyDataProtector - недействительная ссылка, когда электронное письмо с подтверждением отправляется через фоновое задание

Создание маркера сброса пароля не работает на веб-сайте Azure

Итак, моя установка теперь выглядит следующим образом:

В службе Windows

Конфигурация Autofac:

builder.Register<IUserTokenProvider<User, long>>(c => DataProtector.TokenProvider).InstancePerLifetimeScope();

builder.RegisterType<UserManager<User, long>>()
                .As<UserManager<User, long>>().InstancePerLifetimeScope(); 

И в конструкторе:

    private readonly IUnitOfWork _uow;
    private readonly UserManager<User, long> _usermanager;

    public ConfiguratorUserService(UserManager<User, long> userManager, IUnitOfWork uow)
    {
        _uow = uow;
        _usermanager = userManager;
    }

В MVC

Autofac

        builder.Register(c => new UserManager<User, long>(new UserStore(new DeronEntities()))).InstancePerLifetimeScope();

        builder.Register<IUserTokenProvider<User, long>>(c => DataProtector.TokenProvider).InstancePerRequest();

Я взял MachineKeyProtectionProvider из связанных сообщений

Добавьте в свой web.config ключ машины:

  <system.web>
      <machineKey decryption="AES" decryptionKey="dec key here" validation="HMACSHA256" validationKey="key here"/>
  </system.web>

И добавьте то же самое в app.config службы вдов

...