最近我使用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);
}
你有没有尝试过这样的事情,或者甚至可能做到这一点?