angular - 静默登录身份服务器 4 出现不适当的错误响应问题
问题描述
我正在尝试在 oidc-client 中实现静默登录以与 Angular 9 一起使用,并希望用户在电子邮件验证后在 ASP.NET Core 应用程序中注册后自动登录。
除了最后一步,我已经完成了所有工作,即得到实际错误作为响应,以便根据可能的错误为客户端显示适当的消息。有两个可能的错误需要处理:
1) 短信一次码不正确;
2) 一个时间码过期。
这就是为什么我必须在服务器端传递准确的代码描述,然后在客户端处理它。
客户端代码:
export function getClientSettings(identityBaseUrl: string): UserManagerSettings {
const baseUrl = window.location.origin;
return {
authority: identityBaseUrl,
client_id: 'test.admin.spa',
redirect_uri: `${baseUrl}/auth-callback`,
post_logout_redirect_uri: baseUrl,
response_type: 'id_token token',
scope: 'openid profile test.admin.api',
filterProtocolClaims: true,
loadUserInfo: true,
userStore: new WebStorageStateStore({ store: window.localStorage }),
automaticSilentRenew: true,
silent_redirect_uri: `${baseUrl}/silent-refresh.html`,
};
}
这是我在自定义 AuthorizeInteractionResponseGenerator 中覆盖 ProcessInteractionAsync 方法的方式:
public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
var processOtcRequest = !_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
var acrValues = request.GetAcrValues().ToList();
if (acrValues.Any() == false)
{
processOtcRequest = false;
}
var userEmailAcr = acrValues.FirstOrDefault(x => x.StartsWith("user_email"));
var oneTimeCodeAcr = acrValues.FirstOrDefault(x => x.StartsWith("one_time_code"));
if (userEmailAcr != null && oneTimeCodeAcr != null && processOtcRequest)
{
var userEmail = userEmailAcr.Split(':').Last();
var oneTimeCode = oneTimeCodeAcr.Split(':').Last();
var currDate = DateTime.UtcNow;
var user = await _users.GetUserByEmailAsync(userEmail);
if (user != null)
{
// 1) texted one time code is not correct
if (user.OneTimeCode != oneTimeCode)
{
return GetErrorResponse("invalid_code");
}
// 2) one time code is expired
if (user.OneTimeCodeExpiredAt < currDate)
{
return GetErrorResponse("expired_code");
}
user.EmailConfirmed = true;
user.OneTimeCode = null;
user.OneTimeCodeExpiredAt = null;
user.SecurityStamp = Guid.NewGuid().ToString().ToUpper();
user.ConcurrencyStamp = Guid.NewGuid().ToString().ToUpper();
user.NormalizedEmail = user.Email.ToUpper();
user.NormalizedUserName = user.UserName.ToUpper();
if (request != null)
{
request.Subject = new ClaimsPrincipal({{building my principal}});
}
await _users.UpdateAsync(user);
await _users.CommitAsync();
var props = new AuthenticationProperties
{
ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2),
AllowRefresh = true,
RedirectUri = request.RedirectUri
};
await _loginService.SignInAsync(user, props);
return new InteractionResponse
{
IsLogin = false,
IsConsent = false
};
}
}
return await base.ProcessInteractionAsync(request, consent);
}
private InteractionResponse GetErrorResponse(string errorCode)
{
return new InteractionResponse
{
Error = errorCode
};
}
因此,它看起来很合乎逻辑,但是当我发短信一次代码不正确并尝试在客户端处理错误时:
sendRequest(postModel: RegisterCompanyConfirbut mationViewModel) {
this.authService.startSilentAuthentication(this.userEmail, this.form.value.oneTimeCode).then(
(result) => {
this.router.navigate(['', 'company-details']);
},
(error) => {
console.log(error);
}
);
}
我在错误部分观察到这样奇怪的事情:
另一方面,当我查看网络部分并单击此记录时
我看到我的错误代码仍然被发送:
我看到这样的简单返回错误
return new InteractionResponse
{
Error = errorCode
};
没有给我带来我预期的错误(它只给我带来了“框架窗口超时”)。
目的是在客户端部分中使用一个时间码检索有关错误的信息:
(error) => {
console.log(error);
}
也许有人遇到过这样的问题?任何指点都将不胜感激 - 这个简单的问题让我大吃一惊..提前致谢!
解决方案
推荐阅读
- c# - 如何更改动态 DataGrid(绑定到 DataTable)中的单元格模板?
- oracle - 为什么我在使用 PL/SQL 的 Oauth 2 访问令牌代码中出现此错误?
- python - 在 Selenium 中使用 .getAttribute 获取文本数据
- javascript - 文本节点不能作为 [ReactJS] 的子节点出现
为什么我会收到此警告?
Warning: validateDOMNesting(...): Text nodes cannot appear as a child of <table>
.在某些情况下,我看到它是关于一些空白的,但我不明白这在这里是如何应用的。
我的代码:
return (
- tomcat - Tomcat 使用 FormAuthentication 而不是 KeyCloak Tomcat Valve SAML 身份验证
- azure - Azure 虚拟磁盘与 Azure vhdx 驱动器
- sql - 如何在 Oracle 外部表中包含逗号
- c# - 健康检查、ASP.NET Web API
- postgresql - 如何使用 txn 表在 post gresql 中进行每日滚动余额
- android - Google App 脚本错误:“脚本已完成,但未返回任何内容。”