回购这里 –
RemoteAuthenticationHandler
我有一个准备在其基础上进行构建的基本框架,但我无法弄清楚究竟HandleRemoteAuthenticateAsync
应该怎么做才能使其工作。
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;
namespace BlazorAuthExample;
public class MyAuthOptions : RemoteAuthenticationOptions
{
public MyAuthOptions()
{
CallbackPath = new PathString("/signin-myauth");
}
}
public class MyAuthHandler : RemoteAuthenticationHandler<MyAuthOptions>
{
public MyAuthHandler(
IOptionsMonitor<MyAuthOptions> options,
ILoggerFactory logger,
UrlEncoder encoder) : base(options, logger, encoder)
{
}
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/my-sign-in-page");
return Task.CompletedTask;
}
protected override Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
{
var nameIdentifierClaim = new Claim(ClaimTypes.NameIdentifier, "mrpmorris@gmail.com", ClaimTypes.NameIdentifier, "myauth", "myauth");
var identity = new ClaimsIdentity([nameIdentifierClaim], "myauth");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "myauth");
return Task.FromResult(HandleRequestResult.Success(ticket));
}
}
- 创建一个新的 Blazor Web 应用程序,并指定“个人账户”作为身份验证类型。
- 添加上述类
- 在
Program.cs
查找
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
并将其更改为
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddRemoteScheme<MyAuthOptions, MyAuthHandler>("myauth", "My auth", null)
.AddIdentityCookies();
MySignInPage.razor
创建包含以下内容的文件
@page "/my-sign-in-page"
<form action="/signin-myauth" method="post">
<button type="submit">Click here to sign in</button>
</form>
- 运行应用
- 点击
Register
左侧导航菜单中的项目 - 在“使用其他服务注册”下点击
My auth
- 点击“单击此处登录”按钮
我现在期望看到与登录 Google 等时相同的行为,但似乎什么都没有发生。
最佳答案
1
您未RedirectUri
在您的处理程序中进行处理。
将这两行添加到您的HandleRemoteAuthenticateAsync
方法中。
// hardcoded for sake of simplicity
ticket.Properties.RedirectUri = "/Account/ExternalLogin?ReturnUrl=&Action=LoginCallback";
ticket.Properties.Items.Add("LoginProvider", "myauth");
理想情况下,您必须将 RedirectUri 从质询方法 ( properties.RedirectUri
) 传递到您的登录页面,然后再传递到您的处理方法。
更新:
以下是支持正确处理的示例实现RedirectUri
。请勿在生产中使用它。
public class MyAuthHandler : RemoteAuthenticationHandler<MyAuthOptions>
{
public MyAuthHandler(
IOptionsMonitor<MyAuthOptions> options,
ILoggerFactory logger,
UrlEncoder encoder) : base(options, logger, encoder)
{
}
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
var url = "/my-sign-in-page?RedirectUri=" + Uri.EscapeDataString(properties.RedirectUri ?? "");
if (properties.Items.TryGetValue("XsrfId", out var xsrfId))
{
url += "&xsrfId=" + xsrfId;
}
Context.Response.Redirect(url);
return Task.CompletedTask;
}
protected override Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
{
var nameIdentifierClaim = new Claim(ClaimTypes.NameIdentifier, "mrpmorris@gmail.com", ClaimTypes.NameIdentifier, "myauth", "myauth");
var identity = new ClaimsIdentity([nameIdentifierClaim], "myauth");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "myauth");
ticket.Properties.RedirectUri = Context.Request.Form["RedirectUri"];
ticket.Properties.Items.Add("LoginProvider", "myauth");
if (Context.Request.Form.TryGetValue("XsrfId", out var xsrfId))
{
ticket.Properties.Items.Add("XsrfId", xsrfId);
}
return Task.FromResult(HandleRequestResult.Success(ticket));
}
}
@page "/my-sign-in-page"
<form action="/signin-myauth" method="post">
<input type="hidden" name="RedirectUri" value="@RedirectUri"/>
<input type="hidden" name="XsrfId" value="@XsrfId"/>
<button type="submit">Click here to sign in</button>
</form>
@code {
[SupplyParameterFromQuery]
private string? RedirectUri { get; set; }
[SupplyParameterFromQuery]
private string? XsrfId { get; set; }
}
3
-
谢谢,Mike!看起来这已经是解决方案的 99%,但似乎还缺少一些东西。我添加了 Google 和 LinkedIn,然后在 Google 上创建了一个新帐户。然后我可以转到 /Account/Manage/ExternalLogins 并添加 LinkedIn,它会将其与登录帐户关联。但当我单击“我的身份验证”时,它会尝试创建一个新帐户 – 您知道缺少什么吗?
– -
@PeterMorris,这是因为我
RedirectUri
对寄存器进行了硬编码。要使其完全发挥作用,您必须RedirectUri
正确处理。
–
-
@PeterMorris,我更新了我的答案以展示完整流程的示例
RedirectUri
。
–
|
|