Создание частичного cookie для входа в систему для внешней аутентификации - PullRequest
0 голосов
/ 28 мая 2018

Недавно я реализовал 2FA для своего веб-API с использованием Identity Server 3. Все работает, как и ожидалось, если вход выполняется локально (с использованием IUserService).Теперь я хочу иметь возможность войти в систему, выполнив частичный файл cookie для входа.Это означает, что у меня есть метод API (POST), который позволяет пользователям частично входить в систему, не заходя на главную страницу.Для выдачи куки аутентификации это то, что я делаю (на основе метода IS3 Extensions):

_owinContext.Environment.IssueLoginCookie(new AuthenticatedLogin
{
      IdentityProvider = Constants.ExternalAuthenticationType,
      Subject = userId,
      Name = identityId,
      Claims = new[] { new Claim(ClaimTypes.NameIdentifier, identityId) },
      AuthenticationMethod = Constants.AuthenticationMethods.TwoFactorAuthentication
});

После этого я перенаправляю пользователя обратно на страницу входа, и он полностью входит в приложение, минуя шаг 2FA.,Я прыгал, что это заставило бы пользователя частично войти в систему, но вместо этого он полностью вошел в систему пользователя.

Примечание: Способ, которым я реализовал Two Factor, основан на AuthenticateLocalAsync метод из IUserService.Здесь я обновляю AuthenticateResult , чтобы использовать конструктор с путем перенаправления.Метод API не вызывает IUserService.Он просто выдает файл cookie для входа в систему.

Редактировать: Так что после проверки внутренней реализации IdentityServer3 я теперь могу заставить пользователя пройти через экраны 2FA.Проблема теперь в том, что при частичном входе в систему успешно (коды проверки подлинности совпадают) я перенаправляю пользователя на URL-адрес резюме, и это приводит к появлению страницы с ошибкой 500 (исключение не выдается или журналы не отображаются).Если это происходит при обычном входе в систему, все работает.

Обработка пользовательского запроса на вход в систему:

var messageId = clientIdentifier;

var claims = new List<Claim>();
(...)

var authenticationContext = new ExternalAuthenticationContext
{
    ExternalIdentity = new ExternalIdentity() { Provider = "API", Claims = claims },
};

await _userService.AuthenticateExternalAsync(authenticationContext);
var authResult = authenticationContext.AuthenticateResult;

var ctx = new PostAuthenticationContext
{
    AuthenticateResult = authResult
};

var id = authResult.User.Identities.FirstOrDefault();
var props = new AuthenticationProperties();
var resumeId = CryptoRandom.CreateUniqueId();

var resumeLoginUrl = _owinContext.GetPartialLoginResumeUrl(resumeId);
var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
id.AddClaim(resumeLoginClaim);
id.AddClaim(new Claim(GetClaimTypeForResumeId(resumeId), messageId));

// add url to start login process over again (which re-triggers preauthenticate)
var restartUrl = _owinContext.GetPartialLoginRestartUrl(messageId);
id.AddClaim(new Claim(Constants.ClaimTypes.PartialLoginRestartUrl, restartUrl));

_owinContext.Authentication.SignIn(props, id);

// Sends the user to the 2FA pages (where he needs to insert the validation code).
// At this point the user is successfuly partially logged in.
var redirectUrl = GetRedirectUrl(authResult);
return Redirect(redirectUrl);

После вставки кода 2FA пользователь должен войти в систему после ввода URL-адреса резюме.:

if (isAuthCodeValid)
{
    var resumeUrl = await owinContext.Environment.GetPartialLoginResumeUrlAsync();

    // Redirects the user to resume url. This is not working if authentication is done by API but is works with normal local authentication.
   // With API it redirects to a page which eventually will have 500 error (no logs or exceptions being shown)
    return Redirect(resumeUrl);
}

Ребята, вы когда-нибудь пытались сделать что-то подобное или это вообще возможно?

...