Bagikan melalui


Autentikasi dan otorisasi ASP.NET Core Blazor

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Artikel ini menjelaskan dukungan ASP.NET Core untuk konfigurasi dan manajemen keamanan di Blazor aplikasi.

Skenario keamanan berbeda antara kode otorisasi yang menjalankan sisi server dan sisi klien di Blazor aplikasi. Untuk kode otorisasi yang berjalan di server, pemeriksaan otorisasi dapat menerapkan aturan akses untuk area aplikasi dan komponen. Karena eksekusi kode sisi klien dapat dirusak, kode otorisasi yang dijalankan pada klien tidak dapat dipercaya untuk benar-benar menerapkan aturan akses atau mengontrol tampilan konten sisi klien.

Jika penegakan aturan otorisasi harus dijamin, jangan terapkan pemeriksaan otorisasi dalam kode sisi klien. Buat Blazor Aplikasi Web yang hanya bergantung pada penyajian sisi server (SSR) untuk pemeriksaan otorisasi dan penegakan aturan.

Razor Konvensi otorisasi halaman tidak berlaku untuk komponen Razor yang dapat dirutekan. Jika komponen yang tidak dapat Razor dirutekan disematkan di halaman Razor aplikasi Pages, konvensi otorisasi halaman secara tidak langsung memengaruhi Razor komponen bersama dengan konten halaman lainnya.

Jika penegakan aturan otorisasi dan keamanan data dan kode harus dijamin, jangan kembangkan aplikasi sisi klien. Buat Blazor Server aplikasi.

Razor Konvensi otorisasi halaman tidak berlaku untuk komponen Razor yang dapat dirutekan. Jika komponen yang tidak dapat Razor dirutekan disematkan di halaman Razor aplikasi Pages, konvensi otorisasi halaman secara tidak langsung memengaruhi Razor komponen bersama dengan konten halaman lainnya.

ASP.NET Core Identity dirancang untuk bekerja dalam konteks permintaan HTTP dan komunikasi respons, yang umumnya bukan Blazor model komunikasi klien-server aplikasi. Aplikasi ASP.NET Core yang menggunakan ASP.NET Core Identity untuk manajemen pengguna harus menggunakan Halaman Razor, bukan komponen Razor untuk UI terkait Identity, seperti pendaftaran pengguna, masuk, keluar, dan tugas manajemen pengguna lainnya. Komponen bangunan Razor yang menangani Identity tugas secara langsung dimungkinkan untuk beberapa skenario tetapi tidak direkomendasikan atau didukung oleh Microsoft.

Abstraksi ASP.NET Core, seperti SignInManager<TUser> dan UserManager<TUser>, tidak didukung dalam komponen Razor. Untuk informasi selengkapnya tentang menggunakan ASP.NET Core Identity dengan , lihat Scaffold ASP.NET Core Identity ke dalam aplikasi sisi Blazor server.Blazor

Catatan

Contoh kode dalam artikel ini mengadopsi jenis referensi nullable (NRTs) dan .NET compiler null-state static analysis, yang didukung di ASP.NET Core di .NET 6 atau yang lebih baru. Saat menargetkan ASP.NET Core 5.0 atau yang lebih lama, hapus penunjukan jenis null (?) dari contoh dalam artikel ini.

Dukungan antiforgery

Templat Blazor :

Komponen AntiforgeryToken merender token antiforgery sebagai bidang tersembunyi, dan komponen ini secara otomatis ditambahkan ke instans formulir (EditForm). Untuk informasi selengkapnya, lihat ringkasan formulir ASP.NET CoreBlazor.

Layanan ini AntiforgeryStateProvider menyediakan akses ke token antiforgery yang terkait dengan sesi saat ini. Masukkan layanan dan panggil metodenya GetAntiforgeryToken() untuk mendapatkan .AntiforgeryRequestToken Untuk informasi selengkapnya, lihat Memanggil API web dari aplikasi ASP.NET CoreBlazor.

Blazor menyimpan token permintaan dalam status komponen, yang menjamin bahwa token antiforgery tersedia untuk komponen interaktif, bahkan ketika mereka tidak memiliki akses ke permintaan.

