Microsoft Entra(ME-ID) 그룹, 관리자 역할 및 앱 역할

이 문서에서는 ME-ID(Microsoft Entra ID) 그룹 및 역할을 사용하도록 구성하는 Blazor WebAssembly 방법을 설명합니다.

ME-ID는 ASP.NET Core Identity와 결합할 수 있는 몇 가지 권한 부여 방법을 제공합니다.

  • Groups
    • 보안
    • Microsoft 365
    • 배포
  • 역할
    • ME-ID 기본 제공 관리자 역할
    • 앱 역할

이 문서의 지침은 다음 문서에 설명된 ME-ID 배포 시나리오에 적용됩니다 Blazor WebAssembly .

이 문서의 예제에서는 새로운 .NET/C# 기능을 활용합니다. .NET 7 이전 버전에서 예제를 사용하는 경우 약간의 수정이 필요합니다. 그러나 ME-ID 및 Microsoft Graph와 상호 작용하는 것과 관련된 텍스트 및 코드 예제는 모든 버전의 ASP.NET Core에서 동일합니다.

샘플 앱

다음 링크를 사용하여 리포지토리 루트의 최신 버전 폴더를 통해 명명된 BlazorWebAssemblyEntraGroupsAndRoles샘플 앱에 액세스합니다. 샘플은 .NET 8 이상에 대해 제공됩니다. 앱을 실행하는 방법에 대한 단계는 샘플 앱의 README 파일을 참조하세요.

샘플 앱에는 사용자의 클레임을 표시하기 위한 구성 요소가 포함되어 UserClaims 있습니다. UserData 구성 요소에 사용자의 기본 계정 속성이 표시됩니다.

샘플 코드 보기 및 다운로드(다운로드 방법)

전제 조건

이 문서의 지침은 ASP.NET Core Blazor WebAssembly로 Graph API 사용의 .Graph SDK 지침에 따라 Microsoft Graph API를 구현합니다. Graph SDK 구현 지침에 따라 앱을 구성하고 테스트하여 앱이 테스트 사용자 계정에 대한 Graph API 데이터를 가져올 수 있음을 확인합니다. 또한, Microsoft Graph 보안 개념을 검토하려면 Graph API 문서의 보안 문서 교차 링크를 참조하세요.

Graph SDK를 로컬로 테스트할 때 느린 쿠키가 테스트를 방해하지 않도록 각 테스트에 대해 새 프라이빗/시크릿 브라우저 세션을 사용하는 것이 좋습니다. 자세한 내용은 Microsoft Entra ID를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보안을 참조하세요.

ME-ID 앱 등록 온라인 도구

이 문서에서는 앱의 ME-ID 앱 등록을 구성하라는 메시지를 표시할 때 Azure Portal 을 참조하지만 Microsoft Entra 관리 센터는 ME-ID 앱 등록을 관리하기 위한 실행 가능한 옵션이기도 합니다. 두 인터페이스 중 하나를 사용할 수 있지만 이 문서의 지침에는 특히 Azure Portal에 대한 제스처가 설명되어 있습니다.

범위

사용 권한 및 범위는 동일한 것을 의미하며 보안 설명서 및 Azure Portal에서 서로 바꿔서 사용됩니다. 텍스트가 Azure Portal을 참조하지 않는 한 이 문서에서는 Graph 권한을 참조할 때 범위/범위를 사용합니다.

범위는 대/소문자를 구분하지 않으므로 User.Read user.read. 두 형식 중 하나를 자유롭게 사용할 수 있지만 애플리케이션 코드에서 일관된 선택을 하는 것이 좋습니다.

