ASP.NET Core Blazor 인증 및 권한 부여

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

이 문서에서는 Blazor 앱의 보안 구성 및 관리를 위한 ASP.NET Core 지원에 대해 설명합니다.

보안 시나리오는 앱에서 Blazor 서버 쪽과 클라이언트 쪽을 실행하는 권한 부여 코드 간에 다릅니다. 서버에서 실행되는 권한 부여 코드의 경우 권한 부여 검사 앱 및 구성 요소 영역에 대한 액세스 규칙을 적용할 수 있습니다. 클라이언트 쪽 코드 실행을 변조할 수 있으므로 클라이언트에서 실행되는 권한 부여 코드를 신뢰할 수 없으므로 액세스 규칙을 절대적으로 적용하거나 클라이언트 쪽 콘텐츠의 표시를 제어할 수 없습니다.

권한 부여 규칙 적용을 보장해야 하는 경우 클라이언트 쪽 코드에서 권한 부여 검사 구현하지 마세요. Blazor 권한 부여 검사 및 규칙 적용을 위해 SSR(서버 쪽 렌더링)만 사용하는 웹앱을 빌드합니다.

Razor Pages 권한 부여 규칙은 라우팅 가능한 Razor 구성 요소에 적용되지 않습니다. 라우팅할 수 없는 Razor 구성 요소가 Pages 앱의 Razor 페이지에 포함된 경우 페이지의 권한 부여 규칙은 페이지의 나머지 콘텐츠와 함께 구성 요소에 간접적으로 영향을 Razor 줍니다.

권한 부여 규칙 적용 및 데이터 및 코드의 보안을 보장해야 하는 경우 클라이언트 쪽 앱을 개발하지 마세요. 앱을 빌드합니다 Blazor Server .

Razor Pages 권한 부여 규칙은 라우팅 가능한 Razor 구성 요소에 적용되지 않습니다. 라우팅할 수 없는 Razor 구성 요소가 Pages 앱의 Razor 페이지에 포함된 경우 페이지의 권한 부여 규칙은 페이지의 나머지 콘텐츠와 함께 구성 요소에 간접적으로 영향을 Razor 줍니다.

ASP.NET Core Identity는 대부분의 경우 Blazor 앱 클라이언트-서버 커뮤니케이션 모델이 아닌 HTTP 요청 및 응답 커뮤니케이션의 컨텍스트에서 작동하도록 설계되었습니다. 사용자 관리에 ASP.NET Core Identity를 사용하는 ASP.NET Core 앱은 사용자 등록, 로그인, 로그아웃 및 기타 사용자 관리 작업과 같은 Identity 관련 UI에 Razor 구성 요소 대신 Razor Pages를 사용해야 합니다. 작업을 직접 처리하는 Identity 구성 요소를 빌드 Razor 하는 것은 여러 시나리오에서 가능하지만 Microsoft에서 권장하거나 지원하지 않습니다.

ASP.NET Core 추상화(예: SignInManager<TUser>UserManager<TUser>)는 Razor 구성 요소에서 지원되지 않습니다. ASP.NET Core IdentityBlazor를 사용하는 방법에 대한 자세한 내용은 서버 쪽 Blazor 앱에 스캐폴드 ASP.NET Core Identity 를 참조하세요.

참고 항목

이 문서의 코드 예제에서는 NRT(nullable 참조 형식) 및 .NET 컴파일러 null 상태 정적 분석을 채택합니다. 이 분석은 .NET 6 이상의 ASP.NET Core에서 지원됩니다. ASP.NET Core 5.0 이하를 대상으로 하는 경우 이 문서의 예제에서 null 형식 지정(?)을 제거합니다.

위조 방지 지원

Blazor 템플릿:

AntiforgeryToken 구성 요소는 위조 방지 토큰을 숨겨진 필드로 렌더링하고 이 구성 요소는 양식(EditForm) 인스턴스에 자동으로 추가됩니다. 자세한 내용은 ASP.NET Core Blazor 양식 개요를 참조하세요.