Catatan

Mitigasi antiforgery hanya diperlukan saat mengirimkan data formulir ke server yang dikodekan sebagai application/x-www-form-urlencoded, multipart/form-data, atau text/plain karena ini adalah satu-satunya enctype formulir yang valid.

Untuk informasi selengkapnya, lihat sumber daya berikut:

Autentikasi

Blazor menggunakan mekanisme autentikasi ASP.NET Core yang ada untuk menetapkan identitas pengguna. Mekanisme yang tepat tergantung pada bagaimana aplikasi dihosting Blazor , sisi server, atau sisi klien.

Autentikasi sisi server Blazor

Sisi Blazor server yang dirender secara interaktif beroperasi melalui SignalR koneksi dengan klien. Autentikasi di aplikasi berbasis SignalR ditangani saat koneksi dibuat. Autentikasi dapat didasarkan pada cookie atau beberapa token pembawa lainnya, tetapi autentikasi dikelola melalui SignalR hub dan sepenuhnya dalam sirkuit.

Layanan bawaan AuthenticationStateProvider mendapatkan data status autentikasi dari ASP.NET Core HttpContext.User. Ini adalah cara status autentikasi terintegrasi dengan mekanisme autentikasi ASP.NET Core yang ada.

IHttpContextAccessor/HttpContext dalam Razor komponen

IHttpContextAccessor harus dihindari dengan penyajian interaktif karena tidak tersedia yang valid HttpContext .

IHttpContextAccessor dapat digunakan untuk komponen yang dirender secara statis di server. Namun, sebaiknya hindari jika memungkinkan.

HttpContext dapat digunakan sebagai parameter kaskading hanya dalam komponen akar yang dirender secara statis untuk tugas umum, seperti memeriksa dan memodifikasi header atau properti lain dalam App komponen (Components/App.razor). Nilainya selalu null untuk penyajian interaktif.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Untuk skenario di mana HttpContext diperlukan dalam komponen interaktif, sebaiknya mengalirkan data melalui status komponen persisten dari server. Untuk informasi selengkapnya, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

Jangan gunakan IHttpContextAccessor/HttpContext secara langsung atau tidak langsung dalam Razor komponen aplikasi sisi Blazor server. Blazor aplikasi berjalan di luar konteks alur ASP.NET Core. HttpContext tidak dijamin tersedia dalam IHttpContextAccessor, dan HttpContext tidak dijamin untuk menyimpan konteks yang memulai Blazor aplikasi.

Pendekatan yang direkomendasikan untuk meneruskan status permintaan ke Blazor aplikasi adalah melalui parameter komponen akar selama penyajian awal aplikasi. Atau, aplikasi dapat menyalin data ke dalam layanan tercakup dalam peristiwa siklus hidup inisialisasi komponen akar untuk digunakan di seluruh aplikasi. Untuk informasi selengkapnya, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

Aspek penting dari keamanan sisi Blazor server adalah bahwa pengguna yang melekat pada sirkuit tertentu mungkin diperbarui pada beberapa titik setelah Blazor sirkuit dibuat tetapi IHttpContextAccessortidak diperbarui. Untuk informasi selengkapnya tentang mengatasi situasi ini dengan layanan kustom, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

Status bersama

Aplikasi sisi Blazor server berada di memori server, dan beberapa sesi aplikasi dihosting dalam proses yang sama. Untuk setiap sesi aplikasi, Blazor memulai sirkuit dengan cakupan kontainer injeksi dependensinya sendiri, sehingga layanan terlingkup unik per Blazor sesi.

Peringatan

Kami tidak merekomendasikan aplikasi pada status berbagi server yang sama menggunakan layanan singleton kecuali perawatan ekstrem diambil, karena ini dapat memperkenalkan kerentanan keamanan, seperti membocorkan status pengguna di seluruh sirkuit.

