Господа, пытаюсь сделать получение JWT токена на аккаунте с включенным Two-factor authentication (2fa). Как я это сделал:
signInManager.PasswordSignInAsync
, который выдает нам SignInResult
.SignInResult
:
Succeeded
- генерируем токен.RequiresTwoFactor
- проверяем наличие ключа в запросе, если он есть - пробуем авторизоваться, нет - ошибка.Действия при RequiresTwoFactor
:
signInManager.GetTwoFactorAuthenticationUserAsync();
signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, false, false)
, который также дает нам статус.Succeeded
, то генерируем токен и отдаем.Сам код пока имеет такой набросок:
[HttpPost("[action]/{key?}")]
public async Task<ActionResult> Auth([FromBody] TokenRequest tokenRequest, string key)
{
if (tokenRequest == null)
return StatusCode(400, "Request cannot be null!");
var username = tokenRequest.UserName;
var password = tokenRequest.Password;
var result = await signInManager.PasswordSignInAsync(username, password, false, lockoutOnFailure: true);
if (result.Succeeded)
{
var user = await userManager.FindByNameAsync(username);
if (user != null)
{
var principal = await signInManager.CreateUserPrincipalAsync(user);
var token = GenerateToken(principal);
var response = new
{
token,
principal.Identity.Name
};
return Json(response);
}
}
if (result.IsLockedOut)
{
return StatusCode(423, "Account locked out!");
}
if (result.RequiresTwoFactor)
{
if (key == null)
return StatusCode(400, "Two-factor authentication `key` needed!");
var user = await signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
return StatusCode(502, "Unable to load two-factor authentication user.");
var authenticatorCode = key.Replace(" ", string.Empty).Replace("-", string.Empty);
var authResult = await signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, false, false);
if (authResult.Succeeded)
{
var principal = await signInManager.CreateUserPrincipalAsync(user);
var token = GenerateToken(principal);
var response = new
{
token,
principal.Identity.Name
};
return Json(response);
}
else if (authResult.IsLockedOut)
{
return StatusCode(423, "Account locked out!");
}
else
{
return StatusCode(400, "Invalid authenticator code.");
}
}
return StatusCode(400, "Login Failed!");
}
Все это вроде как работает, но вот одна загвоздка - тут используются Cookie, а точнее:
Identity.TwoFactorUserId
с неким ключом и дает сообщение "Требуется 2fa код".signInManager.GetTwoFactorAuthenticationUserAsync();
эту куку считываем, а также код присланный вторым запросом и сверяем все это.Вопрос:
Как мне грамотно реализовать авторизацию с 2fa, не используя куки, ведь в API не очень хорошо (да и не очень удобно) использовать куки, или ошибаюсь?
За основу взял этот ответ.
Для чего это:
Делаю сайт на ASP.Net Core 2.1, который будет неким центральным хабом (аккаунт с возможностью управления, магазин, взаимодействие с игровым миром (сервер будет выдавать свое API для этого, сайт здесь будет в роли клиента).
Для этого всего требуется еще реализовать клиентское приложение, которое сейчас разрабатывается на WPF (его задачи: информация об аккаунте, балансе пользователя, информация о персонажах, обновление клиента и др. информация). По сути это клиентское приложение, которое будет выводить информацию, с минимальным набором "изменяемых" API (то есть не будет пополнение счета через него, не будет изменение пароля и др.). Вот в нем требуется узнать пользователя, авторизовать его, получить его информацию и в дальнейшем пустить в игру.
У меня была подобная проблема и решил её следующим способом:
var authenticatorCode =
model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty);
var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync(
user, _userManager.Options.Tokens.AuthenticatorTokenProvider, authenticatorCode
);
Пытаюсь освоить xamarin как было бы грамотнее реализовать расположение компонентов на activity так как на картинкепримечание компоненты генерируются...
У меня есть дата грид и в ресурсах к ней определено контекстное менюОно статичное, но мне нужно динамично добавлять sub MenuItem для одного из айтемов...