AntiforgeryStateProvider 서비스는 현재 세션과 연결된 위조 방지 토큰에 대한 액세스를 제공합니다. 서비스를 삽입하고 해당 메서드를 GetAntiforgeryToken() 호출하여 현재 AntiforgeryRequestToken를 가져옵니다. 자세한 내용은 ASP.NET Core Blazor 앱에서 웹 API 호출을 참조하세요.

Blazor 는 요청 토큰을 구성 요소 상태로 저장하므로 요청에 액세스할 수 없는 경우에도 대화형 구성 요소에서 위조 방지 토큰을 사용할 수 있습니다.

참고 항목

위조 방지 완화는 인코딩된 서버로 multipart/form-dataapplication/x-www-form-urlencoded양식 데이터를 제출할 때만 필요하거나 text/plain 유효한 양식 인크타입뿐이므로 필요합니다.

자세한 내용은 다음 리소스를 참조하세요.

  • ASP.NET Core에서 XSRF/CSRF(교차 사이트 요청 위조) 공격 방지: 이 문서는 주제에 대한 기본 ASP.NET Core 문서로, 서버 쪽 Blazor Server, Web Apps의 Blazor 서버 프로젝트 및 Blazor MVC/Razor Pages와의 통합에 적용됩니다.
  • ASP.NET Core Blazor 양식 개요: 문서의 위조 방지 지원 섹션은 위조 방지 지원 양식과 관련이 Blazor 있습니다.

인증

Blazor는 기존 ASP.NET Core 인증 메커니즘을 사용하여 사용자 ID를 설정합니다. 정확한 메커니즘은 앱이 Blazor 호스트되는 방법, 서버 쪽 또는 클라이언트 쪽에 따라 달라집니다.

서버 쪽 Blazor 인증

대화형으로 렌더링된 서버 쪽 Blazor 은 클라이언트와의 연결을 통해 SignalR 작동합니다. SignalR 기반 앱의 인증은 연결 시 처리됩니다. 인증은 전달 cookie 자 토큰 또는 일부 다른 전달자 토큰을 기반으로 할 수 있지만 인증은 허브를 SignalR 통해 전적으로 회로 내에서 관리됩니다.

기본 제공 AuthenticationStateProvider 서비스는 ASP.NET Core's HttpContext.User에서 인증 상태 데이터를 가져옵니다. 이것이 바로 인증 상태가 기존의 ASP.NET Core 인증 메커니즘과 통합되는 방식입니다.

IHttpContextAccessor/HttpContext구성 요소에서 Razor

IHttpContextAccessor 는 유효한 HttpContext 사용 가능한 렌더링이 없으므로 대화형 렌더링을 피해야 합니다.

IHttpContextAccessor 는 서버에서 정적으로 렌더링되는 구성 요소에 사용할 수 있습니다. 그러나 가능하면 피하는 것이 좋습니다.

HttpContext는 헤더 또는 구성 요소(Components/App.razor)의 다른 속성 검사 및 수정과 같은 일반적인 작업에 대해 정적으로 렌더링된 루트 구성 요소에서 App 만 연계 매개 변수로 사용할 수 있습니다. 이 값은 항상 null 대화형 렌더링을 위한 것입니다.

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

대화형 구성 요소에 필요한 시나리오 HttpContext 의 경우 서버에서 영구 구성 요소 상태를 통해 데이터를 흐르는 것이 좋습니다. 자세한 내용은 서버 쪽 ASP.NET Core Blazor 추가 보안 시나리오를 참조하세요.

서버 쪽 Blazor 앱의 구성 요소에서 Razor 직접 또는 간접적으로 사용하지 IHttpContextAccessor/HttpContext 마세요. Blazor 앱은 ASP.NET Core 파이프라인 컨텍스트 외부에서 실행됩니다. IHttpContextAccessor 내에서의 HttpContext은 보장되지 않으며, Blazor 앱을 시작하는 컨텍스트 유지를 위해 HttpContext도 보장되지 않습니다.

앱에 요청 상태를 Blazor 전달하는 권장 방법은 앱의 초기 렌더링 중에 루트 구성 요소 매개 변수를 사용하는 것입니다. 또는 앱에서 사용할 루트 구성 요소의 초기화 수명 주기 이벤트에서 범위가 지정된 서비스로 데이터를 복사할 수 있습니다. 자세한 내용은 서버 쪽 ASP.NET Core Blazor 추가 보안 시나리오를 참조하세요.