Anda dapat menggunakan layanan singleton stateful di Blazor aplikasi jika dirancang khusus untuk itu. Misalnya, penggunaan cache memori singleton dapat diterima karena cache memori memerlukan kunci untuk mengakses entri tertentu. Dengan asumsi pengguna tidak memiliki kontrol atas kunci cache yang digunakan dengan cache, status yang disimpan di cache tidak bocor di seluruh sirkuit.

Untuk panduan umum tentang manajemen status, lihat manajemen status ASP.NET CoreBlazor.

Autentikasi sisi Blazor klien

Di aplikasi sisi Blazor klien, pemeriksaan autentikasi sisi klien dapat dilewati karena semua kode sisi klien dapat dimodifikasi oleh pengguna. Hal yang sama berlaku untuk semua teknologi aplikasi sisi klien, termasuk kerangka kerja JavaScript SPA dan aplikasi asli untuk sistem operasi apa pun.

Tambahkan berikut ini:

Untuk menangani autentikasi, penggunaan layanan bawaan atau kustom AuthenticationStateProvider dibahas di bagian berikut.

Untuk informasi selengkapnya, lihat Mengamankan ASP.NET Core Blazor WebAssembly.

Layanan AuthenticationStateProvider

AuthenticationStateProvider adalah layanan yang mendasari yang digunakan oleh AuthorizeView komponen dan layanan autentikasi berkala untuk mendapatkan status autentikasi bagi pengguna.

AuthenticationStateProvider adalah layanan yang mendasar yang digunakan oleh AuthorizeView komponen dan CascadingAuthenticationState komponen untuk mendapatkan status autentikasi bagi pengguna.

Anda biasanya tidak menggunakan AuthenticationStateProvider secara langsung. Gunakan pendekatan komponen AuthorizeView atau Task<AuthenticationState> yang dijelaskan nanti dalam artikel ini. Kelemahan utama menggunakan AuthenticationStateProvider secara langsung adalah komponen tidak diberi tahu secara otomatis jika data status autentikasi yang mendasarinya berubah.

Catatan

Untuk menerapkan kustom AuthenticationStateProvider, lihat Mengamankan aplikasi sisi Blazor server ASP.NET Core.

Layanan AuthenticationStateProvider ini dapat memberikan data pengguna ClaimsPrincipal saat ini, seperti yang ditunjukkan dalam contoh berikut.

ClaimsPrincipalData.razor:

@page "/claims-principle-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Count() > 0)
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Dalam contoh sebelumnya:

  • ClaimsPrincipal.Claims mengembalikan klaim pengguna (claims) untuk ditampilkan di UI.
  • Baris yang mendapatkan panggilan ClaimsPrincipal.FindAll nama keluarga (surname) pengguna dengan predikat untuk memfilter klaim pengguna.
@page "/claims-principle-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Count() > 0)
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Jika user.Identity.IsAuthenticated adalah true dan karena pengguna adalah ClaimsPrincipal, klaim dapat dihitung dan keanggotaan dalam peran dievaluasi.

Untuk informasi lebih lanjut tentang injeksi dependensi (DI) dan layanan, lihat injeksi dependensi Blazor ASP.NET Core dan Injeksi dependensi di ASP.NET Core. Untuk informasi tentang cara menerapkan kustom AuthenticationStateProvider di aplikasi sisi Blazor server, lihat Mengamankan aplikasi sisi Blazor server ASP.NET Core.

Mengekspos status autentikasi sebagai parameter berskala

Jika data status autentikasi diperlukan untuk logika prosedural, seperti saat melakukan tindakan yang dipicu oleh pengguna, dapatkan data status autentikasi dengan menentukan parameter jenis Task<AuthenticationState>berjendela , seperti yang ditunjukkan contoh berikut.

CascadeAuthState.razor:

@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [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} is authenticated.";
            }
        }
    }
}
@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [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} is authenticated.";
            }
        }
    }
}

Jika user.Identity.IsAuthenticated adalah true, klaim dapat dihitung dan keanggotaan dalam peran dievaluasi.

Siapkan Task<AuthenticationState>parameter bertingkat menggunakan AuthorizeRouteView layanan status autentikasi dan bertingkat.