사용자 프로필, 역할 할당 및 그룹 멤버 자격 데이터에 대한 Microsoft Graph API 호출을 허용하기 위해 앱은 Azure Portal에서 위임된 User.Read범위(https://graph.microsoft.com/User.Read)로 구성됩니다. 사용자 데이터를 읽는 액세스 권한은 개별 사용자에게 부여된 범위(위임)에 따라 결정되기 때문입니다. 이 범위는 앞서 나열된 문서(Microsoft 계정을 사용하는 독립 실행형 또는 ME-ID가 있는 독립 실행형)에서 설명한 ME-ID 배포 시나리오에 필요한 범위 외에 필요합니다.

추가 필수 범위는 다음과 같습니다.

  • 위임된 RoleManagement.Read.Directory 범위(https://graph.microsoft.com/RoleManagement.Read.Directory): 앱에서 로그인한 사용자를 대신하여 회사 디렉터리에 대한 RBAC(역할 기반 액세스 제어) 설정을 읽을 수 있습니다. 여기에는 디렉터리 역할 템플릿, 디렉터리 역할 및 멤버 자격을 읽는 것이 포함됩니다. 디렉터리 역할 멤버 자격은 ME ID 기본 제공 관리자 역할에 대한 클레임을 앱에서 만드는 directoryRole 데 사용됩니다. 관리자 동의가 필요합니다.
  • 위임된 AdministrativeUnit.Read.All 범위(https://graph.microsoft.com/AdministrativeUnit.Read.All): 앱에서 로그인한 사용자를 대신하여 관리 단위 및 관리 단위 멤버 자격을 읽을 수 있습니다. 이러한 멤버 자격은 앱에서 클레임을 만드는 administrativeUnit 데 사용됩니다. 관리자 동의가 필요합니다.

자세한 내용은 Microsoft 플랫폼의 사용 권한 및 동의 개요 및 Microsoft identity Graph 권한 개요를 참조하세요.

사용자 지정 사용자 계정

Azure Portal에서 ME-ID 보안 그룹 및 ME-ID 관리자 역할에 사용자를 할당합니다.

이 문서의 예제는 다음과 같습니다.

  • 서버 API 데이터에 액세스하기 위한 권한 부여를 위해 사용자가 Azure Portal ME-ID 테넌트에서 ME-ID 청구 관리자 역할에 할당된다고 가정합니다.
  • 권한 부여 정책을 사용하여 앱 내에서 액세스를 제어합니다.

다음의 속성을 포함하도록 확장 RemoteUserAccount 합니다.

CustomUserAccount.cs:

using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

namespace BlazorWebAssemblyEntraGroupsAndRoles;

public class CustomUserAccount : RemoteUserAccount
{
    [JsonPropertyName("roles")]
    public List<string>? Roles { get; set; }

    [JsonPropertyName("oid")]
    public string? Oid { get; set; }
}

에 대한 앱에 패키지 참조를 추가합니다 Microsoft.Graph.

참고 항목

.NET 앱에 패키지를 추가하는 방법에 대한 지침은 패키지 사용 워크플로에서 패키지 설치 및 관리의 문서(NuGet 설명서)를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.

ASP.NET Core Blazor WebAssembly에서 Graph API 사용 문서의 Graph SDK 지침에서 Graph SDK 유틸리티 클래스 및 구성을 추가합니다. User.Read문서의 예제 wwwroot/appsettings.json 파일에 표시된 대로 액세스 토큰의 범위 RoleManagement.Read.DirectoryAdministrativeUnit.Read.All 범위를 지정합니다.

앱에 다음 사용자 지정 사용자 계정 팩터리를 추가합니다. 사용자 지정 사용자 팩터리는 다음을 설정하는 데 사용됩니다.

  • 앱 역할 클레임(role)(앱 역할 섹션에서 설명).

  • 사용자의 휴대폰 번호(mobilePhone) 및 사무실 위치(officeLocation)에 대한 사용자 프로필 데이터 클레임 예제.

  • ME-ID 관리자 역할 클레임(directoryRole).

  • ME-ID 관리 단위 클레임(administrativeUnit).

  • ME-ID 그룹 클레임(directoryGroup).

  • 정보 또는 오류를 기록하려는 경우 편의를 위한 ILogger(logger).

CustomAccountFactory.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;
using Microsoft.Kiota.Abstractions.Authentication;

namespace BlazorWebAssemblyEntraGroupsAndRoles;

public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider, ILogger<CustomAccountFactory> logger,
        IConfiguration config)
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger = logger;
    private readonly IServiceProvider serviceProvider = serviceProvider;
    private readonly string? baseUrl = string.Join("/",
        config.GetSection("MicrosoftGraph")["BaseUrl"],
        config.GetSection("MicrosoftGraph")["Version"]);

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var initialUser = await base.CreateUserAsync(account, options);

        if (initialUser.Identity is not null &&
            initialUser.Identity.IsAuthenticated)
        {
            var userIdentity = initialUser.Identity as ClaimsIdentity;

            if (userIdentity is not null && !string.IsNullOrEmpty(baseUrl) &&
                account.Oid is not null)
            {
                account?.Roles?.ForEach((role) =>
                {
                    userIdentity.AddClaim(new Claim("role", role));
                });

                try
                {
                    var client = new GraphServiceClient(
                        new HttpClient(),
                        serviceProvider
                            .GetRequiredService<IAuthenticationProvider>(),
                        baseUrl);

                    var user = await client.Me.GetAsync();

                    if (user is not null)
                    {
                        userIdentity.AddClaim(new Claim("mobilephone",
                            user.MobilePhone ?? "(000) 000-0000"));
                        userIdentity.AddClaim(new Claim("officelocation",
                            user.OfficeLocation ?? "Not set"));
                    }

                    var memberOf = client.Users[account?.Oid].MemberOf;

                    var graphDirectoryRoles = await memberOf.GraphDirectoryRole.GetAsync();

                    if (graphDirectoryRoles?.Value is not null)
                    {
                        foreach (var entry in graphDirectoryRoles.Value)
                        {
                            if (entry.RoleTemplateId is not null)
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryRole", entry.RoleTemplateId));
                            }
                        }
                    }

                    var graphAdministrativeUnits = await memberOf.GraphAdministrativeUnit.GetAsync();

                    if (graphAdministrativeUnits?.Value is not null)
                    {
                        foreach (var entry in graphAdministrativeUnits.Value)
                        {
                            if (entry.Id is not null)
                            {
                                userIdentity.AddClaim(
                                    new Claim("administrativeUnit", entry.Id));
                            }
                        }
                    }

                    var graphGroups = await memberOf.GraphGroup.GetAsync();

                    if (graphGroups?.Value is not null)
                    {
                        foreach (var entry in graphGroups.Value)
                        {
                            if (entry.Id is not null)
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryGroup", entry.Id));
                            }
                        }
                    }
                }
                catch (AccessTokenNotAvailableException exception)
                {
                    exception.Redirect();
                }
            }
        }

        return initialUser;
    }
}