서버 쪽 Blazor 보안의 중요한 측면은 회로가 설정된 후 Blazor 특정 시점에 지정된 회로에 연결된 사용자가 업데이트될 수 있지만 IHttpContextAccessor업데이트되지 않는다는 것입니다. 사용자 지정 서비스를 사용하여 이 상황을 해결하는 방법에 대한 자세한 내용은 서버 쪽 ASP.NET Core Blazor 추가 보안 시나리오를 참조하세요.

공유 상태

서버 쪽 Blazor 앱은 서버 메모리에 있으며 여러 앱 세션은 동일한 프로세스 내에서 호스트됩니다. 각 앱 세션 Blazor 에 대해 자체 종속성 주입 컨테이너 범위를 사용하여 회로를 시작하므로 범위가 지정된 서비스는 세션당 Blazor 고유합니다.

Warning

매우 주의하지 않는 한 싱글톤 서비스를 사용하는 동일한 서버 공유 상태에서는 앱을 사용하지 않는 것이 좋습니다. 회로 간 사용자 상태 누수와 같은 보안 취약성이 도입될 수 있기 때문입니다.

특별히 설계된 경우 앱에서 Blazor 상태 저장 싱글톤 서비스를 사용할 수 있습니다. 예를 들어 메모리 캐시에는 지정된 항목에 액세스하는 데 키가 필요하기 때문에 싱글톤 메모리 캐시를 사용할 수 있습니다. 사용자가 캐시와 함께 사용되는 캐시 키를 제어할 수 없다고 가정하면 캐시에 저장된 상태는 회로 간에 누출되지 않습니다.

상태 관리에 대한 일반적인 지침은 ASP.NET Core Blazor 상태 관리를 참조하세요.

클라이언트 쪽 Blazor 인증

클라이언트 쪽 앱에서는 모든 클라이언트 쪽 Blazor 코드를 사용자가 수정할 수 있으므로 클라이언트 쪽 인증 검사 무시될 수 있습니다. JavaScript SPA 프레임워크 및 모든 운영 체제의 네이티브 앱을 비롯한 모든 클라이언트 쪽 앱 기술도 마찬가지입니다.

다음을 추가합니다.

인증을 처리하기 위해 기본 제공 또는 사용자 지정 AuthenticationStateProvider 서비스의 사용은 다음 섹션에서 설명합니다.

자세한 내용은 보안 ASP.NET Core Blazor WebAssembly를 참조하세요.

AuthenticationStateProvider 서비스

AuthenticationStateProvider 는 구성 요소 및 연계 인증 서비스에서 사용자의 인증 상태를 가져오는 데 사용하는 AuthorizeView 기본 서비스입니다.

AuthenticationStateProvider는 구성 요소 및 CascadingAuthenticationState 구성 요소에서 AuthorizeView 사용자의 인증 상태를 가져오는 데 사용하는 기본 서비스입니다.

일반적으로 AuthenticationStateProvider를 직접 사용하지는 않습니다. 이 문서의 뒷부분에서 설명하는 AuthorizeView 구성 요소 또는 Task<AuthenticationState> 접근 방식을 사용합니다. AuthenticationStateProvider를 직접 사용하는 경우의 주요 단점은 기본 인증 상태 데이터가 변경될 때 구성 요소가 자동으로 알림을 받지 못하는 것입니다.

참고 항목

사용자 지정AuthenticationStateProvider을 구현하려면 보안 ASP.NET Core 서버 쪽 Blazor 앱을 참조하세요.

서비스는 AuthenticationStateProvider 다음 예제와 같이 현재 사용자의 ClaimsPrincipal 데이터를 제공할 수 있습니다.

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

앞의 예에서:

  • ClaimsPrincipal.Claims 는 UI에 표시할 사용자의 클레임(claims)을 반환합니다.
  • 사용자의 성(surname)을 가져오는 줄은 사용자의 클레임을 필터링하기 위해 조건자를 사용하여 호출 ClaimsPrincipal.FindAll 합니다.
