adminsystem/adminSystem.UI/Components/Account/Pages/Manage/ExternalLogins.razor

141 lines
5.1 KiB
Plaintext
Raw Normal View History

2024-05-28 15:52:02 +08:00
@page "/Account/Manage/ExternalLogins"
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity
@using adminSystem.UI.Data
@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject IdentityUserAccessor UserAccessor
@inject IUserStore<ApplicationUser> UserStore
@inject IdentityRedirectManager RedirectManager
<PageTitle>Manage your external logins</PageTitle>
<StatusMessage />
@if (currentLogins?.Count > 0)
{
<h3>Registered Logins</h3>
<table class="table">
<tbody>
@foreach (var login in currentLogins)
{
<tr>
<td>@login.ProviderDisplayName</td>
<td>
@if (showRemoveButton)
{
<form @formname="@($"remove-login-{login.LoginProvider}")" @onsubmit="OnSubmitAsync" method="post">
<AntiforgeryToken />
<div>
<input type="hidden" name="@nameof(LoginProvider)" value="@login.LoginProvider" />
<input type="hidden" name="@nameof(ProviderKey)" value="@login.ProviderKey" />
<button type="submit" class="btn btn-primary" title="Remove this @login.ProviderDisplayName login from your account">Remove</button>
</div>
</form>
}
else
{
@: &nbsp;
}
</td>
</tr>
}
</tbody>
</table>
}
@if (otherLogins?.Count > 0)
{
<h4>Add another service to log in.</h4>
<hr />
<form class="form-horizontal" action="Account/Manage/LinkExternalLogin" method="post">
<AntiforgeryToken />
<div>
<p>
@foreach (var provider in otherLogins)
{
<button type="submit" class="btn btn-primary" name="Provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">
@provider.DisplayName
</button>
}
</p>
</div>
</form>
}
@code {
public const string LinkLoginCallbackAction = "LinkLoginCallback";
private ApplicationUser user = default!;
private IList<UserLoginInfo>? currentLogins;
private IList<AuthenticationScheme>? otherLogins;
private bool showRemoveButton;
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
[SupplyParameterFromForm]
private string? LoginProvider { get; set; }
[SupplyParameterFromForm]
private string? ProviderKey { get; set; }
[SupplyParameterFromQuery]
private string? Action { get; set; }
protected override async Task OnInitializedAsync()
{
user = await UserAccessor.GetRequiredUserAsync(HttpContext);
currentLogins = await UserManager.GetLoginsAsync(user);
otherLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync())
.Where(auth => currentLogins.All(ul => auth.Name != ul.LoginProvider))
.ToList();
string? passwordHash = null;
if (UserStore is IUserPasswordStore<ApplicationUser> userPasswordStore)
{
passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
}
showRemoveButton = passwordHash is not null || currentLogins.Count > 1;
if (HttpMethods.IsGet(HttpContext.Request.Method) && Action == LinkLoginCallbackAction)
{
await OnGetLinkLoginCallbackAsync();
}
}
private async Task OnSubmitAsync()
{
var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!);
if (!result.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", HttpContext);
}
await SignInManager.RefreshSignInAsync(user);
RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", HttpContext);
}
private async Task OnGetLinkLoginCallbackAsync()
{
var userId = await UserManager.GetUserIdAsync(user);
var info = await SignInManager.GetExternalLoginInfoAsync(userId);
if (info is null)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext);
}
var result = await UserManager.AddLoginAsync(user, info);
if (!result.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", HttpContext);
}
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", HttpContext);
}
}