Otentikasi jendela Blazor dengan klaim khusus

pemrograman


Hai semuanya,

saya tidak tahu apakah saya melakukannya sepenuhnya salah tetapi apa yang ingin saya capai adalah Menghosting Aplikasi Server Blazor di IIS saya dengan Otentikasi Windows dan customClaim tambahan untuk mencegah semua orang mengakses, tetapi hanya segelintir orang.

Sejauh ini saya telah menemukan kode yang ditempel di bawah ini, dan masalahnya, ini berfungsi dengan studio visual saya saat melakukan debug. Semuanya baik-baik saja di sana dan melakukan Pekerjaan seperti yang diharapkan, tetapi segera setelah saya mempublikasikannya ke Server IIS, itu membatasi akses saya.

Jika ada yang bisa membimbing saya ke arah yang benar, saya akan sangat senang.

Terima kasih sebelumnya!

Apa yang saya coba:

Kode untuk Mengotorisasi Pengguna (program.cs)

using System.Security.Claims;
using System.Security.Principal;
using ImsServerMonitor.Data;
using Microsoft.AspNetCore.Authentication.Negotiate;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate(options =>
    {
        options.Events = new NegotiateEvents
        {
            OnAuthenticated = context =>
            {
                if (context.Principal.Identity is WindowsIdentity windowsIdentity)
                {
                    string loginName = windowsIdentity.Name;
                    
                    if (loginName.Contains("User1")
                        || loginName.Contains("User2")
                        || loginName.Contains("User3")
                        || loginName.Contains("User4"))
                    {
                        var claims = new List<Claim>
                        {
                            new Claim("CustomClaim", "Admin")
                        };

                        context.Principal.AddIdentity(new ClaimsIdentity(claims));
                    }
                }

                return Task.CompletedTask;
            }
        };
    });
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policyBuilder => policyBuilder.RequireClaim("CustomClaim", "Admin"));
    // By default, all incoming requests will be authorized according to the default policy.
    //options.FallbackPolicy = options.DefaultPolicy;
    options.FallbackPolicy = options.GetPolicy("AdminOnly");
});

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<MonitorEngine>();
builder.Services.AddDevExpressBlazor();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // 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.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

Selain itu di kantor IIS saya mengaktifkan WindowsAuth untuk situs ini dan memverifikasi bahwa Penyedia Negosiasi ada di daftar teratas.

Tapi saya benar-benar tidak mengerti apa masalahnya, bahkan ChatGpt mengecewakan saya… atau saya gagal mengajukan pertanyaan yang tepat.

Solusi 2

Terima kasih atas pertanyaan dan solusi ini. Bekerja dengan baik. Di .NET 8 saya harus mengubah kode di bawah ini

var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);

ke

Context.User.AddIdentity(appIdentity);
var ticket = new AuthenticationTicket(Context.User, Scheme.Name);

Jika tidak, Anda tidak dapat mengakses Nama Pengguna di tempat lain dalam kode.
Dalam kode di bawah ini _authMessage mengembalikan null jika kita menggunakan kode asli.

@code {
[CascadingParameter]
private Task<AuthenticationState>? AuthenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (AuthenticationState is not null)
        {
            var authState = await AuthenticationState;
            var user = authState.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                _authMessage = user.Identity.Name;
            }
        }
    }

Solusi 1

Apa yang sebenarnya perlu dilakukan… setelah penelitian yang beruntung dan periksa debug Anda tiga kali:

program.cs perlu menunjuk ke pengautentikasi khusus dengan skema khusus->

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = "CustomWindowsAuthentication";
}).AddScheme<CustomWindowsAuthenticationOptions, CustomWindowsAuthenticationHandler>("CustomWindowsAuthentication", null);

Maka Anda memang memerlukan kelas tambahan yang menangani hal itu:

public class CustomWindowsAuthenticationHandler : AuthenticationHandler<CustomWindowsAuthenticationOptions>
    {
        public CustomWindowsAuthenticationHandler(
            IOptionsMonitor<CustomWindowsAuthenticationOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock)
            : base(options, logger, encoder, clock)
        {
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Context.User.Identity.IsAuthenticated || !(Context.User.Identity is WindowsIdentity windowsIdentity))
            {
                return AuthenticateResult.NoResult();
            }

            var loginName = windowsIdentity.Name;
            if (loginName.Contains("User1")
                || loginName.Contains("User2")
                || loginName.Contains("User3")
                || loginName.Contains("User4"))
            {
                var claims = new List<Claim>
                {
                    new Claim("CustomClaim", "Admin")
                };

                var identity = new ClaimsIdentity(claims, Scheme.Name);
                var principal = new ClaimsPrincipal(identity);

                var ticket = new AuthenticationTicket(principal, Scheme.Name);
                return AuthenticateResult.Success(ticket);
            }

            return AuthenticateResult.Fail("Custom authentication failed.");
        }
    }

Dan demi kelengkapan, “CustomWindowsAuthenticationOptions” karena Anda juga memerlukannya, meskipun kosong karena saya tidak memerlukan opsi super khusus.

public class CustomWindowsAuthenticationOptions : AuthenticationSchemeOptions
    {
        
    }

コメント

タイトルとURLをコピーしました