@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.";
        }
    }
}

user.Identity.IsAuthenticatedtrue이면, 사용자가 ClaimsPrincipal이므로 클레임을 열거하고 역할의 멤버 자격을 평가할 수 있습니다.

DI(종속성 주입) 및 서비스에 대한 자세한 내용은 ASP.NET Core Blazor 종속성 주입ASP.NET Core의 종속성 주입을 참조하세요. 서버 쪽 앱에서 사용자 지정 AuthenticationStateProvider 을 구현하는 방법에 대한 자세한 내용은 보안 ASP.NET Core 서버 쪽 Blazor 앱을 참조하세요.Blazor

인증 상태를 연계 매개 변수로 공개

사용자가 트리거하는 작업을 수행할 때와 같이 절차 논리에 인증 상태 데이터가 필요한 경우 다음 예제와 같이 형식AuthenticationStateTask<>의 연계 매개 변수를 정의하여 인증 상태 데이터를 가져옵니다.

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

user.Identity.IsAuthenticatedtrue이면, 클레임을 열거하고 역할의 멤버 자격을 평가할 수 있습니다.

Task<AuthenticationState>연계 인증 상태 서비스를 사용하여 AuthorizeRouteView 연계 매개 변수를 설정합니다.

인증을 Blazor 사용하도록 설정된 프로젝트 템플릿 중 Blazor 하나에서 앱을 만들 때 앱에는 다음 예제에 표시된 호출과 해당 호출 AddCascadingAuthenticationState 이 포함됩니다AuthorizeRouteView. 클라이언트 쪽 Blazor 앱에는 필요한 서비스 등록도 포함됩니다. 추가 정보는 라우터 구성 요소 섹션을 사용하여 권한 없는 콘텐츠 사용자 지정에 표시됩니다.

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

파일에서 Program 연계 인증 상태 서비스를 등록합니다.

builder.Services.AddCascadingAuthenticationState();

및 구성 요소를 사용하여 연계 매개 변수AuthorizeRouteView 설정합니다>AuthenticationStateTask<.CascadingAuthenticationState

인증을 Blazor 사용하도록 설정된 프로젝트 템플릿 중 Blazor 하나에서 앱을 만들 때 앱은 다음 예제에 표시된 구성 요소와 CascadingAuthenticationState 구성 요소를 포함합니다AuthorizeRouteView. 클라이언트 쪽 Blazor 앱에는 필요한 서비스 등록도 포함됩니다. 추가 정보는 라우터 구성 요소 섹션을 사용하여 권한 없는 콘텐츠 사용자 지정에 표시됩니다.

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

참고 항목

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

클라이언트 쪽 Blazor 앱에서 옵션 및 권한 부여 Program 에 대한 서비스를 파일에 추가합니다.

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

서버 쪽 Blazor 앱에서는 옵션 및 권한 부여에 대한 서비스가 이미 있으므로 추가 단계가 필요하지 않습니다.

권한 부여

사용자가 인증되면, 사용자가 수행할 수 있는 작업을 제어하기 위해 ‘권한 부여’ 규칙이 적용됩니다.

일반적으로 다음 여부에 따라 액세스가 허용 또는 거부됩니다.

  • 사용자가 인증(로그인)되었는지 여부
  • 사용자가 ‘역할’에 속하는지 여부
  • 사용자에게 ‘클레임’이 있는지 여부
  • ‘정책’이 충족되었는지 여부

이러한 각 개념은 ASP.NET Core MVC 또는 Razor Pages 앱에서와 동일합니다. ASP.NET Core 보안에 대한 자세한 내용은 ASP.NET Core 보안 및 Identity의 문서를 참조하세요.

AuthorizeView 구성 요소

AuthorizeView 구성 요소는 사용자에게 권한이 있는지에 따라 선택적으로 UI 콘텐츠를 표시합니다. 이 접근 방식은 사용자에게 데이터를 ‘표시’하기만 하면 되고 절차적 논리에 사용자 ID를 사용할 필요가 없는 경우에 유용합니다.

구성 요소는 로그인한 context 사용자에 Razor 대한 정보에 액세스하는 데 사용할 수 있는 형식 AuthenticationState 변수(@context구문)를 노출합니다.

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