앞의 코드가 하는 역할은 다음과 같습니다.

  • 전이적 멤버 자격은 포함하지 않습니다. 앱에 직접 및 전이적 그룹 멤버 자격 클레임이 필요한 경우 MemberOf 속성(IUserMemberOfCollectionWithReferencesRequestBuilder)을 TransitiveMemberOf(IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder)로 바꿉니다.
  • 클레임의 directoryRole GUID 값은 ME-ID 관리자 역할 템플릿 ID(Microsoft.Graph.Models.DirectoryRole.RoleTemplateId)입니다. 템플릿 ID는 앱에서 사용자 권한 부여 정책을 만들기 위한 안정적인 식별자이며 이 문서의 뒷부분에서 설명합니다. 디렉터리 역할 클레임 값은 테넌트 전체에서 안정적이지 않으므로 사용하지 entry.Id 마세요.

다음으로, 사용자 지정 사용자 계정 팩터리를 사용하도록 MSAL 인증을 구성합니다.

Program 파일이 Microsoft.AspNetCore.Components.WebAssembly.Authentication 네임스페이스를 사용하는지 확인합니다.

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

AddMsalAuthentication 호출을 다음으로 업데이트합니다. Blazor 프레임워크의 RemoteUserAccount는 MSAL 인증 및 계정 클레임 보안 주체 팩터리에 대한 앱의 CustomUserAccount으로 대체됩니다.

builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
    CustomUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd",
            options.ProviderOptions.Authentication);
        options.UserOptions.RoleClaim = "role";
    })
    .AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
        CustomAccountFactory>();

ASP.NET Core Blazor WebAssembly 와 함께 Graph API 사용 문서에 설명된 파일에 Graph SDK 코드 Program 가 있는지 확인합니다.

