다음을 통해 공유


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

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

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

모든 언어 프레임워크의 경우 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도 적절하게 설정합니다.

참고

다른 언어 프레임워크는 이러한 헤더를 소문자 또는 타이틀 사례 사용과 같이 다양한 형식으로 앱 코드에 표시할 수 있습니다.

모든 언어로 작성된 코드 또는 프레임워크는 이러한 헤더에서 필요한 정보를 가져올 수 있습니다. 클라이언트 보안 주체 헤더 디코딩에서 이 프로세스를 다룹니다. 일부 프레임워크의 경우 플랫폼은 더 편리할 수 있는 추가 옵션도 제공합니다.

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

X-MS-CLIENT-PRINCIPAL 에는 Base64로 인코딩된 JSON으로 사용 가능한 클레임의 전체 집합이 포함되어 있습니다. 이러한 클레임은 기본 클레임 매핑 프로세스를 거치므로 토큰을 직접 처리한 경우와 이름이 다를 수 있습니다.

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

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

이 헤더를 처리하려면 앱이 페이로드를 디코딩하고 배열을 claims 반복하여 관련 클레임을 찾아야 합니다. 클레임을 앱의 언어 프레임워크에서 사용하는 표현으로 변환하는 것이 편리할 수 있습니다. 다음은 앱에서 사용할 형식을 생성하는 ClaimsPrincipal C#의 이 프로세스 예제입니다.

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

        /** 
         *  At this point, the code can iterate through `principal.Claims` to
         *  check claims as part of validation. Alternatively, you can convert
         *  it into a standard object with which to perform those checks later
         *  in the request pipeline. That object can also be leveraged for 
         *  associating user data, and so on. The rest of this function performs such
         *  a conversion to create a `ClaimsPrincipal` as might be used in 
         *  other .NET code.
         */

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

프레임워크별 대안

ASP.NET 4.6 앱의 경우 App Service는 ClaimsPrincipal.Current 인증된 사용자의 클레임으로 채웁니다. [Authorize] 특성을 포함하여 표준 .NET 코드 패턴을 따를 수 있습니다. 마찬가지로 PHP 앱의 경우, App Service는 _SERVER['REMOTE_USER'] 변수를 채웁니다. Java 앱의 경우 Tomcat 서블릿에서 클레임에 액세스할 수 있습니다.

Azure Functions의 경우, .NET 코드를 위해 ClaimsPrincipal.Current가 채워지지 않지만, 요청 헤더에서 사용자 클레임을 찾거나 요청 컨텍스트에서 또는 바인딩 매개 변수를 통해 ClaimsPrincipal 개체를 가져올 수 있습니다. 자세한 내용은 Azure Functions의 클라이언트 ID 작업을 참조하세요.

.NET Core Microsoft.Identity.Web 의 경우 App Service 인증을 사용하여 현재 사용자 채우기를 지원합니다. 자세한 내용은 Microsoft.Identity.Web wiki를 검토하거나 이 자습서에서 Microsoft Graph에 액세스하는 웹앱에 대해 설명한 내용을 확인하세요.

참고

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

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

앱에서 토큰 저장소를 사용하도록 설정한 경우 /.auth/me를 호출하여 인증된 사용자에 관한 다른 세부 정보를 가져올 수도 있습니다.