사용자에게 다음과 같은 매개 변수의 조합 AuthorizedNotAuthorized 으로 권한이 부여되지 않은 경우 표시할 다른 콘텐츠를 제공할 수도 있습니다.

<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() { ... }
}

이전 예제의 <button> 요소에 대한 SecureMethod 메서드와 같이 권한 있는 요소에 대한 기본 이벤트 처리기는 권한 있는 사용자만 호출할 수 있습니다.

RazorBlazor 정적 SSR(정적 서버 쪽 렌더링) 중에 권한 부여가 서버 쪽에 실패하는 경우 Web Apps의 구성 요소는 콘텐츠를 표시 <NotAuthorized> 하지 않습니다. 서버 쪽 ASP.NET Core 파이프라인은 서버에서 권한 부여를 처리합니다. 서버 쪽 기술을 사용하여 권한 없는 요청을 처리합니다. 자세한 내용은 ASP.NET Core Blazor 렌더링 모드를 참조하세요.

Warning

클라이언트 쪽 태그 및 연결된 AuthorizeView 메서드는 클라이언트 쪽 Blazor 앱의 렌더링된 UI에서 보기 및 실행으로부터만 보호됩니다. 클라이언트 쪽 Blazor에서 권한 있는 콘텐츠 및 보안 메서드를 보호하기 위해 콘텐츠는 일반적으로 서버 API에 대한 안전하고 권한이 부여된 웹 API 호출에 의해 제공되며 앱에 저장되지 않습니다. 자세한 내용은 ASP.NET Core 앱ASP.NET Core BlazorBlazor WebAssembly 추가 보안 시나리오에서 웹 API 호출을 참조하세요.

AuthorizedNotAuthorized의 콘텐츠에는 다른 대화형 구성 요소와 같은 임의 항목이 포함될 수 있습니다.

UI 옵션이나 액세스를 제어하는 역할 또는 정책과 같은 권한 부여 조건은 권한 부여 섹션에서 설명합니다.

권한 부여 조건이 지정 AuthorizeView 되지 않은 경우 기본 정책을 사용합니다.

  • 인증된(로그인) 사용자에게 권한이 부여됩니다.
  • 인증되지 않은(로그아웃) 사용자는 권한이 없습니다.

AuthorizeView 구성 요소는 NavMenu 구성 요소(Shared/NavMenu.razor)에서 NavLink 구성 요소(NavLink)를 표시하는 데 사용할 수 있지만, 이 방법은 렌더링된 출력에서 목록 항목을 제거할 뿐입니다. 사용자가 해당 구성 요소로 이동하는 것을 방지하지는 않습니다. 대상 구성 요소에서 별도로 권한 부여를 구현합니다.

역할 기반 및 정책 기반 권한 부여

AuthorizeView 구성 요소는 ‘역할 기반’ 또는 ‘정책 기반’ 권한 부여를 지원합니다.

역할 기반 권한 부여의 경우 Roles 매개 변수를 사용합니다. 다음 예제에서는 사용자에게 역할 또는 Superuser 역할에 대한 역할 클레임이 Admin 있어야 합니다.

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

사용자에게 역할 클레임과 Superuser 역할 클레임이 모두 Admin 있어야 하려면 구성 요소를 중첩 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>

앞의 코드는 컨텍스트 충돌을 방지하기 위해 내부 AuthorizeView 구성 요소에 대한 값을 AuthenticationState 설정합니다Context. AuthenticationState 컨텍스트()에 액세스하기 위한 표준 접근 방식을 사용하여 외부 AuthorizeView 에 컨텍스트@context.User에 액세스합니다. 컨텍스트는 명명 innerContext 된 컨텍스트(@innerContext.User)를 사용하여 내부 AuthorizeView 에서 액세스됩니다.

구성 지침을 포함한 자세한 내용은 ASP.NET Core의 역할 기반 권한 부여를 참조하세요.

정책 기반 권한 부여의 Policy 경우 단일 정책과 함께 매개 변수를 사용합니다.

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

