재우니의 블로그

custom Middleware  활용하여 Asp.Net Core Minimal APIs 보안 처리하기

 

이번 포스팅에서는 minimal API 를 활용하기 위한 커스텀 미들웨어를 만들어 보겠습니다.

 

 

Authorization

클라이언트 요청이 데이터에 안전하게 액세스하도록 하기 위해 API 는 authorization 을 사용합니다. authentication (인증)이 올바른 신원을 증명하는 것을 의미한다면, authorization (권한 부여)는 특정 Action 을 Allow(허용) 하는 것을 의미합니다.

authorization (권한 부여) 프로세스에는 요청 발신자를 인증하고 관련 데이터에 액세스하거나 조작할 수 있는 권한이 있는지 확인하는 작업이 포함될 수 있습니다.

 

API Key, Bearer token, Basic auth, OAuth 등과 같은 다양한 authorization 모델이 있습니다.

 

 

 

Api Key

API 는 일반적으로 Request Header 또는 Query parameters 에 포함하는 key-value 쌍입니다. API 키는 주로 API 호출(API 사용을 인증하는 것)을 하는 사람을 식별하는 방법으로 사용합니다. 

 

Middleware

 

 

미들웨어는 requests and responses(요청 및 응답) 을 처리하는 데 사용되는 애플리케이션 파이프라인의 component (클래스)입니다. 

 

component :

  • 파이프라인의 다음 구성 요소에 요청을 전달할지 여부를 선택합니다.
  • 파이프라인의 다음 구성 요소 앞 뒤로 작업을 수행할 수 있습니다.

 

 

다음 다이어그램은 미들웨어 파이프라인이 작동하는 방식을 보여줍니다. 각 미들웨어는 다음 작업 전후에 작업을 수행할 수 있습니다.

 

 

 

 

 

ASP.Net Core Web API가 생성 되면 일부 기본 미들웨어를 사용합니다. 다음 다이어그램은 전체 요청 처리 파이프라인을 보여줍니다. 기존 미들웨어의 주문 방식과 사용자 지정 미들웨어를 추가할 수 있는 위치를 보여줍니다.

 

custom middleware 생성

 

 

Middleware 는 일반적으로 클래스에 캡슐화되고 extension method 로 노출되며 다음을 포함해야 합니다.

 

 

  • RequestDelegate 유형의 매개변수가 있는 public constructor.
  • Invoke 또는 InvokeAsync라는 public method 입니다. method  은 다음을 충족해야 합니다.
    • Task 을 리합니다.
    • HttpContext 유형의 첫 번째 매개변수를 Accept(수락) 합니다.

 

 

이 사용자 정의 미들웨어의 경우 api Keys 값 목록도 parameters 로 전달됩니다.

InvokeAsync 메서드에서 코드는 헤더에 ApiKey가 포함되어 있는지 확인합니다. 그렇지 않으면 다음 미들웨어가 호출되지 않고 오류 401이 발생합니다.

 

 

 

public class CustomApiKeyMiddleware
{
    private readonly RequestDelegate _next;

    private readonly List<string> _apiKeys;


    public CustomApiKeyMiddleware(RequestDelegate next, string apiKey)
        : this(next, new List<string> { apiKey })
    {
    }

    public CustomApiKeyMiddleware(RequestDelegate next, List<string> apiKeys)
    {
        _next = next;
        _apiKeys = apiKeys;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        string header = context.Request.Headers[Constants.ApiKeyHeaderName].ToString();

        if ((context.Features.Get<IEndpointFeature>()?.Endpoint?.Metadata.Any((m) => m is AllowAnonymousAttribute)).GetValueOrDefault() || 
            !string.IsNullOrWhiteSpace(header) && _apiKeys.Any((k) => k == header))
        {
            await _next(context);
            return;
        }

        context.Response.StatusCode = 401;
        context.Response.ContentType = "text/plain";
        await context.Response.WriteAsync("ApiKey is invalid.");
    }
}

 

 

Configuration

 

 

이제 파이프라인에 custom middleware 를 추가할 차례입니다. 이것은 appsettings에 정의된 Api 키의 유효성을 검사하는 데 사용되는 middleware  이며, 다른 모든 middleware 이후에 기술해야 하며, UseEndpoints 미들웨어는 그 이전에 기술되어야 합니다. (코드 순서 기술 중요)

 

 

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseMiddleware<CustomApiKeyMiddleware>(app.Configuration.GetValue<string>("TodoApiKey"));

app.UseHttpsRedirection();

app.Run();

 

 

다음 코드는 swagger에 대한 보안 정의를 추가합니다. 이렇게 하면 승인 버튼이 표시되고 사용자가 엔드포인트를 실행하기 전에 ApiKey를 추가할 수 있습니다.

 

 

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "TodoServiceApi", Version = "v1" });

    c.AddSecurityDefinition(Constants.ApiKeyHeaderName, new OpenApiSecurityScheme
    {
        Description = "Api key needed to access the endpoints. ApiKey: ApiKey",
        In = ParameterLocation.Header,
        Name = Constants.ApiKeyHeaderName,
        Type = SecuritySchemeType.ApiKey
    });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Name = Constants.ApiKeyHeaderName,
                Type = SecuritySchemeType.ApiKey,
                In = ParameterLocation.Header,
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = Constants.ApiKeyHeaderName,
                },
                },
                new string[] {}
            }
    });
});

 

 

Postman 로 테스트

 

 

ApiKey를 제공하지 않고 엔드포인트를 실행하면 다음 이미지와 같이 무단 오류가 발생합니다.

 

Authorization 탭에서 ApiKey를 추가할 수 있으며 Type 목록에서 API Key를 선택하고 Api 설정에서 정의한 동일한 키와 값으로 값을 추가할 수 있습니다.

 

 

 

Swagger 로 테스트하기

 

 

API 키가 제공되지 않으면 swagger 에서도 동일한 오류가 발생합니다.

 

코드를 통해 swagger 설정에 보안 정의가 추가되었으므로 이제 인증 페이지를 사용할 수 있습니다. 페이지 상단의 Authorize 버튼 또는 각 endpoint 의 header 잠금 아이콘을 통해 페이지를 표시할 수 있습니다.

 

 

 

ApiKey 값을 제공한 후 페이지는 모든 endpoint 을 실행할 권한이 부여됩니다.

 

마무리

전체 코드는 내 GitHub 에서 찾을 수 있습니다 .

 

 

원본 사이트 

 

https://blog.jhonatanoliveira.dev/securing-aspnet-core-minimal-apis-with-a-custom-middleware

 

Securing Asp.Net Core Minimal APIs with a custom Middleware

In this post we will create a custom middleware to secure a minimal API. Authorization To ensure that client requests access data securely, APIs use authorization. If authentication refers to proving correct identity, authorization refers to allowing...

blog.jhonatanoliveira.dev