Saat Anda membuat Blazor aplikasi dari salah Blazor satu templat proyek dengan autentikasi diaktifkan, aplikasi menyertakan AuthorizeRouteView dan panggilan untuk AddCascadingAuthenticationState ditampilkan dalam contoh berikut. Aplikasi sisi Blazor klien juga menyertakan pendaftaran layanan yang diperlukan. Informasi tambahan disajikan di bagian Kustomisasi konten yang tidak sah dengan komponen Router.

<Router ...>
    <Found ...>
        <AuthorizeRouteView RouteData="routeData" 
            DefaultLayout="typeof(Layout.MainLayout)" />
        ...
    </Found>
</Router>

Program Dalam file, daftarkan layanan status autentikasi berkala:

builder.Services.AddCascadingAuthenticationState();

Siapkan Task<>AuthenticationStateparameter bertingkat menggunakan AuthorizeRouteView komponen dan .CascadingAuthenticationState

Saat Anda membuat Blazor aplikasi dari salah Blazor satu templat proyek dengan autentikasi diaktifkan, aplikasi menyertakan komponen dan CascadingAuthenticationState yang AuthorizeRouteView ditampilkan dalam contoh berikut. Aplikasi sisi Blazor klien juga menyertakan pendaftaran layanan yang diperlukan. Informasi tambahan disajikan di bagian Kustomisasi konten yang tidak sah dengan komponen Router.

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="routeData" 
                DefaultLayout="typeof(MainLayout)" />
            ...
        </Found>
    </Router>
</CascadingAuthenticationState>

Catatan

Dengan rilis ASP.NET Core 5.0.1 dan untuk rilis 5.x tambahan, komponen Router menyertakan parameter PreferExactMatches yang diatur ke @true. Untuk informasi lebih lanjut, lihat Migrasi dari ASP.NET Core 3.1 ke 5.0.

Di aplikasi sisi Blazor klien, tambahkan layanan otorisasi ke Program file:

builder.Services.AddAuthorizationCore();

Di aplikasi sisi Blazor klien, tambahkan opsi dan layanan otorisasi ke Program file:

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

Di aplikasi sisi Blazor server, layanan untuk opsi dan otorisasi sudah ada, jadi tidak ada langkah lebih lanjut yang diperlukan.

Authorization

Setelah pengguna diautentikasi, aturan otorisasi diterapkan untuk mengontrol apa yang dapat dilakukan pengguna.

Akses biasanya diberikan atau ditolak berdasarkan apakah:

  • Pengguna diautentikasi (masuk).
  • Pengguna berada dalam peran.
  • Pengguna memiliki klaim.
  • Kebijakan terpenuhi.

Masing-masing konsep ini sama seperti di ASP.NET Core MVC atau aplikasi Halaman Razor. Untuk informasi lebih lanjut tentang keamanan ASP.NET Core, lihat artikel di bagian Keamanan ASP.NET Core dan Identity.

AuthorizeView komponen

Komponen AuthorizeView secara selektif menampilkan konten UI bergantung pada apakah pengguna diotorisasi. Pendekatan ini berguna jika Anda hanya perlu menampilkan data untuk pengguna dan tidak perlu menggunakan identitas pengguna dalam logika prosedural.

Komponen mengekspos context variabel jenis AuthenticationState (@context dalam Razor sintaksis), yang dapat Anda gunakan untuk mengakses informasi tentang pengguna yang masuk:

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>

Anda juga dapat menyediakan konten yang berbeda untuk ditampilkan jika pengguna tidak diotorisasi dengan kombinasi Authorized parameter dan NotAuthorized :

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
        <p><button @onclick="SecureMethod">Authorized Only Button</button></p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    private void SecureMethod() { ... }
}

Penangan peristiwa default untuk elemen yang diotorisasi, seperti metode SecureMethod untuk elemen <button> dalam contoh sebelumnya, hanya dapat dipanggil oleh pengguna yang berwenang.

Razor komponen Blazor Web Apps tidak pernah menampilkan <NotAuthorized> konten saat otorisasi gagal di sisi server selama penyajian sisi server statis (SSR statis). Alur sisi server ASP.NET Core memproses otorisasi di server. Gunakan teknik sisi server untuk menangani permintaan yang tidak sah. Untuk informasi selengkapnya, lihat mode render ASP.NET CoreBlazor.