사용자가 여러 정책 중 하나를 충족해야 하는 경우를 처리하려면 사용자가 다른 정책을 충족하는지 확인하는 정책을 만듭니다.

사용자가 여러 정책을 동시에 충족해야 하는 경우를 처리하려면 다음 방법 중 하나를 수행합니다.

  • 사용자가 다른 여러 정책을 AuthorizeView 충족하는지 확인하는 정책을 만듭니다.

  • 정책을 여러 AuthorizeView 구성 요소에 중첩합니다.

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

클레임 기반 권한 부여는 정책 기반 권한 부여의 특별한 경우입니다. 예를 들어 사용자에게 특정 클레임이 있어야 하는 정책을 정의할 수 있습니다. 자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.

둘 다 지정 AuthorizeView 하지 PolicyRoles 않으면 기본 정책을 사용합니다.

  • 인증된(로그인) 사용자에게 권한이 부여됩니다.
  • 인증되지 않은(로그아웃) 사용자는 권한이 없습니다.

.NET 문자열 비교는 기본적으로 대/소문자를 구분하므로 일치하는 역할 및 정책 이름도 대/소문자를 구분합니다. 예를 들어, Admin(대문자 A)는 admin(소문자 a)와 동일한 역할로 처리되지 않습니다.

파스칼 사례는 일반적으로 역할 및 정책 이름(예: BillingAdministrator)에 사용되지만 파스칼 대/소문자를 사용하는 것은 엄격한 요구 사항이 아닙니다. 낙타 케이스, 케밥 케이스 및 뱀 케이스와 같은 다양한 대/소문자 구성표가 허용됩니다. 역할 및 정책 이름에 공백을 사용하는 것은 비정상적이지만 프레임워크에서 허용됩니다. 예를 들어 billing administrator .NET 앱에서 비정상적인 역할 또는 정책 이름 형식이지만 유효한 역할 또는 정책 이름입니다.

비동기 인증 중에 표시되는 콘텐츠

Blazor에서는 인증 상태를 비동기적으로 확인할 수 있습니다. 이 방법의 기본 시나리오는 인증을 위해 외부 엔드포인트에 요청을 하는 클라이언트 쪽 Blazor 앱에 있습니다.

인증이 진행되는 동안 AuthorizeView는 기본적으로 아무 콘텐츠도 표시하지 않습니다. 인증이 발생하는 동안 콘텐츠를 표시하려면 매개 변수에 Authorizing 콘텐츠를 할당합니다.

<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>

이 방법은 일반적으로 서버 쪽 Blazor 앱에 적용되지 않습니다. 서버 쪽 Blazor 앱은 상태가 설정되는 즉시 인증 상태를 알고 있습니다. Authorizing 콘텐츠는 앱의 AuthorizeView 구성 요소에 제공할 수 있지만 콘텐츠는 표시되지 않습니다.

[Authorize] 특성

이 특성[Authorize] 구성 요소에서 Razor 사용할 수 있습니다.

@page "/"
@attribute [Authorize]

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

Important

라우터를 통해 도달한 구성 요소에서 @pageBlazor 만 사용합니다[Authorize]. 권한 부여는 라우팅의 일부로만 수행되고, 페이지에 렌더링된 자식 구성 요소에 대해서는 수행되지 ‘않습니다’. 페이지 내의 특정 파트 표시 권한을 부여하려면 AuthorizeView를 대신 사용합니다.

[Authorize] 특성은 역할 기반 또는 정책 기반 권한 부여도 지원합니다. 역할 기반 권한 부여의 경우 Roles 매개 변수를 사용합니다.

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

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

정책 기반 권한 부여의 경우 Policy 매개 변수를 사용합니다.

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

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

둘 다 지정 [Authorize] 하지 PolicyRoles 않으면 기본 정책을 사용합니다.

  • 인증된(로그인) 사용자에게 권한이 부여됩니다.
  • 인증되지 않은(로그아웃) 사용자는 권한이 없습니다.

사용자에게 권한이 부여되지 않고 앱이 라우터 구성 요소를 사용하여 권한 없는 콘텐츠를 사용자 지정하지 않는 경우 프레임워크는 다음 대체 메시지를 자동으로 표시합니다.

