빠른 시작: ASP.NET Core Web API 보호

이 Quickstart에서는 Microsoft.Identity.Web을 사용하여 Microsoft Entra ID로 ASP.NET Core Web API를 보호합니다. 전달자 토큰의 유효성을 검사하고 권한 있는 호출자에 대한 액세스를 제한하는 인증 미들웨어를 추가합니다.

Azure 구독이 없는 경우, 시작하기 전에 무료 계정을 만드십시오.

사전 요구 사항

  • .NET 9 SDK
  • Microsoft Entra ID 테넌트입니다. 아직 없는 경우 무료 계정을 만들 수 있습니다.
  • API에 대한 앱 등록

옵션 1: 템플릿에서 만들기(가장 빠른)

기본 제공 Microsoft Entra 인증과 함께 ASP.NET Core 템플릿을 사용하여 보호된 API 프로젝트를 스캐폴드합니다.

1. 프로젝트 만들기

다음 명령을 실행하여 단일 조직 인증을 사용하여 새 웹 API 프로젝트를 만들고 프로젝트 디렉터리로 이동합니다.

dotnet new webapi --auth SingleOrg --name MyWebApi
cd MyWebApi

2. 앱 등록 구성

appsettings.json 플레이스홀더 값을 Microsoft Entra 앱 등록 세부 사항으로 바꾸십시오.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  }
}

3. API 실행

애플리케이션을 시작합니다.

dotnet run

이제 API가 https://localhost:5001에서 보호됩니다.

완료! 이제 요청에 유효한 액세스 토큰이 필요합니다.


옵션 2: 기존 Web API에 추가

ASP.NET Core Web API가 이미 있는 경우 다음 단계를 사용하여 Microsoft Entra 인증을 추가합니다.

1. NuGet 패키지 설치

프로젝트에 Microsoft.Identity.Web NuGet 패키지를 추가합니다.

dotnet add package Microsoft.Identity.Web

2. Program.cs에서 인증을 구성하세요.

앱의 시작 파이프라인에 인증 및 권한 부여 서비스를 등록합니다. 다음 코드는 Microsoft Entra 유효성 검사를 사용하여 JWT 전달자 인증을 구성합니다.

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");

// Add authorization
builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication(); //  Add authentication middleware
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 구성을 appsettings.json에 추가

테넌트 및 애플리케이션 세부 정보가 포함된 Microsoft Entra 구성 섹션을 추가합니다. Microsoft.Identity.Web 대한 로깅 수준을 Information 설정하여 토큰 유효성 검사 문제를 해결합니다.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "Information"
    }
  }
}

4. API 엔드포인트 보호

[Authorize] 특성을 유효한 액세스 토큰이 필요한 컨트롤러 또는 작업에 적용합니다.

모든 엔드포인트에 대한 인증 필요:

다음 컨트롤러는 모든 작업에 유효한 액세스 토큰이 필요하며 사용자 클레임에 액세스하는 방법을 보여 줍니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Authorize] //  Require valid access token
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        // Access user information
        var userId = User.FindFirst("oid")?.Value;
        var userName = User.Identity?.Name;

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Protected data"
        });
    }
}

특정 범위 필요:

[RequiredScope] 특성을 사용하여 개별 작업에 대해 세분화된 권한을 적용합니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TodoController : ControllerBase
{
    [HttpGet]
    [RequiredScope("access_as_user")] //  Require specific scope
    public IActionResult GetAll()
    {
        return Ok(new[] { "Todo 1", "Todo 2" });
    }

    [HttpPost]
    [RequiredScope("write")] //  Different scope for write operations
    public IActionResult Create([FromBody] string item)
    {
        return Created("", item);
    }
}

5. 실행 및 테스트

애플리케이션을 시작하고 인증되지 않은 요청이 거부되었는지 확인합니다.

dotnet run

Postman 또는 curl과 같은 도구를 사용하여 테스트합니다. 인증되지 않은 요청은 다음을 반환합니다.401 Unauthorized

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://localhost:5001/api/weatherforecast

성공! 이제 API는 전달자 토큰의 유효성을 검사합니다.


앱 등록 설정

API가 토큰의 유효성을 검사하려면 Microsoft Entra 앱 등록이 필요합니다. Azure 포털에서 다음 단계를 수행합니다.

1. API 등록

  1. Azure 포털에 로그인합니다.
  2. Microsoft Entra ID>앱 등록>새 등록으로 이동합니다.
  3. 이름 입력(예: "My Web API")
  4. 단일 테넌트 선택(API에 가장 일반적)
  5. API에 필요한 리디렉션 URI 없음
  6. 등록 클릭

2. API 범위 노출