Peringatan

Markup sisi klien dan metode yang AuthorizeView terkait dengan hanya dilindungi dari tampilan dan eksekusi di UI yang dirender di aplikasi sisi Blazor klien. Untuk melindungi konten resmi dan metode aman di sisi Blazorklien, konten biasanya disediakan oleh panggilan API web yang aman dan resmi ke API server dan tidak pernah disimpan di aplikasi. Untuk informasi selengkapnya, lihat Memanggil API web dari aplikasi ASP.NET Core Blazor dan skenario keamanan tambahan ASP.NET CoreBlazor WebAssembly.

Authorized Konten dan NotAuthorized dapat mencakup item arbitrer, seperti komponen interaktif lainnya.

Kondisi otorisasi, seperti peran atau kebijakan yang mengontrol opsi atau akses UI, dibahas di bagian Otorisasi.

Jika kondisi otorisasi tidak ditentukan, AuthorizeView gunakan kebijakan default:

  • Pengguna yang diautentikasi (masuk) diotorisasi.
  • Pengguna yang tidak diautentikasi (keluar) tidak sah.

Komponen AuthorizeView dapat digunakan dalamNavMenu komponen (Shared/NavMenu.razor) untuk menampilkanNavLink komponen (NavLink), tetapi perhatikan bahwa pendekatan ini hanya menghapus item daftar dari output yang diberikan. Pendekatan ini tidak mencegah pengguna menavigasi ke komponen. Terapkan otorisasi secara terpisah di komponen tujuan.

Otorisasi berbasis peran dan berbasis kebijakan

Komponen AuthorizeView mendukung otorisasi berbasis peran atau berbasis kebijakan.

Untuk otorisasi berbasis peran, gunakan Roles parameter . Dalam contoh berikut, pengguna harus memiliki klaim peran untuk Admin peran atau Superuser :

<AuthorizeView Roles="Admin, Superuser">
    <p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>

Untuk mengharuskan pengguna memiliki Admin klaim peran dan Superuser , komponen sarang AuthorizeView :

<AuthorizeView Roles="Admin">
    <p>User: @context.User</p>
    <p>You have the 'Admin' role claim.</p>
    <AuthorizeView Roles="Superuser" Context="innerContext">
        <p>User: @innerContext.User</p>
        <p>You have both 'Admin' and 'Superuser' role claims.</p>
    </AuthorizeView>
</AuthorizeView>

Kode sebelumnya menetapkan Context untuk komponen dalam AuthorizeView untuk mencegah AuthenticationState tabrakan konteks. Konteks AuthenticationState diakses di luar AuthorizeView dengan pendekatan standar untuk mengakses konteks (@context.User). Konteks diakses di dalam AuthorizeView dengan konteks bernama innerContext (@innerContext.User).

Untuk informasi lebih lanjut, termasuk panduan konfigurasi, lihat Otorisasi berbasis peran di ASP.NET Core.

Untuk otorisasi berbasis kebijakan, gunakan Policy parameter dengan satu kebijakan:

<AuthorizeView Policy="Over21">
    <p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>

Untuk menangani kasus di mana pengguna harus memenuhi salah satu dari beberapa kebijakan, buat kebijakan yang mengonfirmasi bahwa pengguna memenuhi kebijakan lain.

Untuk menangani kasus di mana pengguna harus memenuhi beberapa kebijakan secara bersamaan, lakukan salah satu pendekatan berikut:

  • Buat kebijakan untuk AuthorizeView yang mengonfirmasi bahwa pengguna memenuhi beberapa kebijakan lain.

  • Menumpuk kebijakan dalam beberapa AuthorizeView komponen:

    <AuthorizeView Policy="Over21">
        <AuthorizeView Policy="LivesInCalifornia">
            <p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
        </AuthorizeView>
    </AuthorizeView>
    

