다음을 통해 공유


Azure App Service 인증에서 사용자 ID 사용

이 문서에서는 Azure App Service 에서 기본 제공 인증 및 권한 부여 를 사용할 때 사용자 ID를 사용하는 방법을 보여줍니다.

필수 조건

App Service 인증/권한 부여 모듈을 사용하도록 설정된 Azure App Service에서 실행되는 웹 애플리케이션

앱 코드에서 사용자 클레임에 액세스

앱의 인증된 최종 사용자 또는 클라이언트 애플리케이션은 들어오는 토큰에서 클레임을 만듭니다. App Service는 요청 헤더에 클레임을 삽입함으로써 코드에서 이를 사용할 수 있도록 합니다. 외부 요청은 이러한 헤더를 설정할 수 없으므로 App Service에서 설정한 경우에만 표시됩니다.

App Service 인증에서 제공하는 클레임 정보를 사용하여 앱 코드에서 권한 부여 검사를 수행할 수 있습니다. 모든 언어 또는 프레임워크의 코드는 요청 헤더에서 필요한 정보를 가져올 수 있습니다. 일부 코드 프레임워크는 더 편리할 수 있는 추가 옵션을 제공합니다. 프레임워크별 대안을 참조하세요.

다음 표에서는 몇 가지 예제 헤더에 대해 설명합니다.

헤더 설명
X-MS-CLIENT-PRINCIPAL 사용 가능한 클레임의 Base64로 인코딩된 JSON 표현입니다. 더 많은 정보를 원하시면 클라이언트 주요 헤더 디코딩를 참조하세요.
X-MS-CLIENT-PRINCIPAL-ID ID 공급자가 호출자에 대해 설정하는 식별자입니다.
X-MS-CLIENT-PRINCIPAL-NAME ID 공급자가 전자 메일 주소 또는 사용자 계정 이름과 같이 호출자에 대해 설정하는 사람이 읽을 수 있는 이름입니다.
X-MS-CLIENT-PRINCIPAL-IDP App Service 인증에서 사용하는 ID 공급자의 이름입니다.

유사한 헤더는 공급자 토큰을 노출합니다. 예를 들어, Microsoft Entra는 적절하게 X-MS-TOKEN-AAD-ACCESS-TOKENX-MS-TOKEN-AAD-ID-TOKEN 공급자 토큰 헤더를 설정합니다.

참고

App Service는 모든 언어 프레임워크에서 요청 헤더를 사용할 수 있도록 합니다. 다른 언어 프레임워크는 이러한 헤더를 앱 코드에 소문자로 표시하거나 단어의 첫 글자를 대문자로 표시하는 것과 같이 다양한 형식을 사용할 수 있습니다.

클라이언트 프린시펄 헤더를 디코딩하기

헤더에는 X-MS-CLIENT-PRINCIPAL Base64로 인코딩된 JSON에서 사용 가능한 클레임의 전체 집합이 포함됩니다. 이 헤더를 처리하려면 앱이 페이로드를 디코딩하고 배열을 claims 반복하여 관련 클레임을 찾아야 합니다.

참고

이러한 클레임은 기본 클레임 매핑 프로세스를 거치므로 일부 이름은 토큰에 표시되는 것과 다를 수 있습니다.

디코딩된 페이로드 구조는 다음과 같습니다.

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}

다음 표에서는 속성에 대해 설명합니다.

속성 유형 설명
auth_typ string App Service 인증에서 사용하는 ID 공급자의 이름입니다.
claims array 사용 가능한 클레임을 나타내는 개체의 배열입니다. 각 개체에는 typval 속성이 포함됩니다.
typ string 기본 클레임 매핑이 적용되고 토큰의 해당 클레임과 다를 수 있는 클레임의 이름입니다.
val string 클레임의 값입니다.
name_typ string 이름 클레임 유형은 일반적으로 URI 형식으로, 클레임이 정의된 경우 name 클레임에 대한 체계 정보를 제공합니다.
role_typ string 일반적으로 역할 클레임 유형은 클레임이 정의된 경우 role 클레임에 대한 체계 정보를 제공하는 URI입니다.

편의를 위해 클레임을 앱의 언어 프레임워크에서 사용하는 표현으로 변환할 수 있습니다. 다음 C# 예제에서는 앱에서 ClaimsPrincipal 사용할 형식을 생성합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;

public static class ClaimsPrincipalParser
{
    private class ClientPrincipalClaim
    {
        [JsonPropertyName("typ")]
        public string Type { get; set; }
        [JsonPropertyName("val")]
        public string Value { get; set; }
    }

    private class ClientPrincipal
    {
        [JsonPropertyName("auth_typ")]
        public string IdentityProvider { get; set; }
        [JsonPropertyName("name_typ")]
        public string NameClaimType { get; set; }
        [JsonPropertyName("role_typ")]
        public string RoleClaimType { get; set; }
        [JsonPropertyName("claims")]
        public IEnumerable<ClientPrincipalClaim> Claims { get; set; }
    }

    public static ClaimsPrincipal Parse(HttpRequest req)
    {
        var principal = new ClientPrincipal();

        if (req.Headers.TryGetValue("x-ms-client-principal", out var header))
        {
            var data = header[0];
            var decoded = Convert.FromBase64String(data);
            var json = Encoding.UTF8.GetString(decoded);
            principal = JsonSerializer.Deserialize<ClientPrincipal>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }

이 시점에서 코드는 유효성 검사의 일부로 클레임을 확인하기 위해 principal.Claims를 통해 반복할 수 있습니다. 또는 principal.Claims를 표준 개체로 변환하여 요청 파이프라인의 나중 단계에서 관련 검사를 수행하는 데 사용할 수 있습니다. 해당 개체를 사용하여 사용자 데이터와 다른 용도로 연결할 수도 있습니다.

나머지 함수는 이 변환을 수행하여 다른 .NET 코드에서 사용할 수 있는 ClaimsPrincipal를 만듭니다.

        var identity = new ClaimsIdentity(principal.IdentityProvider, principal.NameClaimType, principal.RoleClaimType);
        identity.AddClaims(principal.Claims.Select(c => new Claim(c.Type, c.Value)));
        
        return new ClaimsPrincipal(identity);
    }
}

프레임워크별 대안

참고

클레임 매핑이 작동하려면 앱에 토큰 저장소 를 사용하도록 설정해야 합니다.

API를 사용하여 사용자 클레임에 액세스

앱에 토큰 저장소 를 사용하도록 설정한 경우 인증된 사용자에 대한 다른 세부 정보를 얻기 위해 호출 /.auth/me 할 수도 있습니다.