클라이언트 앱이 API를 호출할 때 요청할 수 있는 권한(범위)을 정의합니다.

  1. API 앱 등록에서 API 노출로 이동합니다.
  2. 범위 추가 클릭
  3. 기본 애플리케이션 ID URI를 적용하거나 사용자 지정합니다(예: api://your-api-client-id).
  4. 범위를 추가합니다.
    • 범위 이름:access_as_user
    • 동의할 수 있는 사람: 관리자 및 사용자
    • 관리자 동의 표시 이름: "내 웹 API에 액세스"
    • 관리자 동의 설명: "앱이 로그인한 사용자를 대신하여 웹 API에 액세스할 수 있도록 허용합니다."
  5. 범위 추가 클릭

3. 애플리케이션 ID를 확인합니다.

앱 등록 개요 페이지에서 애플리케이션(클라이언트) ID 를 복사합니다. 이 값은 사용자의 ClientId 안에 있는 appsettings.json입니다.


클라이언트 앱 등록 만들기(테스트용)

보호된 API를 테스트하려면 토큰을 획득하고 API를 호출하는 별도의 클라이언트 애플리케이션을 등록합니다.

1. 클라이언트 애플리케이션 등록

  1. Microsoft Entra ID>앱 등록에서 다른 등록을 만듭니다.
  2. 이름을 지정합니다(예: "My API 클라이언트").
  3. 계정 유형 선택
  4. 리디렉션 URI 추가: https://localhost:7000/signin-oidc (웹앱인 경우)
  5. 등록 클릭

2. API 권한 부여

정의한 범위로 API를 호출할 수 있는 권한을 클라이언트 애플리케이션에 부여합니다.

  1. 클라이언트 앱 등록에서 API 권한으로 이동합니다.
  2. 권한 추가>내 API 클릭
  3. API 등록 선택
  4. access_as_user 범위 확인
  5. 권한 추가 클릭
  6. 관리자 동의 부여를 클릭합니다(필요한 경우).

3. 클라이언트 비밀 만들기(기밀 클라이언트용)

클라이언트 앱이 브라우저 또는 모바일 디바이스가 아닌 서버에서 실행되는 경우 인증을 위한 클라이언트 암호를 만듭니다.

  1. 인증서 및 비밀로 이동
  2. 새 클라이언트 암호를 클릭합니다.
  3. 설명 및 만료 추가
  4. 추가 클릭
  5. 비밀 값을 즉시 복사 합니다. 다시 볼 수 없습니다.

보호된 API 테스트

API가 인증된 요청을 전송하여 토큰의 유효성을 올바르게 검사했는지 확인합니다.

Postman 사용

Postman에서 OAuth 2.0 인증을 설정하여 토큰을 획득하고 API를 호출합니다.

  1. Postman에서 새 요청 만들기
  2. OAuth 2.0 인증을 설정합니다.
    • 권한 부여 유형: 권한 부여 코드(사용자 컨텍스트용) 또는 클라이언트 자격 증명(앱 컨텍스트용)
    • 인증 URL:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • 액세스 토큰 URL:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • 클라이언트 ID: 클라이언트 앱의 클라이언트 ID
    • 클라이언트 암호: 클라이언트 앱의 비밀
    • 범위:api://your-api-client-id/access_as_user
  3. 새 액세스 토큰 가져오기 클릭
  4. 토큰을 사용하여 API 호출

코드 사용(C# 예제)

다음 예제에서는 MSAL.NET 사용하여 클라이언트 자격 증명 흐름을 사용하여 토큰을 획득하고 보호된 API를 호출합니다.

// In a console app or client application
using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("client-app-id")
    .WithClientSecret("client-secret")
    .WithAuthority("https://login.microsoftonline.com/{tenant-id}")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://your-api-client-id/.default" }
).ExecuteAsync();

var accessToken = result.AccessToken;

// Use the token to call your API
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://localhost:5001/api/weatherforecast");

일반적인 구성 옵션

Microsoft. Identity.Web은 다양한 시나리오에 대한 몇 가지 구성 패턴을 지원합니다.

구성에서 특정 범위 필요

특성을 사용하는 [RequiredScope] 대신 다음에서 필요한 범위를 전역적으로 구성할 수 있습니다.appsettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id",
    "Scopes": "access_as_user"
  }
}

여러 테넌트에서 토큰 수락

Microsoft Entra 테넌트에서 토큰을 수락하려면 TenantIdcommon 설정합니다.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "ClientId": "your-api-client-id"
  }
}

토큰 유효성 검사 구성

API가 다운스트림 API(예: Microsoft Graph)를 호출하는 경우 토큰 획득을 사용하도록 설정하고 토큰 캐시를 구성합니다.

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi() // If your API calls other APIs
    .AddInMemoryTokenCaches();

다음 단계

이제 보호된 API가 있으므로 다음 항목을 살펴보세요.

Troubleshooting

401 권한 없음

문제: API는 토큰을 사용하여도 401을 반환합니다.

가능한 원인:

  • 토큰 대상 그룹(aud 클레임)이 API와 일치하지 않음 ClientId
  • 토큰이 만료되었습니다.
  • 토큰이 잘못된 테넌트에 대한 것입니다.
  • 필수 범위가 누락되었습니다.

솔루션:jwt.ms 토큰을 디코딩하고 클레임을 확인합니다. 자세한 문제 해결 은 로깅 및 진단을 참조하세요.

AADSTS50013: 잘못된 서명

문제: 토큰 서명 유효성 검사에 실패합니다.

솔루션:TenantIdClientId가 올바른지 확인하십시오. 토큰은 예상된 기관에서 발급해야 합니다. 자세한 로깅을 사용하도록 설정하여 유효성 검사 오류를 확인합니다.

토큰에서 범위를 찾을 수 없음

문제:[RequiredScope] 특성이 실패합니다.

Solution:

  1. 클라이언트 앱에 범위에 대한 권한이 있는지 확인합니다.
  2. 관리자 동의가 부여되었는지 확인(필요한 경우)
  3. 전체 범위 유효성 검사 패턴은 권한 부여 가이드 를 참조하세요.
  4. 토큰을 획득할 때 범위가 요청되는지 확인합니다(예: api://your-api/.default 특정 범위).

자세한 정보:Web API 문제 해결 가이드