Otorisasi berbasis klaim adalah kasus khusus dari otorisasi berbasis kebijakan. Misalnya, Anda dapat menentukan kebijakan yang mengharuskan pengguna memiliki klaim tertentu. Untuk informasi lebih lanjut, lihat Otorisasi berbasis kebijakan di ASP.NET Core.

Jika tidak atau RolesPolicy ditentukan, AuthorizeView gunakan kebijakan default:

  • Pengguna yang diautentikasi (masuk) diotorisasi.
  • Pengguna yang tidak diautentikasi (keluar) tidak sah.

Karena perbandingan string .NET peka huruf besar/kecil secara default, peran yang cocok dan nama kebijakan juga peka huruf besar/kecil. Misalnya, Admin (huruf Abesar ) tidak diperlakukan sebagai peran yang sama dengan admin (huruf akecil ).

Kasus Pascal biasanya digunakan untuk nama peran dan kebijakan (misalnya, BillingAdministrator), tetapi penggunaan kasus Pascal bukan persyaratan yang ketat. Skema casing yang berbeda, seperti camel case, kebab case, dan snake case, diizinkan. Menggunakan spasi dalam peran dan nama kebijakan tidak biasa tetapi diizinkan oleh kerangka kerja. Misalnya, billing administrator adalah format peran atau nama kebijakan yang tidak biasa di aplikasi .NET, tetapi ini adalah peran atau nama kebijakan yang valid.

Konten ditampilkan selama autentikasi asinkron

Blazor memungkinkan status autentikasi ditentukan secara asinkron. Skenario utama untuk pendekatan ini ada di aplikasi sisi Blazor klien yang membuat permintaan ke titik akhir eksternal untuk autentikasi.

Saat autentikasi sedang berlangsung, AuthorizeView tidak menampilkan konten secara default. Untuk menampilkan konten saat autentikasi terjadi, tetapkan konten ke Authorizing parameter:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <Authorizing>
        <p>You can only see this content while authentication is in progress.</p>
    </Authorizing>
</AuthorizeView>

Pendekatan ini biasanya tidak berlaku untuk aplikasi sisi Blazor server. Aplikasi sisi Blazor server mengetahui status autentikasi segera setelah status ditetapkan. Authorizing konten dapat disediakan dalam komponen aplikasi AuthorizeView , tetapi konten tidak pernah ditampilkan.

atribut [Authorize]

Atribut [Authorize] tersedia dalam Razor komponen:

@page "/"
@attribute [Authorize]

You can only see this if you're signed in.

Penting

Hanya gunakan [Authorize] pada @page komponen yang dicapai melalui Blazor router. Otorisasi hanya dilakukan sebagai aspek perutean dan bukan untuk komponen turunan yang dirender dalam halaman. Untuk mengotorisasi tampilan bagian tertentu dalam halaman, gunakan AuthorizeView sebagai gantinya.

Atribut [Authorize] juga mendukung otorisasi berbasis peran atau berbasis kebijakan. Untuk otorisasi berbasis peran, gunakan parameter Roles:

@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]

<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>

Untuk otorisasi berbasis kebijakan, gunakan parameter Policy:

@page "/"
@attribute [Authorize(Policy = "Over21")]

<p>You can only see this if you satisfy the 'Over21' policy.</p>

Jika tidak atau RolesPolicy ditentukan, [Authorize] gunakan kebijakan default:

  • Pengguna yang diautentikasi (masuk) diotorisasi.
  • Pengguna yang tidak diautentikasi (keluar) tidak sah.

Saat pengguna tidak diotorisasi dan jika aplikasi tidak menyesuaikan konten yang tidak sah dengan komponen Router, kerangka kerja secara otomatis menampilkan pesan fallback berikut:

Not authorized.

Otorisasi sumber daya

Untuk mengotorisasi pengguna atas sumber daya, teruskan data rute permintaan ke parameter Resource dari AuthorizeRouteView.

Router.Found Dalam konten untuk rute yang diminta:

<AuthorizeRouteView Resource="routeData" RouteData="routeData" 
    DefaultLayout="typeof(MainLayout)" />