var baseUrl =
    string.Join("/",
        builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
            "https://graph.microsoft.com",
        builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
            "v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
    .Get<List<string>>() ?? [ "user.read" ];

builder.Services.AddGraphClient(baseUrl, scopes);

Important

Azure Portal의 앱 등록에서 다음 권한이 부여되는지 확인합니다.

  • User.Read
  • RoleManagement.Read.Directory (관리자 동의 필요)
  • AdministrativeUnit.Read.All (관리자 동의 필요)

wwwroot/appsettings.json Graph SDK 지침에 따라 구성이 올바른지 확인합니다.

wwwroot/appsettings.json:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/{TENANT ID}",
    "ClientId": "{CLIENT ID}",
    "ValidateAuthority": true
  },
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com",
    "Version": "v1.0",
    "Scopes": [
      "User.Read",
      "RoleManagement.Read.Directory",
      "AdministrativeUnit.Read.All"
    ]
  }
}

Azure Portal에서 앱의 ME-ID 등록에서 다음 자리 표시자에 대한 값을 제공합니다.

  • {TENANT ID}: 디렉터리(테넌트) ID GUID 값입니다.
  • {CLIENT ID}: 애플리케이션(클라이언트) ID GUID 값입니다.

권한 부여 구성

파일에서 앱 역할(역할 이름별), ME ID 기본 제공 관리자 역할(역할 템플릿 ID/GUID별) 또는 보안 그룹(개체 ID/GUID별)에 Program 대한 정책을 만듭니다. 다음 예제에서는 ME-ID 기본 제공 청구 관리자 역할에 대한 정책을 만듭니다.