Not authorized.

리소스 권한 부여

사용자에게 리소스에 대한 권한을 부여하려면 요청의 경로 데이터를 AuthorizeRouteViewResource 매개 변수에 전달합니다.

요청된 경로에 Router.Found 대한 콘텐츠에서:

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

프로시저 논리에서 권한 부여 상태 데이터가 전달되고 사용되는 방법에 대한 자세한 내용은 인증 상태를 연계 매개 변수로 공개 섹션을 참조하세요.

AuthorizeRouteView에서 리소스에 대한 경로 데이터를 수신하면 권한 부여 정책에서 RouteData.PageTypeRouteData.RouteValues에 액세스하여 권한 부여 결정을 내리기 위한 사용자 지정 논리를 허용합니다.

다음 예제에서는 다음 논리를 사용하여 앱의 권한 부여 서비스 구성(AddAuthorizationCore)에 대해 EditUser 정책을 AuthorizationOptions에서 만듭니다.

  • 키가 id인 경로 값이 있는지 여부를 확인합니다. 키가 있는 경우 경로 값은 value에 저장됩니다.
  • id라는 변수에서 value를 문자열로 저장 거나 빈 문자열 값(string.Empty)을 설정합니다.
  • id가 빈 문자열이 아닌 경우에는 문자열의 값이 EMP로 시작되는 경우 정책이 충족됨(true 반환)을 어설션합니다. 그렇지 않은 경우 정책이 실패함(false 반환)을 어설션합니다.

Program 파일에서:

  • 다음과 같이 Microsoft.AspNetCore.ComponentsSystem.Linq의 네임스페이스를 추가합니다.

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • 다음과 같이 정책을 추가합니다.

    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;
        })
    );
    

앞의 예제는 작업 예제를 사용하여 개념을 설명하는 데만 사용되는 너무 단순해진 권한 부여 정책입니다. 권한 부여 정책 생성 및 구성에 대한 자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.

다음 EditUser 구성 요소에서 /users/{id}/edit의 리소스에는 사용자의 식별자({id})에 대한 경로 매개 변수가 있습니다. 구성 요소는 위의 EditUser 권한 부여 정책을 사용하여 id의 경로 값이 EMP로 시작하는지 여부를 확인합니다. idEMP로 시작하면 정책이 성공하고 구성 요소에 대한 액세스 권한이 부여됩니다. idEMP 이외의 값으로 시작하거나 id가 빈 문자열인 경우 정책이 실패하고 구성 요소가 로드되지 않습니다.

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; }
}

Router 구성 요소를 사용하여 권한 없는 콘텐츠 사용자 지정

AuthorizeRouteView 구성 요소와 함께 Router 구성 요소를 사용하면 다음과 같은 경우 앱이 사용자 지정 콘텐츠를 지정할 수 있습니다.

  • 사용자가 구성 요소에 적용된 [Authorize] 조건을 충족하지 못하는 경우 <NotAuthorized> 요소의 태그가 표시됩니다. [Authorize] 특성은 [Authorize] 속성 섹션에서 설명합니다.
  • 비동기 권한 부여가 진행 중이며 이는 일반적으로 사용자를 인증하는 프로세스가 진행되고 있음을 의미합니다. <Authorizing> 요소의 태그가 표시됩니다.

Important

Blazor요청 처리는 ASP.NET Core 미들웨어 파이프라인 요청 처리에 의해 완전히 처리되고 구성 요소는 무단 또는 잘못된 요청에 대해 전혀 렌더링되지 않으므로 정적 SSR(정적 서버 쪽 렌더링) 중에는 표시 및 Razor 콘텐츠가 작동하지 <NotAuthorized><NotFound> 않습니다. 서버 쪽 기술을 사용하여 정적 SSR 중에 무단 및 잘못된 요청을 처리합니다. 자세한 내용은 ASP.NET Core Blazor 렌더링 모드를 참조하세요.

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

AuthorizedNotAuthorized의 콘텐츠에는 다른 대화형 구성 요소와 같은 임의 항목이 포함될 수 있습니다.

참고 항목

앞에는 앱 Program 파일에서 연속 인증 상태 서비스 등록이 필요합니다.

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

