ASP.NET Core Blazor Server 추가 보안 시나리오ASP.NET Core Blazor Server additional security scenarios

작성자: Javier Calvarro NelsonBy Javier Calvarro Nelson

Blazor Server 앱으로 토큰 전달Pass tokens to a Blazor Server app

Blazor Server 앱의 Razor 구성 요소 외부에서 사용할 수 있는 토큰은 이 섹션에서 설명하는 방법을 통해 구성 요소로 전달할 수 있습니다.Tokens available outside of the Razor components in a Blazor Server app can be passed to components with the approach described in this section. 완전한 Startup.ConfigureServices 예제와 샘플 코드를 보려면 Passing tokens to a server-side Blazor application(서버 쪽 Blazor 애플리케이션으로 토큰 전달)을 참조하세요.For sample code, including a complete Startup.ConfigureServices example, see the Passing tokens to a server-side Blazor application.

일반 Razor Pages나 MVC 앱을 인증하는 것처럼 Blazor Server 앱을 인증합니다.Authenticate the Blazor Server app as you would with a regular Razor Pages or MVC app. 토큰을 프로비저닝하고 인증 cookie에 저장합니다.Provision and save the tokens to the authentication cookie. 예를 들어:For example:

using Microsoft.AspNetCore.Authentication.OpenIdConnect;

...

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
    options.ResponseType = "code";
    options.SaveTokens = true;

    options.Scope.Add("offline_access");
    options.Scope.Add("{SCOPE}");
    options.Resource = "{RESOURCE}";
});

액세스 토큰 및 새로 고침 토큰과 함께 초기 앱 상태를 전달하는 클래스를 정의합니다.Define a class to pass in the initial app state with the access and refresh tokens:

public class InitialApplicationState
{
    public string AccessToken { get; set; }
    public string RefreshToken { get; set; }
}

Blazor 앱 내에서 DI(종속성 주입)로부터 토큰을 확인하는 데 사용할 수 있는 범위가 지정된 토큰 공급자 서비스를 정의합니다.Define a scoped token provider service that can be used within the Blazor app to resolve the tokens from dependency injection (DI):

public class TokenProvider
{
    public string AccessToken { get; set; }
    public string RefreshToken { get; set; }
}

Startup.ConfigureServices에서 다음 서비스를 추가합니다.In Startup.ConfigureServices, add services for:

  • IHttpClientFactory
  • TokenProvider
services.AddHttpClient();
services.AddScoped<TokenProvider>();

_Host.cshtml 파일에서 InitialApplicationState의 인스턴스를 만들어 앱에 매개 변수로 전달합니다.In the _Host.cshtml file, create and instance of InitialApplicationState and pass it as a parameter to the app:

@using Microsoft.AspNetCore.Authentication

...

@{
    var tokens = new InitialApplicationState
    {
        AccessToken = await HttpContext.GetTokenAsync("access_token"),
        RefreshToken = await HttpContext.GetTokenAsync("refresh_token")
    };
}

<app>
    <component type="typeof(App)" param-InitialState="tokens" 
        render-mode="ServerPrerendered" />
</app>

App 구성 요소(App.razor)에서 서비스를 확인하고 매개 변수로 받은 데이터를 사용하여 초기화합니다.In the App component (App.razor), resolve the service and initialize it with the data from the parameter:

@inject TokenProvider TokenProvider

...

@code {
    [Parameter]
    public InitialApplicationState InitialState { get; set; }

    protected override Task OnInitializedAsync()
    {
        TokenProvider.AccessToken = InitialState.AccessToken;
        TokenProvider.RefreshToken = InitialState.RefreshToken;

        return base.OnInitializedAsync();
    }
}

Microsoft.AspNet.WebApi.Client NuGet 패키지용 앱에 패키지 참조를 추가합니다.Add a package reference to the app for the Microsoft.AspNet.WebApi.Client NuGet package.

보안 API 요청을 만드는 서비스에서 토큰 공급자를 주입하고 토큰을 가져와서 API를 호출합니다.In the service that makes a secure API request, inject the token provider and retrieve the token to call the API:

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class WeatherForecastService
{
    private readonly TokenProvider store;

    public WeatherForecastService(IHttpClientFactory clientFactory, 
        TokenProvider tokenProvider)
    {
        Client = clientFactory.CreateClient();
        store = tokenProvider;
    }

    public HttpClient Client { get; }

    public async Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
    {
        var token = store.AccessToken;
        var request = new HttpRequestMessage(HttpMethod.Get, 
            "https://localhost:5003/WeatherForecast");
        request.Headers.Add("Authorization", $"Bearer {token}");
        var response = await Client.SendAsync(request);
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsAsync<WeatherForecast[]>();
    }
}

인증 체계 설정Set the authentication scheme

여러 인증 미들웨어를 사용하여 인증 체계가 두 개 이상인 앱의 경우 Blazor가 사용하는 체계를 Startup.Configure의 엔드포인트 구성에서 명시적으로 설정할 수 있습니다.For an app that uses more than one Authentication Middleware and thus has more than one authentication scheme, the scheme that Blazor uses can be explicitly set in the endpoint configuration of Startup.Configure. 다음 예제에서는 Azure Active Directory 체계를 설정합니다.The following example sets the Azure Active Directory scheme:

endpoints.MapBlazorHub().RequireAuthorization(
    new AuthorizeAttribute 
    {
        AuthenticationSchemes = AzureADDefaults.AuthenticationScheme
    });

OIDC(OpenID Connect) v2.0 엔드포인트 사용Use OpenID Connect (OIDC) v2.0 endpoints

인증 라이브러리 및 Blazor 템플릿은 OIDC(OpenID Connect) v1.0 엔드포인트를 사용합니다.The authentication library and Blazor templates use OpenID Connect (OIDC) v1.0 endpoints. v2.0 엔드포인트를 사용하려면 OpenIdConnectOptions에서 OpenIdConnectOptions.Authority 옵션을 구성해야 합니다.To use a v2.0 endpoint, configure the OpenIdConnectOptions.Authority option in the OpenIdConnectOptions:

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, 
    options =>
    {
        options.Authority += "/v2.0";
    }

또는 앱 설정(appsettings.json) 파일에서 설정을 수행할 수 있습니다.Alternatively, the setting can be made in the app settings (appsettings.json) file:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/common/oauth2/v2.0/",
    ...
  }
}

인증 기관에 대한 세그먼트의 추적이 앱의 OIDC 공급자에 적합하지 않은 경우(예: 비 AAD 공급자) Authority 속성을 직접 설정합니다.If tacking on a segment to the authority isn't appropriate for the app's OIDC provider, such as with non-AAD providers, set the Authority property directly. OpenIdConnectOptions 또는 앱 설정 파일에서 Authority 키를 사용하여 속성을 설정합니다.Either set the property in OpenIdConnectOptions or in the app settings file with the Authority key.

코드 변경 내용Code changes

App ID URI

  • When using v2.0 endpoints, APIs define an App ID URI, which is meant to represent a unique identifier for the API.
  • All scopes include the App ID URI as a prefix, and v2.0 endpoints emit access tokens with the App ID URI as the audience.
  • When using V2.0 endpoints, the client ID configured in the Server API changes from the API Application ID (Client ID) to the App ID URI.

appsettings.json:

{
  "AzureAd": {
    ...
    "ClientId": "https://{TENANT}.onmicrosoft.com/{APP NAME}"
    ...
  }
}

OIDC 공급자 앱 등록 설명에서 사용해야 하는 앱 ID URI를 확인할 수 있습니다.You can find the App ID URI to use in the OIDC provider app registration description.