Microsoft. Identity.Web은 ASP.NET Core, OWIN 또는 .NET 애플리케이션에서 Microsoft Graph, Azure 서비스 및 사용자 지정 REST API를 포함하여 다운스트림 API를 호출하는 여러 방법을 제공합니다. 이 문서는 시나리오에 적합한 방법을 선택하고 빠르게 시작하는 데 도움이 됩니다.
접근 방식 선택
이 의사 결정 트리를 사용하여 시나리오에 가장 적합한 방법을 선택합니다.
| API 유형/시나리오 | 의사 결정/조건 | 권장 클라이언트/클래스 |
|---|---|---|
| Microsoft Graph | Microsoft Graph API를 호출해야 합니다. | GraphServiceClient |
| Azure SDK(스토리지, KeyVault 등) | Azure API(Azure SDK)를 호출해야 합니다. | Azure SDK 클라이언트를 사용하는 MicrosoftIdentityTokenCredential |
| 토큰 바인딩을 사용하는 사용자 지정 API | 인증서 바인딩을 사용하여 보안 강화(mTLS PoP) | IDownstreamApi와 ProtocolScheme: "MTLS_POP" |
| 토큰 바인딩을 사용하는 사용자 지정 API | HttpClient 통합을 통한 보안 강화(mTLS PoP) | MicrosoftIdentityMessageHandler ProtocolScheme: "MTLS_POP" |
| 사용자 지정 API | 간단하고 구성 가능 | IDownstreamApi |
| 사용자 지정 API | HttpClient + 위임 처리기 사용 | MicrosoftIdentityMessageHandler |
| 사용자 지정 API | HttpClient 사용하기 | IAuthorizationHeaderProvider |
복잡성 및 유연성별 접근 방식 비교
다음 표에는 의도한 사용 사례, 복잡성 수준 및 유연성별로 각 접근 방식이 요약되어 있습니다.
| 접근법 | 적합한 대상 | 복잡성 | Configuration | 유연성 |
|---|---|---|---|---|
| GraphServiceClient | Microsoft Graph API | Low | Simple | 중간 |
| MicrosoftIdentityTokenCredential | Azure SDK 클라이언트 | Low | Simple | Low |
| IDownstreamApi | 표준 패턴이 있는 REST API | Low | JSON + 코드 | 중간 |
| MicrosoftIdentityMessageHandler | 인증 파이프라인이 있는 HttpClient | 중간 | 코드 | 높음 |
| IAuthorizationHeaderProvider | 사용자 지정 인증 논리 | 높음 | 코드 | 매우 높음 |
토큰 획득 패턴
Microsoft. Identity.Web은 세 가지 기본 토큰 획득 패턴을 지원합니다.
graph LR
A[Token Acquisition] --> B[Delegated<br/>On behalf of user]
A --> C[App-Only<br/>Application permissions in all apps]
A --> D[On-Behalf-Of OBO<br/>in web API]
B --> B1[Web Apps]
B --> B2[Daemon acting as user / user agent]
C --> C1[Daemon Apps]
C --> C2[Web APIs with app permissions]
D --> D1[Web APIs calling other APIs]
style B fill:#cfe2ff
style C fill:#fff3cd
style D fill:#f8d7da
위임된 권한(사용자 토큰)
애플리케이션이 로그인한 사용자를 대신하여 작동할 때 위임된 권한을 사용합니다.
- 시나리오: 웹앱은 로그인한 사용자 및 자율 에이전트 사용자 ID를 대신하여 API를 호출합니다.
- 토큰 유형: 위임된 권한이 있는 액세스 토큰
-
메서드:
CreateAuthorizationHeaderForUserAsync()GetForUserAsync()
애플리케이션 권한(앱 전용 토큰)
사용자가 없고 앱이 자체 인증하는 경우 애플리케이션 권한을 사용합니다.
- 시나리오: 디먼 앱 또는 백그라운드 서비스가 API를 호출합니다. 자율 에이전트 신원
- 토큰 유형: 애플리케이션 권한이 있는 액세스 토큰
-
메서드:
CreateAuthorizationHeaderForAppAsync()GetForAppAsync()
OBO(On-Behalf-Of) 흐름
사용자의 ID를 유지하면서 웹 API가 다른 다운스트림 API를 호출해야 하는 경우 OBO 흐름을 사용합니다.
- 시나리오: Web API는 사용자 토큰을 수신하고 해당 사용자 및 대화형 에이전트를 대신하여 다른 API를 호출합니다.
- 토큰 유형: OBO 흐름을 통한 새 액세스 토큰
-
메서드:
CreateAuthorizationHeaderForUserAsync()웹 API 컨텍스트에서
토큰 바인딩(mTLS PoP)
토큰 바인딩은 X.509 인증서에 액세스 토큰을 암호화하여 추가 보안 계층을 추가합니다.
- 시나리오: RFC 8705에 따라 토큰이 인증서에 암호화적으로 바인딩되는 보안 강화
-
토큰 유형: 인증서 바인딩을 사용하여 액세스 토큰(
cnf클레임) -
메서드:
GetForAppAsync()ProtocolScheme: "MTLS_POP"와 함께 - 보안: 특정 인증서에 토큰을 바인딩하여 토큰 도난 방지
mTLS PoP를 사용하여 토큰 바인딩에 대해 자세히 알아보기
빠른 시작 코드 예제
다음 예제에서는 애플리케이션에 적응할 수 있는 엔드 투 엔드 코드를 사용하여 각 방법을 보여 줍니다.
Microsoft Graph(Graph API에 권장)
다음 예제에서는 GraphServiceClient 등록하고 로그인한 사용자를 대신하여 앱 전용 호출로 Microsoft Graph 호출하는 데 사용합니다.
// Installation
// dotnet add package Microsoft.Identity.Web.GraphServiceClient
// Startup configuration
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftGraph();
// Usage in controller
public class HomeController : Controller
{
private readonly GraphServiceClient _graphClient;
public HomeController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Profile()
{
// Delegated - calls on behalf of signed-in user
var user = await _graphClient.Me.GetAsync();
// App-only - requires app permissions
var users = await _graphClient.Users
.GetAsync(r => r.Options.WithAppOnly());
return View(user);
}
}
Microsoft Graph 통합에 대해 자세히 알아보세요
GraphServiceClient 마이그레이션 및 자세한 사용
Azure SDK(Azure 서비스에 권장)
다음 예제에서는 MicrosoftIdentityTokenCredential 등록하고 Azure Blob Storage 클라이언트에 전달합니다.
// Installation
// dotnet add package Microsoft.Identity.Web.Azure
// dotnet add package Azure.Storage.Blobs
// Startup configuration
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityAzureTokenCredential();
// Usage
public class StorageService
{
private readonly MicrosoftIdentityTokenCredential _credential;
public StorageService(MicrosoftIdentityTokenCredential credential)
{
_credential = credential;
}
public async Task<List<string>> ListBlobsAsync()
{
var blobClient = new BlobServiceClient(
new Uri("https://myaccount.blob.core.windows.net"),
_credential);
var container = blobClient.GetBlobContainerClient("mycontainer");
var blobs = new List<string>();
await foreach (var blob in container.GetBlobsAsync())
{
blobs.Add(blob.Name);
}
return blobs;
}
}
IDownstreamApi(사용자 지정 REST API에 권장)
다음 예제에서는 명명된 다운스트림 API를 appsettings.json 구성하고 위임된 토큰과 앱 전용 토큰을 모두 사용하여 호출합니다.
// Installation
// dotnet add package Microsoft.Identity.Web.DownstreamApi
// appsettings.json
{
"DownstreamApis": {
"MyApi": {
"BaseUrl": "https://myapi.example.com",
"Scopes": ["api://myapi/read", "api://myapi/write"]
}
}
}
// Startup configuration
using Microsoft.Identity.Web;
builder.Services.AddDownstreamApis(
builder.Configuration.GetSection("DownstreamApis"));
// Usage
public class ApiService
{
private readonly IDownstreamApi _api;
public ApiService(IDownstreamApi api)
{
_api = api;
}
public async Task<Product> GetProductAsync(int id)
{
// Delegated - on behalf of user
return await _api.GetForUserAsync<Product>(
"MyApi",
$"api/products/{id}"
);
}
public async Task<List<Product>> GetAllProductsAsync()
{
// App-only - using app permissions
return await _api.GetForAppAsync<List<Product>>(
"MyApi",
"api/products");
}
}
mTLS PoP를 사용하여 토큰 바인딩(보안 강화)
토큰 바인딩은 X.509 인증서에 액세스 토큰을 암호화적으로 바인딩하여 향상된 보안을 제공합니다. 토큰이 가로채더라도 해당 인증서 없이는 사용할 수 없습니다.
// Installation
// dotnet add package Microsoft.Identity.Web.DownstreamApi
// appsettings.json
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientCredentials": [
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=YourCertificate"
}
],
"SendX5c": true
},
"SecureApi": {
"BaseUrl": "https://api.contoso.com/",
"RelativePath": "api/data",
"ProtocolScheme": "MTLS_POP",
"RequestAppToken": true,
"Scopes": [ "api://your-api/.default" ]
}
}
// Startup configuration
builder.Services.AddDownstreamApi(
"SecureApi",
builder.Configuration.GetSection("SecureApi"));
// Usage
public class SecureApiService
{
private readonly IDownstreamApi _api;
public SecureApiService(IDownstreamApi api)
{
_api = api;
}
public async Task<SecureData> GetSecureDataAsync()
{
// Token is bound to certificate - enhanced security
return await _api.GetForAppAsync<SecureData>("SecureApi");
}
}
주요 이점:
- 토큰 도난 방지: 도난당한 토큰은 인증서 없이는 쓸모가 없습니다.
- 재생 공격 방지: 다른 클라이언트에서 토큰을 재생할 수 없습니다.
- 제로 트러스트 정렬: 클라이언트와 토큰 간의 강력한 암호화된 결합
MicrosoftIdentityMessageHandler(HttpClient 통합용)
다음 예제에서는 보내는 모든 요청에 권한 부여 헤더가 자동으로 포함되도록 위임 처리기를 HttpClient 추가합니다. 처리기는 시작 시 범위를 등록하고 개별 요청은 토큰 옵션을 재정의할 수 있습니다.
// Startup configuration
using Microsoft.Identity.Web;
builder.Services.AddHttpClient("MyApiClient", client =>
{
client.BaseAddress = new Uri("https://myapi.example.com");
})
.AddHttpMessageHandler(sp => new MicrosoftIdentityMessageHandler(
sp.GetRequiredService<IAuthorizationHeaderProvider>(),
new MicrosoftIdentityMessageHandlerOptions
{
Scopes = new[] { "api://myapi/.default" }
}));
// Usage
public class ApiService
{
private readonly HttpClient _httpClient;
public ApiService(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient("MyApiClient");
}
public async Task<Product> GetProductAsync(int id)
{
var request = new HttpRequestMessage(HttpMethod.Get, $"api/products/{id}")
.WithAuthenticationOptions(options =>
{
options.RequestAppToken = false; // Use delegated token
options.scopes = [ "myApi.scopes" ];
});
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<Product>();
}
}
MicrosoftIdentityMessageHandler에 대해 자세히 알아보기
IAuthorizationHeaderProvider(최대 유연성)
다음 예제에서는 사용자 지정 헤더와 함께 HTTP 요청에 연결할 수 있도록 권한 부여 헤더를 직접 검색합니다.
// Direct usage for custom scenarios
public class CustomAuthService
{
private readonly IAuthorizationHeaderProvider _headerProvider;
public CustomAuthService(IAuthorizationHeaderProvider headerProvider)
{
_headerProvider = headerProvider;
}
public async Task<string> CallApiAsync()
{
// Get auth header (includes "Bearer " + token)
string authHeader = await _headerProvider
.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "api://myapi/.default" });
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authHeader);
client.DefaultRequestHeaders.Add("X-Custom-Header", "MyValue");
var response = await client.GetStringAsync("https://myapi.example.com/data");
return response;
}
}
IAuthorizationHeaderProvider에 대해 자세히 알아보기
구성 패턴
Microsoft. Identity.Web은 JSON 구성과 코드 기반 구성을 모두 지원합니다.
appsettings.json 구성
다음 JSON은 Microsoft Entra ID 자격 증명과 두 개의 다운스트림 API를 등록하는 일반적인 구성을 보여 줍니다.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity"
}
]
},
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": ["User.Read", "Mail.Read"]
},
"MyApi": {
"BaseUrl": "https://myapi.example.com",
"Scopes": ["api://myapi/read"]
}
}
}
Note
디먼/콘솔 앱의 경우 속성을 설정합니다 appsettings.json . "출력 디렉터리에 복사" = "최신인 경우 복사"
코드 기반 구성
다음 예제와 같이 완전히 코드에서 자격 증명 및 다운스트림 API를 구성할 수도 있습니다.
// Explicit configuration in code
builder.Services.Configure<MicrosoftIdentityApplicationOptions>(options =>
{
options.Instance = "https://login.microsoftonline.com/";
options.TenantId = "your-tenant-id";
options.ClientId = "your-client-id";
options.ClientCredentials = new[]
{
CertificateDescription.FromKeyVault(
"https://myvault.vault.azure.net",
"MyCertificate")
};
});
builder.Services.AddDownstreamApi("MyApi", options =>
{
options.BaseUrl = "https://myapi.example.com";
options.Scopes = new[] { "api://myapi/read" };
});
시나리오별 가이드
가장 좋은 방법은 API를 호출하는 위치에 따라 달라집니다.
웹앱 통합
웹앱은 일반적으로 로그인한 사용자를 대신하여 다운스트림 API를 호출합니다.
- 기본 패턴: 위임된 권한(사용자 대신)
- 토큰 획득: 로그인하는 동안 자동으로 발생합니다.
- 특별 고려 사항: 증분 동의, 동의 실패 처리
Web API 통합
Web API는 On-Behalf-Of 흐름을 사용하여 들어오는 사용자 토큰을 다운스트림 API로 범위가 설정된 새 토큰으로 교환합니다.
- 기본 패턴: OBO(on-Behalf-Of) 흐름
- 토큰 획득: 들어오는 토큰을 다운스트림 토큰으로 교환
- 특별 고려 사항: 장기 실행 프로세스, 토큰 캐싱, 에이전트 ID.
디먼 앱 통합
디먼 앱은 로그인한 사용자 없이 스스로 인증합니다.
- 기본 패턴: 애플리케이션 권한(앱 전용)
- 토큰 획득: 클라이언트 자격 증명 흐름
- 특별 고려 사항: 사용자 컨텍스트 없음, 관리자 동의 필요
- 고급: 자율 에이전트, 에이전트 사용자 ID
토큰 획득에 대한 오류 처리
모든 토큰 획득 메서드는 애플리케이션에서 처리해야 하는 예외를 발생시킬 수 있습니다.
웹앱에서 [AuthorizeForScope(scopes)] 속성은 사용자 점진적 동의 또는 다시 인증을 처리합니다.
다음 예제에서는 일반적인 토큰 획득 예외를 catch하고 처리하는 방법을 보여 줍니다.
using Microsoft.Identity.Abstractions;
try
{
var result = await _api.GetForUserAsync<Data>("MyApi", "api/data");
}
catch (MicrosoftIdentityWebChallengeUserException ex)
{
// User needs to sign in or consent to additional scopes
// In web apps, this triggers a redirect to Microsoft Entra ID
throw;
}
catch (HttpRequestException ex)
{
// Downstream API returned error
_logger.LogError(ex, "API call failed");
}
일반적인 오류 시나리오
다음 표에서는 가장 일반적인 예외 및 해결 방법을 나열합니다.
| 예외 | Meaning | 해결 방법 |
|---|---|---|
MicrosoftIdentityWebChallengeUserException |
사용자 동의 필요 | Microsoft Entra ID로 동의를 위한 리디렉션하십시오. AuthorizeForScopes 특성 또는 ConsentHandler 클래스 사용 |
MsalUiRequiredException |
대화형 인증 필요 | 웹앱에서 챌린지를 처리하기 |
MsalServiceException |
Microsoft Entra ID 서비스 오류 | 구성 확인, 다시 시도 |
HttpRequestException |
다운스트림 API 오류 | API 관련 오류 처리 |
필요한 NuGet 패키지
시나리오와 일치하는 패키지를 선택합니다. 다음 표에는 각 패키지와 사용 시기가 나열되어 있습니다.
| Package | Purpose | 사용 시기 |
|---|---|---|
| Microsoft. Identity.Web.TokenAcquisition | 토큰 획득 서비스 | 핵심 패키지 |
| Microsoft. Identity.Web.DownstreamApi | IDownstreamApi 추상화 | REST API 호출 |
| Microsoft. Identity.Web.GraphServiceClient | Microsoft Graph 통합 | Microsoft Graph 호출(마이그레이션 가이드) |
| Microsoft. Identity.Web. Azure | Azure SDK 통합 | Azure 서비스 호출 |
| Microsoft. Identity.Web | 웹앱 및 웹 API ASP.NET Core | ASP.NET Core |
| Microsoft. Identity.Web.OWIN | OWIN 웹앱 및 웹 API ASP.NET | OWIN |
관련 콘텐츠
자세한 연습 및 고급 시나리오에 대한 가이드를 살펴보세요.