У меня есть служба 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