最近我使用Identity Server 3为我的Web API实现了2FA . 如果登录是在本地进行的(使用IUserService),一切都按预期工作 . 现在,我希望能够通过发出部分登录cookie来进行此登录 . 这意味着我有一个API方法(POST),可以让用户在不进入主页面的情况下进行部分登录 . 要发出身份验证cookie,这就是我所做的(基于IS3扩展方法):

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

在此之后,我将用户重定向回登录页面,并完全登录到绕过2FA步骤的应用程序 . 我正在跳跃,这将使用户部分登录,但它完全登录用户 .

Note: 我实现Two Factor的方式基于IUserService的AuthenticateLocalAsync方法 . 在这里,我更新AuthenticateResult以使用带有重定向路径的构造函数 . API方法不会调用IUserService . 它简单地发布了登录cookie .

Edit: 因此,在检查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);
}

你有没有尝试过这样的事情,或者甚至可能做到这一点?