Аутентификация сервера Blazor без использования удостоверения с использованием HttpContext.SignInAsyncC#

Место общения программистов C#
Ответить
Anonymous
 Аутентификация сервера Blazor без использования удостоверения с использованием HttpContext.SignInAsync

Сообщение Anonymous »

Я пытался заставить работать аутентификацию для серверного приложения Blazor с помощью моей собственной проверки личности (я не хочу использовать SqlServer или этот механизм). Кажется, все в порядке, если принять, что HttpContext всегда имеет значение null. Я видел много-много предложений о том, как преодолеть эту проблему, но ни одно из них не сработало:
Аутентификация приложений сервера Blazor без Identity Server
Все остальное, кажется, работает. за исключением того, что я не могу войти в учетную запись, которую создаю (а также выйти из системы). Я пытался удалить интерактивный рендеринг, но безрезультатно.
Вот код Login.razor:

Код: Выделить всё

@page "/login"
@rendermode @(new InteractiveServerRenderMode(false))
@inject LoginApiClient LoginApi
@inject UserApiClient UserApi
@inject NavigationManager navigationManager
@inject IHttpContextAccessor httpContextAccessor
@using MayApp.Web.APIClients;
@using MayApp.Web.Models
@using Blazorise.Components
@using System.Text.RegularExpressions;
@using System.Security.Claims
@using Microsoft.AspNetCore.Authentication.Cookies
@using Microsoft.AspNetCore.Authentication;
@using Microsoft.AspNetCore.Http

Login - My App
Login



User Name



Please provide an User Name




@if (@error)
{

@errorMessage

}

Password



Invalid password.  Passwords must be between 8 and 30 characters long, one number, one lower and one upper case letter, and one special character.





Login




@code {
[CascadingParameter]
public HttpContext httpcontext { get; set; } = default!;

private MyApp.Web.Models.Login login = new();
const string passwordPattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,30}$";
string errorMessage = string.Empty;
bool error = false;

Validations ValidationsRef { get; set; }

void ValidatePassword(ValidatorEventArgs e)
{
bool isMatch = Regex.IsMatch(Convert.ToString(e.Value), passwordPattern);
e.Status = isMatch ? ValidationStatus.Success : ValidationStatus.Error;
}

async void Authenticate()
{
var result = await MyApp.Login(login);
if (result.Success)
{
if (result.PasswordResetNeeded)
{
// Provide a link to reset password.
error = true;
errorMessage = result.Message;
await InvokeAsync(StateHasChanged);
}
else if (result.Users != null && result.Users.Count > 0)
{
User user = result.Users[0];
if (!string.IsNullOrEmpty(user.UserName) && !string.IsNullOrEmpty(user.Role))
{
errorMessage = string.Empty;
error = false;
var claims = new List
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.Role, user.Role)
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
await httpcontext.SignInAsync(principal);
navigationManager.NavigateTo("/"); // Should be home

}
else
{
error = true;
errorMessage = "Invalid UserName or Password.";
await InvokeAsync(StateHasChanged);
}
}
else
{
error = true;
errorMessage = "Invalid UserName or Password.";
await InvokeAsync(StateHasChanged);
}
}
else
{
error = true;
errorMessage = "Invalid UserName or Password.";
await InvokeAsync(StateHasChanged);
}

}

protected override void OnInitialized()
{
}

}
Ошибка всегда связана с тем, что контекст в этой строке имеет значение null:

Код: Выделить всё

   await httpcontext.SignInAsync(principal);
Мой файл program.cs выглядит так:

Код: Выделить всё

using Blazored.Toast;
using Blazorise;
using Blazorise.Bootstrap5;
using Blazorise.Icons.FontAwesome;
using CollectXScore.Web.APIClients;
using CollectXScore.Web.Components;
using CollectXScore.Web.Utilities;
using Microsoft.AspNetCore.Authentication.Cookies;

// This is a Blazor Server Application (NOT a Webassembly App)
var builder = WebApplication.CreateBuilder(args);

// Add service defaults & Aspire components.
builder.AddServiceDefaults();

// Add services to the container.
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
builder.Services.AddOutputCache();
builder.Services.AddBlazoredToast();
// Authentication and Authorization services
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).
AddCookie(options =>
{
options.Cookie.Name = "auth_cookie";
options.LoginPath = "/login";
options.Cookie.MaxAge = TimeSpan.FromMinutes(90);
options.AccessDeniedPath = "/accessdenied";
});
builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();

builder.Services
.AddBlazorise(options =>
{
options.Immediate = true;
})
.AddBootstrap5Providers()
.AddFontAwesomeIcons();
builder.Services.ConfigureApplicationCookie(ops =>
{
ops.ExpireTimeSpan = TimeSpan.FromMinutes(30);
ops.SlidingExpiration = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseAuthentication();
app.UseAuthorization();
app.UseOutputCache();
app.MapDefaultEndpoints();
app.Run();
Есть ли способ сохранить HttpContext при запуске, а затем ссылаться на него или в другое место кода? Или какой-то механизм не задокументирован?

Подробнее здесь: https://stackoverflow.com/questions/791 ... signinasyn
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»