builder.Services.AddAuthorizationCore(options =>
{
    options.AddPolicy("BillingAdministrator", policy => 
        policy.RequireClaim("directoryRole", 
            "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});

ME-ID 관리자 역할에 대한 ID(GUID)의 전체 목록은 ME-ID 설명서의 역할 템플릿 ID를 참조하세요. Azure 보안 또는 O365 그룹 ID(GUID)의 경우 앱 등록의 Azure Portal 그룹 창에서 그룹의 개체 ID를 참조하세요. 권한 부여 정책에 대한 자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.

다음 예제에서 앱은 앞에 나온 정책을 사용하여 사용자에게 권한을 부여합니다.

AuthorizeView 구성 요소는 이 정책을 준수합니다.

<AuthorizeView Policy="BillingAdministrator">
    <Authorized>
        <p>
            The user is in the 'Billing Administrator' ME-ID Administrator Role
            and can see this content.
        </p>
    </Authorized>
    <NotAuthorized>
        <p>
            The user is NOT in the 'Billing Administrator' role and sees this
            content.
        </p>
    </NotAuthorized>
</AuthorizeView>

전체 구성 요소에 대한 액세스는 [Authorize] 특성 지시문(AuthorizeAttribute)을 사용하는 정책을 기반으로 할 수 있습니다.

@page "/"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "BillingAdministrator")]

사용자에게 권한이 없는 경우 ME-ID 로그인 페이지로 리디렉션됩니다.

절차 논리를 사용하여 코드에서 정책 검사를 수행할 수도 있습니다.

CheckPolicy.razor:

@page "/checkpolicy"
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

<h1>Check Policy</h1>

<p>This component checks a policy in code.</p>

<button @onclick="CheckPolicy">Check 'BillingAdministrator' policy</button>

<p>Policy Message: @policyMessage</p>

@code {
    private string policyMessage = "Check hasn't been made yet.";

    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private async Task CheckPolicy()
    {
        var user = (await authenticationStateTask).User;

        if ((await AuthorizationService.AuthorizeAsync(user, 
            "BillingAdministrator")).Succeeded)
        {
            policyMessage = "Yes! The 'BillingAdministrator' policy is met.";
        }
        else
        {
            policyMessage = "No! 'BillingAdministrator' policy is NOT met.";
        }
    }
}

앞의 방법을 사용하여 보안 그룹에 대한 정책 기반 액세스를 만들 수도 있습니다. 여기서 정책에 사용된 GUID는 와 일치합니다.

앱 역할

앱 역할 멤버 자격 클레임을 제공하도록 Azure Portal에서 앱을 구성하려면 애플리케이션에 앱 역할 추가를 참조 하고 ME-ID 설명서의 토큰 에서 해당 역할을 받습니다.

다음 예제에서는 앱이 두 개의 역할로 구성되고 역할이 테스트 사용자에게 할당된다고 가정합니다.

  • Admin
  • Developer

ME-ID Premium 계정이 없는 그룹에 역할을 할당할 수는 없지만 사용자에게 역할을 할당하고 표준 Azure 계정을 사용하는 사용자에 대한 역할 클레임을 받을 수 있습니다. 이 섹션의 지침에는 ME-ID Premium 계정이 필요하지 않습니다.

다음 방법 중 하나를 사용하여 ME-ID에 앱 역할을 추가합니다.

  • 기본 디렉터리작업할 때 애플리케이션에 앱 역할 추가의 지침에 따라 토큰에서 수신하여 ME-ID 역할을 만듭니다.

  • 기본 디렉터리로 작업하지 않는 경우 Azure Portal에서 앱의 매니페스트를 편집하여 매니페스트 파일 항목에서 appRoles 수동으로 앱의 역할을 설정합니다. 다음은 AdminDeveloper 역할을 만드는 예제 appRoles 항목입니다. 이러한 예제 역할은 나중에 구성 요소 수준에서 액세스 제한을 구현하는 데 사용됩니다.

    Important

    다음 방법은 Azure 계정의 기본 디렉터리에 등록되지 않은 앱에만 권장됩니다. 기본 디렉터리에 등록된 앱의 경우 이 목록의 이전 글머리 기호를 참조하세요.

    "appRoles": [
      {
        "allowedMemberTypes": [
          "User"
        ],
        "description": "Administrators manage developers.",
        "displayName": "Admin",
        "id": "{ADMIN GUID}",
        "isEnabled": true,
        "lang": null,
        "origin": "Application",
        "value": "Admin"
      },
      {
        "allowedMemberTypes": [
          "User"
        ],
        "description": "Developers write code.",
        "displayName": "Developer",
        "id": "{DEVELOPER GUID}",
        "isEnabled": true,
        "lang": null,
        "origin": "Application",
        "value": "Developer"
      }
    ],
    

    앞의 예제에서 {ADMIN GUID} 자리 표시자 및 {DEVELOPER GUID} 자리 표시자의 경우 온라인 GUID 생성기를 사용하여 GUID 를 생성할 수 있습니다("guid 생성기"에 대한 Google 검색 결과).

사용자(또는 프리미엄 계층 Azure 계정이 있는 경우, 그룹)에 역할을 할당하려면 다음을 수행합니다.

  1. Azure Portal의 ME-ID 영역에서 엔터프라이즈 애플리케이션으로 이동합니다.
  2. app을 선택합니다. 사이드바에서관리>사용자 및 그룹을 선택합니다.
  3. 하나 이상의 사용자 계정에 대한 확인란을 선택합니다.
  4. 사용자 목록 위의 메뉴에서 할당 편집을 선택합니다.
  5. 역할 선택 항목에서 선택한 항목 없음을 선택합니다.
  6. 목록에서 역할을 선택하고 선택 단추를 사용하여 선택합니다.
  7. 화면 아래쪽에 있는 할당 단추를 사용하여 역할을 할당합니다.

Azure Portal에서 각 추가 역할 할당에 대해 ‘사용자를 다시 추가’함으로써 여러 역할이 할당됩니다. 사용자 목록 맨 위에 있는 사용자/그룹 추가 단추를 사용하여 사용자를 다시 추가합니다. 이전 단계를 사용하여 사용자에게 다른 역할을 할당합니다. 사용자(또는 그룹)에 역할을 추가하는 데 필요한 횟수만큼 이 프로세스를 반복할 수 있습니다.

사용자 지정 사용자 계정 섹션에 표시된 CustomAccountFactory는 JSON 배열 값을 사용하여 role 클레임에 대해 작동하도록 설정됩니다. 사용자 지정 사용자 계정 섹션에 표시된 대로 앱에 추가 및 등록 CustomAccountFactory 합니다. 원래 role 클레임은 프레임워크에 의해 자동으로 제거되므로 이를 제거하는 코드를 제공할 필요는 없습니다.

Program 파일에서 "role"라는 클레임을 검사에 대한 ClaimsPrincipal.IsInRole 역할 클레임으로 추가하거나 확인합니다.

builder.Services.AddMsalAuthentication(options =>
{
    ...

    options.UserOptions.RoleClaim = "role";
});

참고 항목

클레임(ME-ID 관리자 역할)을 directoryRoles 사용하려면 "directoryRoles"를 할당합니다 RemoteAuthenticationUserOptions.RoleClaim.

이전 단계를 완료하여 사용자(또는 프리미엄 계층 Azure 계정이 있는 경우, 그룹)에 역할을 만들고 할당하고 이 문서의 앞부분과 ASP.NET Core Blazor WebAssembly로 Graph API 사용에서 설명한 대로 Graph SDK를 사용하여 CustomAccountFactory을 구현한 후에는 로그인한 사용자에게 할당된 각 역할(또는 구성원이 속한 그룹에 할당된 역할)에 대한 role 클레임이 표시됩니다. 테스트 사용자와 함께 앱을 실행하여 클레임이 예상대로 존재하는지 확인합니다. Graph SDK를 로컬로 테스트할 때 느린 쿠키가 테스트를 방해하지 않도록 각 테스트에 대해 새 프라이빗/시크릿 브라우저 세션을 사용하는 것이 좋습니다. 자세한 내용은 Microsoft Entra ID를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보안을 참조하세요.

이 시점에서는 구성 요소 권한 부여 방식이 작동합니다. 앱 구성 요소의 모든 권한 부여 메커니즘은 역할을 사용하여 Admin 사용자에게 권한을 부여할 수 있습니다.

여러 역할 테스트가 지원됩니다.

  • 사용자는 AuthorizeView 구성 요소가 있는 Admin 또는 Developer 역할 중 하나에 있어야 합니다.

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • 사용자는 AuthorizeView 구성 요소가 있는 Admin Developer 역할 모두에 있어야 합니다.

    <AuthorizeView Roles="Admin">
        <AuthorizeView Roles="Developer" Context="innerContext">
            ...
        </AuthorizeView>
    </AuthorizeView>
    

    내부 인증에 대한 Context 자세한 내용은 ASP.NET Core Blazor 인증 및 권한 부여를 참조하세요.AuthorizeView

  • 사용자는 [Authorize] 특성이 있는 Admin 또는 Developer 역할 중 하나에 있어야 합니다.

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • 사용자는 [Authorize] 특성이 있는 Admin Developer 역할 모두에 있어야 합니다.

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • 사용자는 프로시저 코드가 있는 Admin 또는 Developer 역할 중 하나에 있어야 합니다.

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • 앞의 예제에서 조건부 OR(||)조건부 AND(&&)로 변경하면 사용자가 Admin Developer 역할 모두에 있어야 합니다.

    if (user.IsInRole("Admin") && user.IsInRole("Developer"))
    

여러 역할 테스트가 지원됩니다.

  • 사용자는 [Authorize] 특성이 있는 Admin 또는 Developer 역할 중 하나에 있어야 합니다.

    [Authorize(Roles = "Admin, Developer")]
    
  • 사용자는 [Authorize] 특성이 있는 Admin Developer 역할 모두에 있어야 합니다.

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • 사용자는 프로시저 코드가 있는 Admin 또는 Developer 역할 중 하나에 있어야 합니다.

    static readonly string[] scopeRequiredByApi = new string[] { "API.Access" };
    
    ...
    
    [HttpGet]
    public IEnumerable<ReturnType> Get()
    {
        HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
    
        if (User.IsInRole("Admin") || User.IsInRole("Developer"))
        {
            ...
        }
        else
        {
            ...
        }
    
        return ...
    }
    
  • 앞의 예제에서 조건부 OR(||)조건부 AND(&&)로 변경하면 사용자가 Admin Developer 역할 모두에 있어야 합니다.

    if (User.IsInRole("Admin") && User.IsInRole("Developer"))
    

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

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

추가 리소스