Untuk informasi lebih lanjut tentang bagaimana data status otorisasi diteruskan dan digunakan dalam logika prosedural, lihat bagian Mengekspos status autentikasi sebagai parameter berskala.

Saat AuthorizeRouteView menerima data rute untuk sumber daya, kebijakan otorisasi memiliki akses ke RouteData.PageType dan RouteData.RouteValues yang mengizinkan logika kustom untuk membuat keputusan otorisasi.

Dalam contoh berikut, kebijakan EditUser dibuat di AuthorizationOptions untuk konfigurasi layanan otorisasi aplikasi (AddAuthorizationCore) dengan logika berikut:

  • Tentukan apakah ada nilai rute dengan kunci id. Jika kunci ada, nilai rute disimpan di value.
  • Dalam variabel bernama id, simpan value sebagai string atau tetapkan nilai string kosong (string.Empty).
  • Jika id bukan string kosong, tegaskan bahwa kebijakan terpenuhi (kembalikan true) jika nilai string dimulai dengan EMP. Jika tidak, nyatakan bahwa kebijakan tersebut gagal (kembalikan false).

Dalam file Program:

  • Tambahkan namespace untuk Microsoft.AspNetCore.Components dan System.Linq:

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • Tambahkan kebijakan:

    options.AddPolicy("EditUser", policy =>
        policy.RequireAssertion(context =>
        {
            if (context.Resource is RouteData rd)
            {
                var routeValue = rd.RouteValues.TryGetValue("id", out var value);
                var id = Convert.ToString(value, 
                    System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty;
    
                if (!string.IsNullOrEmpty(id))
                {
                    return id.StartsWith("EMP", StringComparison.InvariantCulture);
                }
            }
    
            return false;
        })
    );
    

Contoh sebelumnya adalah kebijakan otorisasi yang terlalu disederhanakan, hanya digunakan untuk menunjukkan konsep dengan contoh kerja. Untuk informasi lebih lanjut tentang membuat dan mengonfigurasi kebijakan otorisasi, lihat Otorisasi berbasis kebijakan di ASP.NET Core.

Dalam komponen EditUser berikut, sumber daya di /users/{id}/edit memiliki parameter rute untuk pengidentifikasi pengguna ({id}). Komponen menggunakan kebijakan otorisasi EditUser sebelumnya untuk menentukan apakah nilai rute untuk id dimulai dengan EMP. Jika id dimulai dengan EMP, kebijakan berhasil dan akses ke komponen diotorisasi. Jika id dimulai dengan nilai selain EMP atau jika id adalah string kosong, kebijakan gagal, dan komponen tidak dimuat.

EditUser.razor:

@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}

Sesuaikan konten yang tidak sah dengan komponen Router

Komponen Router, bersama dengan komponen AuthorizeRouteView, memungkinkan aplikasi menentukan konten khusus jika:

Penting

Blazor Fitur router yang menampilkan <NotAuthorized> dan <NotFound> konten tidak beroperasi selama penyajian sisi server statis (SSR statis) karena pemrosesan permintaan sepenuhnya ditangani oleh pemrosesan dan Razor komponen permintaan alur middleware core ASP.NET tidak dirender sama sekali untuk permintaan yang tidak sah atau buruk. Gunakan teknik sisi server untuk menangani permintaan yang tidak sah dan buruk selama SSR statis. Untuk informasi selengkapnya, lihat mode render ASP.NET CoreBlazor.

<Router ...>
    <Found ...>
        <AuthorizeRouteView ...>
            <NotAuthorized>
                ...
            </NotAuthorized>
            <Authorizing>
                ...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
</Router>

Authorized Konten dan NotAuthorized dapat mencakup item arbitrer, seperti komponen interaktif lainnya.

Catatan

Sebelumnya memerlukan pendaftaran layanan status autentikasi berskala dalam file aplikasi Program :

builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView ...>
                <NotAuthorized>
                    ...
                </NotAuthorized>
                <Authorizing>
                    ...
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

NotFoundKonten , Authorized, dan NotAuthorized dapat mencakup item arbitrer, seperti komponen interaktif lainnya.