NotFound, AuthorizedNotAuthorized의 콘텐츠에는 다른 대화형 구성 요소와 같은 임의 항목이 포함될 수 있습니다.

콘텐츠가 지정 AuthorizeRouteView 되지 않은 경우 NotAuthorized 다음 대체 메시지를 사용합니다.

Not authorized.

인증을 Blazor WebAssembly 사용하도록 설정된 프로젝트 템플릿에서 만든 앱에는 구성 요소의 Router 콘텐츠에 <NotAuthorized> 배치되는 구성 요소가 포함됩니다RedirectToLogin. 사용자가 인증되지 않은 경우(context.User.Identity?.IsAuthenticated != true) RedirectToLogin 구성 요소는 인증을 위해 브라우저를 authentication/login 엔드포인트로 리디렉션합니다. 사용자는 ID 공급자를 인증한 후 요청된 URL로 돌아갑니다.

절차적 논리

앱이 절차적 논리의 일부로 권한 부여 규칙을 확인해야 하는 경우, Task<AuthenticationState> 형식의 연계 매개 변수를 사용하여 사용자의 ClaimsPrincipal을 가져옵니다. IAuthorizationService 등의 다른 서비스와 Task<AuthenticationState>를 결합하여 정책을 평가할 수 있습니다.

다음 예제에서

  • user.Identity.IsAuthenticated 인증된(로그인) 사용자에 대한 코드를 실행합니다.
  • 'user.IsInRole("admin")관리' 역할의 사용자에 대한 코드를 실행합니다.
  • ' (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded content-editor' 정책을 만족하는 사용자에 대한 코드를 실행합니다.

서버 쪽 Blazor 앱은 프로젝트 템플릿에서 만들 때 기본적으로 적절한 네임스페이스를 포함합니다. 클라이언트 쪽 Blazor 앱에서 구성 요소 또는 앱 파일에 네임스페이스 및 Microsoft.AspNetCore.Components.Authorization 네임스페이스가 _Imports.razor 있는지 확인 Microsoft.AspNetCore.Authorization 합니다.

@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)
                {
                    // ...
                }
            }
        }
    }
}

오류 문제 해결

일반 오류:

  • 권한을 부여하려면 Task<AuthenticationState> 형식의 연계 매개 변수가 필요합니다. CascadingAuthenticationState를 사용하여 이 변수를 제공하는 방법을 고려하세요.

  • authenticationStateTask에 대해 null 값을 받았습니다.

인증을 사용하도록 설정된 서버 쪽 Blazor 템플릿을 사용하여 프로젝트를 만들지 않았을 수 있습니다.

.NET 7 이하에서는 라우터와 같이 Blazor UI 트리의 일부 부분을 래핑 <CascadingAuthenticationState> 합니다.

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

.NET 8 이상에서는 다음 구성 요소를 사용하지 CascadingAuthenticationState 마세요.

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

대신 파일의 서비스 컬렉션 Program 에 연계 인증 상태 서비스를 추가합니다.

builder.Services.AddCascadingAuthenticationState();

CascadingAuthenticationState 구성 요소(.NET 7 이하) 또는 (.NET 8 이상)에서 제공하는 AddCascadingAuthenticationState 서비스는 기본 종속성 주입 서비스에서 수신하는 연계 매개 변수를 AuthenticationStateProvider 제공합니다AuthenticationStateTask<>.

PII(개인 식별 정보)

Microsoft는 설명서에서 PII(개인 식별 정보) 에 대해 설명하는 경우 '개인 데이터'(GDPR 4.1)에 GDPR 정의를 사용합니다.

PII는 식별되거나 식별 가능한 자연인과 관련된 모든 정보를 참조합니다. 식별 가능한 자연인은 다음 중 하나를 사용하여 직접 또는 간접적으로 식별할 수 있는 사람입니다.

  • 속성
  • ID 번호
  • 위치 좌표
  • 온라인 식별자
  • 기타 특정 요소
    • 물리적
    • 생리 적
    • 유전
    • 정신(심리적)
    • 경제
    • 문화권
    • 소셜 ID

추가 리소스