Microsoft Entra(ME-ID) 그룹, 관리자 역할 및 앱 역할(.NET 5에서 .NET 7까지)
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 ASP.NET Core 릴리스는 Microsoft Entra ID 그룹 및 역할이 있는 최신 버전의 ASP.NET Core Blazor WebAssembly 를 참조하세요.
이 문서에서는 Microsoft Entra ID 그룹 및 역할을 사용하도록 구성하는 Blazor WebAssembly 방법을 설명합니다.
MICROSOFT Entra(ME-ID)는 ASP.NET Core Identity와 결합할 수 있는 몇 가지 권한 부여 방법을 제공합니다.
- Groups
- 보안
- Microsoft 365
- 배포
- 역할
- ME-ID 관리자 역할
- 앱 역할
이 문서의 지침은 다음 문서에 설명된 ME-ID 배포 시나리오에 적용됩니다 Blazor WebAssembly .
이 문서에서는 클라이언트 앱과 서버 앱에 대한 지침을 제공합니다.
- CLIENT: 독립 실행형 Blazor WebAssembly 앱 또는 호스트된 Blazor솔루션의 Client 앱입니다.
- SERVER: ASP.NET Core 서버 API/웹 API 앱 또는 호스트된 Blazor 솔루션의 Server 앱. 독립 실행형 Blazor WebAssembly 앱에 대한 문서 전체에서 SERVER 지침을 무시할 수 있습니다.
이 문서의 예제에서는 새로운 .NET/C# 기능을 활용합니다. .NET 7 이전 버전에서 예제를 사용하는 경우 약간의 수정이 필요합니다. 그러나 ME-ID 및 Microsoft Graph와 상호 작용하는 것과 관련된 텍스트 및 코드 예제는 모든 버전의 ASP.NET Core에서 동일합니다.
전제 조건
이 문서의 지침은 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 독립 실행형 앱 보안을 참조하세요.
범위
Microsoft Graph API에 사용자 프로필, 역할 할당 및 그룹 멤버 자격 데이터에 대한 호출을 허용하려면 다음을 수행합니다.
- 클라이언트 앱은 Azure Portal에서 위임된
User.Read
범위(https://graph.microsoft.com/User.Read
)로 구성됩니다. 사용자 데이터를 읽는 액세스 권한은 개별 사용자에게 부여(위임된) 범위에 따라 결정되기 때문입니다. - 서버 앱은 Azure Portal의 애플리케이션
GroupMember.Read.All
범위(https://graph.microsoft.com/GroupMember.Read.All
)로 구성됩니다. 액세스는 앱이 그룹 구성원에 대한 데이터에 액세스하기 위한 개별 사용자 권한 부여를 기반으로 하지 않고 그룹 멤버 자격에 대한 정보를 가져오는 데 사용되므로 구성됩니다.
앞의 범위는 앞서 나열된 문서(Microsoft 계정으로 독립 실행형, ME-ID가 있는 독립 실행형 및 ME-ID로 호스트됨)에 설명된 ME-ID 배포 시나리오에 필요한 범위 외에 필요합니다.
자세한 내용은 Microsoft 플랫폼의 사용 권한 및 동의 개요 및 Microsoft identity Graph 권한 개요를 참조하세요.
사용 권한 및 범위는 동일한 것을 의미하며 보안 설명서 및 Azure Portal에서 서로 바꿔서 사용됩니다. 텍스트가 Azure Portal을 참조하지 않는 한 이 문서에서는 Graph 권한을 참조할 때 범위/범위를 사용합니다.
범위는 대/소문자를 구분하지 않으므로 User.Read
user.read
. 두 형식 중 하나를 자유롭게 사용할 수 있지만 애플리케이션 코드에서 일관된 선택을 하는 것이 좋습니다.
그룹 멤버 자격 클레임 특성
Azure Portal에서 CLIENT 및 SERVER 앱의 앱 매니페스트에서 groupMembershipClaims
특성을 DirectoryRole
로 설정합니다. ME-ID의 DirectoryRole
값은 잘 알려진 ID 클레임(wids
)에서 로그인한 사용자의 모든 역할을 전송합니다.
- 앱의 Azure Portal 등록을 엽니다.
- 사이드바에서 관리>매니페스트를 선택합니다.
groupMembershipClaims
특성을 찾습니다.- 값을
DirectoryRole
("groupMembershipClaims": "DirectoryRole"
)로 설정합니다. - 변경한 경우 저장 단추를 선택합니다.
Azure Portal에서 CLIENT 및 SERVER 앱의 앱 매니페스트에서 groupMembershipClaims
특성을 All
로 설정합니다. ME-ID가 All
잘 알려진 ID 클레임(wids
)에서 로그인한 사용자의 모든 보안 그룹, 메일 그룹 및 역할을 보내는 결과 값입니다.
- 앱의 Azure Portal 등록을 엽니다.
- 사이드바에서 관리>매니페스트를 선택합니다.
groupMembershipClaims
특성을 찾습니다.- 값을
All
("groupMembershipClaims": "All"
)로 설정합니다. - 변경한 경우 저장 단추를 선택합니다.
사용자 지정 사용자 계정
Azure Portal에서 ME-ID 보안 그룹 및 ME-ID 관리자 역할에 사용자를 할당합니다.
이 문서의 예제는 다음과 같습니다.
- 서버 API 데이터에 액세스하기 위한 권한 부여를 위해 사용자가 Azure Portal ME-ID 테넌트에서 ME-ID 청구 관리자 역할에 할당된다고 가정합니다.
- 권한 부여 정책을 사용하여 CLIENT 및 SERVER 앱 내의 액세스를 제어합니다.
CLIENT 앱에서 RemoteUserAccount를 확장하여 다음 속성을 포함합니다.
Roles
: ME-ID 앱 역할 배열(앱 역할 섹션에서 설명)Wids
: 잘 알려진 ID 클레임의 ME-ID 관리자 역할(wids
)Oid
: 변경할 수 없는 개체 식별자 클레임()(oid
테넌트 내 및 테넌트 전체에서 사용자를 고유하게 식별)
CustomUserAccount.cs
:
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
namespace BlazorSample;
public class CustomUserAccount : RemoteUserAccount
{
[JsonPropertyName("roles")]
public List<string>? Roles { get; set; }
[JsonPropertyName("wids")]
public List<string>? Wids { get; set; }
[JsonPropertyName("oid")]
public string? Oid { get; set; }
}
Microsoft.Graph
용 CLIENT 앱에 패키지 참조를 추가합니다.
참고 항목
.NET 앱에 패키지를 추가하는 방법에 대한 지침은 패키지 사용 워크플로에서 패키지 설치 및 관리의 문서(NuGet 설명서)를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.
ASP.NET Core Blazor WebAssembly에서 Graph API 사용 문서의 Graph SDK 지침에서 Graph SDK 유틸리티 클래스 및 구성을 추가합니다. 문서의 예제 wwwroot/appsettings.json
파일에 표시된 대로 액세스 토큰의 User.Read
범위를 지정합니다.
CLIENT 앱에 다음 사용자 지정 사용자 계정 팩터리를 추가합니다. 사용자 지정 사용자 팩터리는 다음을 설정하는 데 사용됩니다.
- 앱 역할 클레임(
appRole
)(앱 역할 섹션에서 설명). - ME-ID 관리자 역할 클레임(
directoryRole
). - 사용자의 휴대폰 번호(
mobilePhone
) 및 사무실 위치(officeLocation
)에 대한 사용자 프로필 데이터 클레임 예제. - 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 BlazorSample;
public class CustomAccountFactory()
: AccountClaimsPrincipalFactory<CustomUserAccount>
{
private readonly ILogger<CustomAccountFactory> logger;
private readonly IServiceProvider serviceProvider;
private readonly string? baseUrl =
string.Join("/",
config.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
config.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider,
ILogger<CustomAccountFactory> logger)
: base(accessor)
{
this.serviceProvider = serviceProvider;
this.logger = logger;
}
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?.Roles?.ForEach((role) =>
{
userIdentity.AddClaim(new Claim("appRole", role));
});
account?.Wids?.ForEach((wid) =>
{
userIdentity.AddClaim(new Claim("directoryRole", wid));
});
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 requestMemberOf = client.Users[account?.Oid].MemberOf;
var graphGroups = await requestMemberOf.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;
}
}
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;
namespace BlazorSample;
public class CustomAccountFactory()
: AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
private readonly ILogger<CustomAccountFactory> logger;
private readonly IServiceProvider serviceProvider;
public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider,
ILogger<CustomAccountFactory> logger)
: base(accessor)
{
this.serviceProvider = serviceProvider;
this.logger = logger;
}
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)
{
account?.Roles?.ForEach((role) =>
{
userIdentity.AddClaim(new Claim("appRole", role));
});
account?.Wids?.ForEach((wid) =>
{
userIdentity.AddClaim(new Claim("directoryRole", wid));
});
try
{
var client = ActivatorUtilities
.CreateInstance<GraphServiceClient>(serviceProvider);
var request = client.Me.Request();
var user = await request.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 requestMemberOf = client.Users[account?.Oid].MemberOf;
var memberships = await requestMemberOf.Request().GetAsync();
if (memberships is not null)
{
foreach (var entry in memberships)
{
if (entry.ODataType == "#microsoft.graph.group")
{
userIdentity.AddClaim(
new Claim("directoryGroup", entry.Id));
}
}
}
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
return initialUser;
}
}
위의 코드에는 전이적 멤버 자격이 포함되어 있지 않습니다. 앱에 직접 및 전이적 그룹 멤버 자격 클레임이 필요한 경우 MemberOf
속성(IUserMemberOfCollectionWithReferencesRequestBuilder
)을 TransitiveMemberOf
(IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder
)로 바꿉니다.
이전 코드는 ME-ID에서 반환된 GUID 값이 역할 템플릿 ID가 아닌 관리자 역할 엔터티 ID이기 때문에 ME-ID 관리자 역할(형식)인 그룹 멤버 자격 클레임groups
(#microsoft.graph.directoryRole
)을 무시합니다. 엔터티 ID는 테넌트 전체에서 안정적이지 않으며 앱에서 사용자에 대한 권한 부여 정책을 만드는 데 사용하면 안 됩니다. 클레임에서 제공하는 ME-ID 관리자 역할에는 항상 템플릿 ID를 wids
사용합니다.
wids
테넌트 비 게스트 계정에 대한 값 b79fbf4d-3ef9-4689-8143-76b194e85509
이 있는 클레임(따라서 directoryRole
클레임)이 있습니다. ME-ID 관리자 역할 템플릿 ID를 참조하지 않습니다.
CLIENT 앱에서 사용자 지정 사용자 계정 팩터리를 사용하도록 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);
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
CustomAccountFactory>();
ASP.NET Core Blazor WebAssembly로 Graph API 사용 문서에 설명된 Graph SDK 코드가 있는지 확인하고 Graph SDK 지침에 따라 wwwroot/appsettings.json
구성이 올바른지 확인합니다.
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);
wwwroot/appsettings.json
:
{
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com",
"Version": "v1.0",
"Scopes": [
"user.read"
]
}
}
권한 부여 구성
클라이언트 앱에서 파일의 각 앱 역할, ME-ID 관리자 역할 또는 보안 그룹에 Program
대한 정책을 만듭니다. 다음 예제에서는 ME-ID 기본 제공 청구 관리자 역할에 대한 정책을 만듭니다.
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("BillingAdministrator", policy =>
policy.RequireClaim("directoryRole",
"b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});
ME-ID 관리자 역할에 대한 ID의 전체 목록은 Entra 설명서의 역할 템플릿 ID를 참조하세요. 권한 부여 정책에 대한 자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.
다음 예제에서 CLIENT 앱은 앞의 정책을 사용하여 사용자에게 권한을 부여합니다.
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의 앱 매니페스트 요소에 appRoles
설정된 앱 역할 및 정책에 사용되는 GUID가 Azure Portal 그룹 창의 그룹 개체 ID 와 일치하는 보안 그룹에 대한 정책 기반 액세스를 만들 수도 있습니다.
서버 API/웹 API 액세스 권한 부여
서버 API 앱은 액세스 토큰wids
groups
에 포함되는 경우 보안 그룹, ME-ID 관리자 역할 및 앱 역할에 대한 권한 부여 정책을 사용하여 보안 API 엔드포인트에 액세스하도록 사용자에게 권한을 부여할 수 있습니다role
. 다음 예제에서는 (잘 알려진 ID/역할 템플릿 ID) 클레임을 사용하여 파일에 ME-ID 청구 관리자 역할에 Program
대한 정책을 만듭니다.wids
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("BillingAdministrator", policy =>
policy.RequireClaim("wids", "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});
ME-ID 관리자 역할에 대한 ID의 전체 목록은 Azure 설명서의 역할 템플릿 ID를 참조하세요. 권한 부여 정책에 대한 자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.
SERVER 앱의 컨트롤러에 대한 액세스는 정책 이름과 함께 [Authorize]
특성 사용을 기반으로 할 수 있습니다(API 설명서: AuthorizeAttribute).
다음 예제는 정책 이름 BillingAdministrator
를 사용하여 BillingDataController
의 청구 데이터에 대한 액세스를 Azure 대금 청구 관리자로 제한합니다.
using Microsoft.AspNetCore.Authorization;
[Authorize(Policy = "BillingAdministrator")]
[ApiController]
[Route("[controller]")]
public class BillingDataController : ControllerBase
{
...
}
자세한 내용은 ASP.NET Core의 정책 기반 권한 부여를 참조하세요.
앱 역할
앱 역할 멤버 자격 클레임을 제공하도록 Azure Portal에서 앱을 구성하려면 애플리케이션에 앱 역할 추가를 참조 하고 Entra 설명서의 토큰 에서 해당 역할을 받습니다.
다음 예제에서는 CLIENT 및 SERVER 앱이 두 개의 역할로 구성되고 이 역할이 테스트 사용자에게 할당된다고 가정합니다.
Admin
Developer
참고 항목
호스트된 Blazor WebAssembly 앱 또는 독립 실행형 앱의 클라이언트-서버 쌍(독립 실행형 Blazor WebAssembly 앱 및 ASP.NET Core 서버 API/웹 API 앱)을 개발하는 경우 클라이언트 및 서버 Azure Portal 앱 등록 appRoles
매니페스트 속성은 구성된 동일한 역할을 포함해야 합니다. 클라이언트 앱의 매니페스트에 역할을 설정한 후 역할 전체를 서버 앱의 매니페스트에 복사합니다. 클라이언트와 서버 앱 등록 간에 매니페스트 appRoles
를 미러링하지 않으면 액세스 토큰에 역할 클레임에 올바른 항목이 있더라도 서버 API/웹 API의 인증된 사용자에 대해 역할 클레임이 설정되지 않습니다.
Microsoft Entra ID Premium 계정이 없는 그룹에 역할을 할당할 수는 없지만 사용자에게 역할을 할당하고 표준 Azure 계정을 사용하는 사용자에 대한 역할 클레임을 받을 수 있습니다. 이 섹션의 지침에는 ME-ID Premium 계정이 필요하지 않습니다.
기본 디렉터리로 작업할 때 애플리케이션에 앱 역할 추가의 지침을 따르고 토큰 에서 수신하여 역할을 구성하고 할당합니다. 기본 디렉터리로 작업하지 않는 경우 Azure Portal에서 앱의 매니페스트를 편집하여 매니페스트 파일 항목에서 appRoles
수동으로 앱의 역할을 설정합니다. 다음은 Admin
및 Developer
역할을 만드는 예제 appRoles
항목입니다. 이러한 예제 역할은 구성 요소 수준에서 이 섹션의 예제 뒷부분에서 액세스 제한을 구현하는 데 사용됩니다.
"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 계정이 있는 경우, 그룹)에 역할을 할당하려면 다음을 수행합니다.
- Azure Portal의 ME-ID 영역에서 엔터프라이즈 애플리케이션으로 이동합니다.
- app을 선택합니다. 사이드바에서관리>사용자 및 그룹을 선택합니다.
- 하나 이상의 사용자 계정에 대한 확인란을 선택합니다.
- 사용자 목록 위의 메뉴에서 할당 편집을 선택합니다.
- 역할 선택 항목에서 선택한 항목 없음을 선택합니다.
- 목록에서 역할을 선택하고 선택 단추를 사용하여 선택합니다.
- 화면 아래쪽에 있는 할당 단추를 사용하여 역할을 할당합니다.
Azure Portal에서 각 추가 역할 할당에 대해 ‘사용자를 다시 추가’함으로써 여러 역할이 할당됩니다. 사용자 목록 맨 위에 있는 사용자/그룹 추가 단추를 사용하여 사용자를 다시 추가합니다. 이전 단계를 사용하여 사용자에게 다른 역할을 할당합니다. 사용자(또는 그룹)에 역할을 추가하는 데 필요한 횟수만큼 이 프로세스를 반복할 수 있습니다.
사용자 지정 사용자 계정 섹션에 표시된 CustomAccountFactory
는 JSON 배열 값을 사용하여 role
클레임에 대해 작동하도록 설정됩니다. 사용자 지정 사용자 계정 섹션에 표시된 대로 CLIENT 앱에 CustomAccountFactory
를 추가하고 등록합니다. 원래 role
클레임은 프레임워크에 의해 자동으로 제거되므로 이를 제거하는 코드를 제공할 필요는 없습니다.
Program
클라이언트 앱 파일에서 "appRole
"라는 클레임을 검사에 대한 ClaimsPrincipal.IsInRole 역할 클레임으로 지정합니다.
builder.Services.AddMsalAuthentication(options =>
{
...
options.UserOptions.RoleClaim = "appRole";
});
참고 항목
directoryRoles
클레임(ADD 관리자 역할)을 사용하려면 RemoteAuthenticationUserOptions.RoleClaim에 "directoryRoles
"를 할당합니다.
Program
서버 앱 파일에서 "http://schemas.microsoft.com/ws/2008/06/identity/claims/role
"라는 클레임을 검사에 대한 ClaimsPrincipal.IsInRole 역할 클레임으로 지정합니다.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
Configuration.Bind("AzureAd", options);
options.TokenValidationParameters.RoleClaimType =
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
},
options => { Configuration.Bind("AzureAd", options); });
참고 항목
단일 인증 체계가 등록되면 인증 체계가 앱의 기본 체계로 자동으로 사용되며 구성표를 AddAuthentication 또는 AuthenticationOptions을 통해 지정할 필요가 없습니다. 자세한 내용은 ASP.NET Core 인증 개요 및 ASP.NET Core 알림(aspnet/Announcements #490)을 참조하세요.
참고 항목
wids
클레임(ADD 관리자 역할)을 사용하려면 TokenValidationParameters.RoleClaimType에 "wids
"를 할당합니다.
이전 단계를 완료하여 사용자(또는 프리미엄 계층 Azure 계정이 있는 경우, 그룹)에 역할을 만들고 할당하고 이 문서의 앞부분과 ASP.NET Core Blazor WebAssembly로 Graph API 사용에서 설명한 대로 Graph SDK를 사용하여 CustomAccountFactory
을 구현한 후에는 로그인한 사용자에게 할당된 각 역할(또는 구성원이 속한 그룹에 할당된 역할)에 대한 appRole
클레임이 표시됩니다. 테스트 사용자와 함께 앱을 실행하여 클레임이 예상대로 존재하는지 확인합니다. Graph SDK를 로컬로 테스트할 때 느린 쿠키가 테스트를 방해하지 않도록 각 테스트에 대해 새 프라이빗/시크릿 브라우저 세션을 사용하는 것이 좋습니다. 자세한 내용은 Microsoft Entra ID를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보안을 참조하세요.
이 시점에서는 구성 요소 권한 부여 방식이 작동합니다. CLIENT 앱의 구성 요소에 있는 권한 부여 메커니즘은 Admin
역할을 사용하여 사용자에게 권한을 부여할 수 있습니다.
-
<AuthorizeView Roles="Admin">
[Authorize]
특성 지시문(AuthorizeAttribute)@attribute [Authorize(Roles = "Admin")]
-
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var user = authState.User; if (user.IsInRole("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"))
SERVER 앱의 구성 요소에 있는 권한 부여 메커니즘은 Admin
역할을 사용하여 사용자에게 권한을 부여할 수 있습니다.
[Authorize]
특성 지시문(AuthorizeAttribute)[Authorize(Roles = "Admin")]
-
if (User.IsInRole("Admin")) { ... }
여러 역할 테스트가 지원됩니다.
사용자는
[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 앱에서 비정상적인 역할 이름 형식이지만 유효합니다.
추가 리소스
ASP.NET Core