Jika NotAuthorized konten tidak ditentukan, AuthorizeRouteView gunakan pesan fallback berikut:

Not authorized.

Aplikasi yang dibuat dari Blazor WebAssembly templat proyek dengan autentikasi diaktifkan menyertakan RedirectToLogin komponen, yang diposisikan dalam <NotAuthorized> konten Router komponen. Saat pengguna tidak diautentikasi (context.User.Identity?.IsAuthenticated != true), RedirectToLogin komponen mengalihkan browser ke authentication/login titik akhir untuk autentikasi. Pengguna dikembalikan ke URL yang diminta setelah mengautentikasi dengan penyedia identitas.

Logika prosedural

Jika aplikasi diperlukan untuk memeriksa aturan otorisasi sebagai bagian dari logika prosedural, gunakan parameter berskala dari jenis Task<AuthenticationState> untuk mendapatkan ClaimsPrincipal pengguna. Task<AuthenticationState> dapat digabungkan dengan layanan lain, seperti IAuthorizationService, untuk mengevaluasi kebijakan.

Dalam contoh berikut:

  • Kode user.Identity.IsAuthenticated eksekusi untuk pengguna yang diautentikasi (masuk).
  • Kode user.IsInRole("admin") eksekusi untuk pengguna dalam peran 'Admin'.
  • Kode (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded eksekusi untuk pengguna yang memenuhi kebijakan 'content-editor'.

Aplikasi sisi Blazor server menyertakan namespace yang sesuai secara default saat dibuat dari templat proyek. Di aplikasi sisi Blazor klien, konfirmasikan keberadaan Microsoft.AspNetCore.Authorization namespace layanan dan Microsoft.AspNetCore.Components.Authorization baik di komponen atau di file aplikasi _Imports.razor :

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

ProceduralLogic.razor:

@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}

Memecahkan masalah kesalahan

Kesalahan umum:

  • Otorisasi memerlukan parameter berskala dari jenis Task<AuthenticationState>. Pertimbangkan untuk menggunakan CascadingAuthenticationState guna menyediakan ini.

  • null nilai diterima untuk authenticationStateTask

Kemungkinan proyek tidak dibuat menggunakan templat sisi Blazor server dengan autentikasi diaktifkan.

Di .NET 7 atau yang lebih lama, bungkus <CascadingAuthenticationState> beberapa bagian pohon UI, misalnya di Blazor sekitar router:

<CascadingAuthenticationState>
    <Router ...>
        ...
    </Router>
</CascadingAuthenticationState>

Di .NET 8 atau yang lebih baru, jangan gunakan CascadingAuthenticationState komponen:

- <CascadingAuthenticationState>
      <Router ...>
          ...
      </Router>
- </CascadingAuthenticationState>

Sebagai gantinya, tambahkan layanan status autentikasi berkala ke kumpulan layanan dalam Program file:

builder.Services.AddCascadingAuthenticationState();

Komponen CascadingAuthenticationState (.NET 7 atau yang lebih lama) atau layanan yang disediakan oleh AddCascadingAuthenticationState (.NET 8 atau yang lebih baru) memasok parameter kaskading>Task<AuthenticationState, yang pada gilirannya menerima dari layanan injeksi dependensi yang mendasarinya.AuthenticationStateProvider

Informasi Pengidentifikasi Pribadi (PII)

Microsoft menggunakan definisi GDPR untuk 'data pribadi' (GDPR 4.1) saat dokumentasi membahas Informasi Pengidentifikasi Pribadi (PII).

PII merujuk informasi apa pun yang berkaitan dengan orang alami yang diidentifikasi atau dapat diidentifikasi. Orang alami yang dapat diidentifikasi adalah orang yang dapat diidentifikasi, secara langsung atau tidak langsung, dengan salah satu hal berikut:

  • Nama
  • Nomor identifikasi
  • Koordinat lokasi
  • Pengidentifikasi online
  • Faktor spesifik lainnya
    • Fisik
    • Fisiologis
    • Genetik
    • Mental (psikologis)
    • Ekonomi
    • Budaya
    • Identitas sosial

Sumber Daya Tambahan: