Azure Active Directory B2C를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보호

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

이 문서에서는 인증을 위해 AAD(Azure Active Directory) B2C를 사용하는 독립 실행형 Blazor WebAssembly 앱을 만드는 방법을 설명합니다.

이 문서를 읽은 후 추가 보안 시나리오에 대한 자세한 내용은 ASP.NET Core Blazor WebAssembly 추가 보안 시나리오를 참조하세요.

연습

연습의 하위 섹션에서는 다음 방법을 설명합니다.

  • Azure에서 테넌트 만들기
  • Azure에서 앱 등록
  • Blazor 앱 만들기
  • 앱 실행

Azure에서 테넌트 만들기

자습서의 지침에 따라 Azure Active Directory B2C 테넌트를 만들어 AAD B2C 테넌트를 만듭니다.

이 문서의 지침을 진행하기 전에 AAD B2C 테넌트에 대한 올바른 디렉터리를 선택했는지 확인합니다.

Azure에서 앱 등록

AAD B2C 앱을 등록합니다.

  1. Azure Portal에서 Azure AD B2C로 이동합니다. 사이드바에서 앱 등록을 선택합니다. 새 등록 단추를 선택합니다.
  2. 앱의 이름을 지정합니다(예: Blazor 독립 실행형 AAD B2C).
  3. 지원되는 계정 유형의 경우 다중 테넌트 옵션( 조직 디렉터리 또는 ID 공급자의 계정)을 선택합니다. Azure AD B2C를 사용하여 사용자를 인증하는 경우
  4. 리디렉션 URI 드롭다운 목록을 SPA(단일 페이지 애플리케이션)로 설정하고 다음 리디렉션 URIhttps://localhost/authentication/login-callback를 제공합니다. Azure 기본 호스트에 대한 프로덕션 리디렉션 URI(예: azurewebsites.net) 또는 사용자 지정 도메인 호스트(예: contoso.com)를 알고 있는 경우 localhost 리디렉션 URI를 제공하는 동시에 프로덕션 리디렉션 URI를 추가할 수도 있습니다. 추가하는 프로덕션 리디렉션 URI에 비 :443 포트에 대한 포트 번호를 포함해야 합니다.
  5. 확인되지 않은 게시자 도메인을 사용하는 경우 권한>openid 및 offline_access 권한에 대한 관리자 동의 허용을 선택 취소했는지 확인합니다. 게시자 도메인이 확인된 경우에는 이 확인란이 표시되지 않습니다.
  6. 등록을 선택합니다.

참고 항목

localhost AAD B2C 리디렉션 URI에 대한 포트 번호를 제공할 필요는 없습니다. 자세한 내용은 리디렉션 URI(회신 URL) 제한 사항: Localhost 예외(Entra 설명서)를 참조하세요.

다음과 같은 정보를 기록해 둡니다.

  • 애플리케이션(클라이언트) ID(예: 41451fa7-82d9-4673-8fa5-69eff5a761fd).
  • AAD B2C 인스턴스(예: 후행 슬래시를 포함하는 https://contoso.b2clogin.com/): 이 인스턴스는 Azure B2C 앱 등록의 스키마 및 호스트로, Azure Portal의 앱 등록 페이지에서 엔드포인트 창을 열어 찾을 수 있습니다.
  • AAD B2C 주/게시자/테넌트 도메인(예: contoso.onmicrosoft.com): 도메인은 Azure Portal에서 등록된 앱의 브랜딩 블레이드에 게시자 도메인으로 표시되어 있습니다.

인증>플랫폼 구성>에서 단일 페이지 애플리케이션:

  1. 리디렉션 URI가 https://localhost/authentication/login-callback 있는지 확인합니다.
  2. 암시적 권한 부여 섹션에서 액세스 토큰 및 ID 토큰에 대한 검사box가 선택되지 않았는지 확인합니다. MSAL v2.0 이상을 사용하는 앱에서는 Blazor 암시적 허용이 권장되지 않습니다. 자세한 내용은 보안 ASP.NET Core Blazor WebAssembly를 참조하세요.
  3. 이 환경에서는 앱의 나머지 기본값을 그대로 사용해도 좋습니다.
  4. 변경한 경우 저장 단추를 선택합니다.

Home>Azure AD B2C>사용자 흐름에서 다음을 수행합니다.

가입 및 로그인 사용자 흐름 만들기

최소한 애플리케이션 클레임>표시 이름 사용자 특성을 선택하여 LoginDisplay 구성 요소(Shared/LoginDisplay.razor)의 context.User.Identity?.Name/context.User.Identity.Name을 채웁니다.

앱에 대해 만들어진 가입 및 로그인 사용자 흐름 이름을 기록해 둡니다(예: B2C_1_signupsignin).

Blazor 앱 만들기

빈 폴더에서 다음 명령의 자리 표시자를 앞에서 기록해 둔 정보로 바꾸고 명령 셸에서 명령을 실행합니다.

dotnet new blazorwasm -au IndividualB2C --aad-b2c-instance "{AAD B2C INSTANCE}" --client-id "{CLIENT ID}" --domain "{TENANT DOMAIN}" -o {PROJECT NAME} -ssp "{SIGN UP OR SIGN IN POLICY}"
자리 표시자 Azure Portal 이름 예시
{AAD B2C INSTANCE} 인스턴스 https://contoso.b2clogin.com/(후행 슬래시 포함)
{PROJECT NAME} BlazorSample
{CLIENT ID} 애플리케이션(클라이언트) ID 41451fa7-82d9-4673-8fa5-69eff5a761fd
{SIGN UP OR SIGN IN POLICY} 가입/로그인 사용자 흐름 B2C_1_signupsignin1
{TENANT DOMAIN} 주/게시자/테넌트 도메인 contoso.onmicrosoft.com

옵션으로 -o|--output 지정된 출력 위치는 프로젝트 폴더가 존재하지 않는 경우 프로젝트 폴더를 만들고 프로젝트 이름의 일부가 됩니다.

openidoffline_accessDefaultAccessTokenScopes에 대한 MsalProviderOptions 쌍을 추가합니다.

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
});

앱을 만든 후에는 다음을 수행할 수 있습니다.

앱 실행

다음 방법 중 하나를 사용하여 앱을 실행합니다.

  • Visual Studio
    • 실행 단추를 선택합니다.
    • 메뉴에서 디버그>디버깅 시작을 사용합니다.
    • F5키를 누릅니다.
  • .NET CLI 명령 셸: 앱의 폴더에서 명령을 실행 dotnet run 합니다.

앱의 일부

이 섹션에서는 프로젝트 템플릿에서 Blazor WebAssembly 생성된 앱의 부분과 앱이 구성된 방법에 대해 설명합니다. 연습 섹션의 지침을 사용하여 앱을 만든 경우 기본 작업 애플리케이션에 대해 이 섹션에서 따라야 할 구체적인 지침은 없습니다. 이 섹션의 지침은 사용자를 인증하고 권한을 부여하도록 앱을 업데이트하는 데 유용합니다. 그러나 앱을 업데이트하는 다른 방법은 연습 섹션의 지침에서 새 앱을 만들고 앱의 구성 요소, 클래스 및 리소스를 새 앱으로 이동하는 것입니다.

인증 패키지

앱이 개별 B2C 계정을 사용하도록 만들어진 경우(IndividualB2C) 해당 앱은 자동으로 Microsoft 인증 라이브러리(Microsoft.Authentication.WebAssembly.Msal)에 대한 패키지 참조를 받습니다. 패키지는 앱이 사용자를 인증하고 보호된 API를 호출하는 데 사용할 토큰을 가져올 수 있도록 지원하는 기본 형식 세트를 제공합니다.

앱에 인증을 추가하는 경우에는 Microsoft.Authentication.WebAssembly.Msal 패키지를 앱에 수동으로 추가합니다.

참고 항목

.NET 앱에 패키지를 추가하는 방법에 대한 지침은 패키지 사용 워크플로에서 패키지 설치 및 관리의 문서(NuGet 설명서)를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.

Microsoft.Authentication.WebAssembly.Msal 패키지는 타동적으로 Microsoft.AspNetCore.Components.WebAssembly.Authentication 패키지를 앱에 추가합니다.

인증 서비스 지원

사용자 인증에 대한 지원은 Microsoft.Authentication.WebAssembly.Msal 패키지에서 제공하는 AddMsalAuthentication 확장 메서드를 통해 서비스 컨테이너에 등록됩니다. 이 메서드는 앱이 IP(Identity 공급자)와 상호 작용하는 데 필요한 모든 서비스를 설정합니다.

Program 파일에서:

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
});

AddMsalAuthentication 메서드는 콜백을 받아서 앱을 인증하는 데 필요한 매개 변수를 구성합니다. 앱을 등록할 때 구성에서 앱을 구성하는 데 필요한 값을 가져올 수 있습니다.

구성은 wwwroot/appsettings.json 파일에서 제공합니다.

{
  "AzureAdB2C": {
    "Authority": "{AAD B2C INSTANCE}{TENANT DOMAIN}/{SIGN UP OR SIGN IN POLICY}",
    "ClientId": "{CLIENT ID}",
    "ValidateAuthority": false
  }
}

위의 구성에서는 {AAD B2C INSTANCE}에 후행 슬래시가 포함됩니다.

예시:

{
  "AzureAdB2C": {
    "Authority": "https://contoso.b2clogin.com/contoso.onmicrosoft.com/B2C_1_signupsignin1",
    "ClientId": "41451fa7-82d9-4673-8fa5-69eff5a761fd",
    "ValidateAuthority": false
  }
}

액세스 토큰 범위

Blazor WebAssembly 템플릿은 앱이 보안 API에 대한 액세스 토큰을 요청하도록 자동으로 구성하지 않습니다. 로그인 흐름의 일부로 액세스 토큰을 프로비저닝하려면 MsalProviderOptions의 기본 액세스 토큰 범위에 해당 범위를 추가해야 합니다.

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

AdditionalScopesToConsent를 사용하여 추가 범위를 지정합니다.

options.ProviderOptions.AdditionalScopesToConsent.Add("{ADDITIONAL SCOPE URI}");

참고 항목

AdditionalScopesToConsent 사용자가 Microsoft Azure에 등록된 앱을 처음 사용하는 경우 Microsoft Entra ID 동의 UI를 통해 Microsoft Graph에 대한 위임된 사용자 권한을 프로비전할 수 없습니다. 자세한 내용은 ASP.NET Core에서 Graph API 사용을 참조 하세요 Blazor WebAssembly.

자세한 내용은 ‘추가 시나리오’ 문서의 다음 섹션을 참조하세요.

로그인 모드

프레임워크는 기본적으로 팝업 로그인 모드로 설정되며 팝업을 열 수 없는 경우 리디렉션 로그인 모드로 대체됩니다. MsalProviderOptionsLoginMode 속성을 redirect로 설정하여 리디렉션 로그인 모드를 사용하도록 MSAL을 구성합니다.

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.LoginMode = "redirect";
});

기본 설정은 popup이며 문자열 값은 대/소문자를 구분하지 않습니다.

Imports 파일

Microsoft.AspNetCore.Components.Authorization 네임스페이스는 _Imports.razor 파일을 통해 앱 전체에서 사용할 수 있게 됩니다.

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared

인덱스 페이지

인덱스 페이지(wwwroot/index.html)는 JavaScript로 AuthenticationService를 정의하는 스크립트를 포함합니다. AuthenticationService는 OIDC 프로토콜의 하위 수준 세부 정보를 처리합니다. 앱은 내부적으로 스크립트에 정의된 메서드를 호출하여 인증 작업을 수행합니다.

<script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>

App 구성 요소

App 구성 요소(App.razor)는 Blazor Server 앱에 있는 App 구성 요소와 비슷합니다.

  • AuthorizeRouteView 구성 요소는 현재 사용자가 지정된 페이지에 액세스할 수 있는 권한이 부여받았는지 확인하고 그러지 않은 경우 RedirectToLogin 구성 요소를 렌더링합니다.
  • RedirectToLogin 구성 요소는 권한 없는 사용자를 로그인 페이지로 리디렉션하는 기능을 관리합니다.
  • CascadingAuthenticationState 구성 요소는 앱의 나머지 부분에 AuthenticationState를 노출하는 것을 관리합니다.
  • AuthorizeRouteView 구성 요소는 현재 사용자가 지정된 페이지에 액세스할 수 있는 권한이 부여받았는지 확인하고 그러지 않은 경우 RedirectToLogin 구성 요소를 렌더링합니다.
  • RedirectToLogin 구성 요소는 권한 없는 사용자를 로그인 페이지로 리디렉션하는 기능을 관리합니다.

ASP.NET Core 릴리스 간 프레임워크 변경으로 인해 App 구성 요소의 Razor 변경 내용(App.razor)은 이 섹션에 표시되지 않습니다. 지정된 릴리스의 구성 요소의 변경 내용을 검사하려면 다음 방법 중 하나를 사용합니다.

  • 사용하려는 ASP.NET Core 버전의 기본 Blazor WebAssembly 프로젝트 템플릿에서 인증을 위해 프로비전된 앱을 만듭니다. 생성된 앱에서 App 구성 요소(App.razor)를 검사합니다.

  • 참조 소스에서 App 구성 요소(App.razor)를 검사합니다. 분기 선택기에서 버전을 선택하고 수년에 걸쳐 이동했기 때문에 리포지토리 폴더에서 구성 요소를 ProjectTemplates 검색합니다.

    참고 항목

    .NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.

RedirectToLogin 구성 요소

RedirectToLogin 구성 요소(RedirectToLogin.razor)는 다음을 수행합니다.

  • 로그인 페이지로의 권한 없는 사용자 리디렉션을 관리합니다.
  • 사용자가 액세스를 시도하는 현재 URL은 다음을 사용하여 인증에 성공한 경우 해당 페이지로 반환될 수 있도록 기본.

참조 소스에서 RedirectToLogin 구성 요소를 검사합니다. 구성 요소의 위치는 시간이 지남에 따라 변경되므로 GitHub 검색 도구를 사용하여 구성 요소를 찾습니다.

참고 항목

.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.

LoginDisplay 구성 요소

LoginDisplay 구성 요소(LoginDisplay.razor)는 MainLayout 구성 요소(MainLayout.razor)에서 렌더링되고 다음 동작을 관리합니다.

  • 인증된 사용자의 경우:
    • 현재 사용자 이름을 표시합니다.
    • ASP.NET Core Identity에 있는 사용자 프로필 페이지로 연결되는 링크를 제공합니다.
    • 앱에서 로그아웃하는 단추를 제공합니다.
  • 익명 사용자의 경우:
    • 등록 옵션을 제공합니다.
    • 로그인 옵션을 제공합니다.

ASP.NET Core 릴리스 간 프레임워크 변경으로 인해 LoginDisplay 구성 요소의 Razor 변경 내용은 이 섹션에 표시되지 않습니다. 지정된 릴리스의 구성 요소의 변경 내용을 검사하려면 다음 방법 중 하나를 사용합니다.

  • 사용하려는 ASP.NET Core 버전의 기본 Blazor WebAssembly 프로젝트 템플릿에서 인증을 위해 프로비전된 앱을 만듭니다. 생성된 앱에서 LoginDisplay 구성 요소를 검사합니다.

  • 참조 소스에서 LoginDisplay 구성 요소를 검사합니다. 구성 요소의 위치는 시간이 지남에 따라 변경되므로 GitHub 검색 도구를 사용하여 구성 요소를 찾습니다. true와 같은 Hosted에 대한 템플릿 콘텐츠가 사용됩니다.

    참고 항목

    .NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.

Authentication 구성 요소

Authentication 구성 요소에 의해 생성된 페이지(Pages/Authentication.razor)는 다른 인증 단계를 처리하는 데 필요한 경로를 정의합니다.

RemoteAuthenticatorView 구성 요소는 다음과 같습니다.

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

참고 항목

NRT(Nullable 참조 형식) 및 .NET 컴파일러 null 상태 정적 분석은 .NET 6 이상의 ASP.NET Core에서 지원됩니다. .NET 6에서 ASP.NET Core가 릴리스되기 전에 형식은 string null 형식 지정(?)없이 표시됩니다.

사용자 지정 정책

Microsoft 인증 라이브러리(Microsoft.Authentication.WebAssembly.MsalNuGet 패키지)는 기본적으로 AAD B2C 사용자 지정 정책을 지원하지 않습니다.

문제 해결

로깅

인증에 Blazor WebAssembly 디버그 또는 추적 로깅을 사용하도록 설정하려면 문서 버전 선택기가 ASP.NET Core Blazor 7.0 이상으로 설정된 ASP.NET Core 로깅의 클라이언트 쪽 인증 로깅 섹션을 참조하세요.

일반 오류

  • 앱 또는 IP(Identity 공급자)의 잘못된 구성

    가장 일반적인 오류는 잘못된 구성으로 인해 발생합니다. 다음은 몇 가지 예입니다.

    • 시나리오의 요구 사항에 따라, 누락되거나 잘못된 권한, 인스턴스, 테넌트 ID, 테넌트 도메인, 클라이언트 ID 또는 리디렉션 URI 때문에 앱에서 클라이언트를 인증하지 못합니다.
    • 잘못된 요청 범위는 클라이언트가 서버 웹 API 엔드포인트에 액세스하지 못하게 합니다.
    • 서버 API 권한이 잘못되거나 누락되어 클라이언트가 서버 웹 API 엔드포인트에 액세스할 수 없습니다.
    • IP 앱 등록의 리디렉션 URI에 구성된 것과 다른 포트에서 앱을 실행합니다. Microsoft Entra ID 및 개발 테스트 주소에서 localhost 실행되는 앱에는 포트가 필요하지 않지만 앱의 포트 구성 및 앱이 실행되는 포트는 주소localhost 가 아닌 경우 일치해야 합니다.

    이 문서 지침의 구성 섹션에서는 올바른 구성의 예를 보여 줍니다. 앱 및 IP 구성을 찾는 문서의 각 섹션을 주의 깊게 확인하세요.

    구성이 올바르게 표시되면 다음을 수행합니다.

    • 애플리케이션 로그를 분석합니다.

    • 브라우저의 개발자 도구를 사용하여 클라이언트 앱과 IP 또는 서버 앱 간의 네트워크 트래픽을 검사합니다. 종종 정확한 오류 메시지 또는 문제의 원인에 대한 단서가 있는 메시지가 요청을 수행한 후 IP 또는 서버 앱에 의해 클라이언트로 반환됩니다. 개발자 도구 지침은 다음 문서에서 확인할 수 있습니다.

    • JWT(ON Web Token)가 사용되는 릴리스JS의 Blazor 경우 문제가 발생하는 위치에 따라 클라이언트를 인증하거나 서버 웹 API에 액세스하는 데 사용되는 토큰의 콘텐츠를 디코딩합니다. 자세한 내용은 JWT(JSON Web Token)의 콘텐츠 검사를 참조하세요.

    문서 작업 팀은 설명서 피드백 및 문서의 버그에 응답하지만(이 페이지의 피드백 섹션에서 문제 열기) 제품 지원을 제공할 수 없습니다. 앱 문제 해결을 지원하기 위해 몇 가지 퍼블릭 지원 포럼을 사용할 수 있습니다. 다음을 권장합니다.

    이전 포럼은 Microsoft에서 소유하거나 제어하지 않습니다.

    중요하지 않고 보안이나 기밀이 아니며 재현 가능한 프레임워크 버그 보고서의 경우 ASP.NET Core 제품 단위에서 문제를 여세요. 문제의 원인을 철저하게 조사했으며 자신의 노력과 퍼블릭 지원 포럼에서 커뮤니티의 도움을 받아도 해결할 수 없는 경우에만 제품 단위에서 문제를 열고 그전에는 열지 마세요. 제품 단위는 단순한 구성 오류 또는 타사 서비스와 관련된 사용 사례로 인해 손상된 개별 앱의 문제를 해결할 수 없습니다. 보고서가 본질적으로 민감하거나 기밀이거나 공격자가 악용할 수 있는 제품의 잠재적인 보안 결함을 설명하는 경우 보안 문제 및 버그 보고(dotnet/aspnetcoreGitHub 리포지토리)를 참조하세요.

  • ME-ID에 대한 권한 없는 클라이언트

    info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 권한 부여에 실패했습니다. 이러한 요구 사항이 충족되지 않았습니다. DenyAnonymousAuthorizationRequirement: 인증된 사용자가 필요합니다.

    ME-ID의 로그인 콜백 오류:

    • 오류: unauthorized_client
    • 설명: AADB2C90058: The provided application is not configured to allow public clients.

    오류를 해결하려면:

    1. Azure Portal에서 앱의 매니페스트에 액세스합니다.
    2. allowPublicClient 특성null 또는 true로 설정합니다.

Cookie 및 사이트 데이터

Cookie 및 사이트 데이터가 앱을 업데이트할 때에도 유지되어 테스트 및 문제 해결에 방해가 될 수 있습니다. 앱 코드를 변경하거나 공급자를 사용하여 사용자 계정을 변경하거나 공급자 앱 구성을 변경하는 경우 다음을 지우세요.

  • 사용자 로그인 cookie
  • 앱 cookie
  • 캐시되고 저장된 사이트 데이터

남겨진 cookie 및 사이트 데이터로 인해 테스트 및 문제 해결이 지장을 받지 않도록 하려면 다음을 수행합니다.

  • 브라우저 구성
    • 브라우저에서 브라우저를 닫을 때마다 모든 cookie 및 사이트 데이터를 삭제하도록 구성할 수 있는지 테스트합니다.
    • 앱, 테스트 사용자 또는 공급자 구성을 변경할 때 수동으로 또는 IDE를 통해 브라우저를 닫습니다.
  • 사용자 지정 명령을 사용하여 Visual Studio에서 InPrivate 또는 Incognito 모드로 브라우저를 엽니다.
    • Visual Studio의 실행 단추를 통해 브라우저 선택 대화 상자를 엽니다.
    • 추가 단추를 선택합니다.
    • 프로그램 필드에서 브라우저의 경로를 제공합니다. 다음 실행 파일 경로는 Windows 10에서 일반적인 설치 위치입니다. 브라우저가 다른 위치에 설치되어 있거나 Windows 10을 사용하지 않는 경우 브라우저 실행 파일의 경로를 제공합니다.
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • 인수 필드에서 브라우저가 InPrivate 또는 Incognito 모드에서 여는 데 사용하는 명령줄 옵션을 제공합니다. 일부 브라우저에는 앱의 URL이 필요합니다.
      • Microsoft Edge: 사용 -inprivate.
      • Google Chrome: 자리 표시자가 {URL} 열 URL인 경우(예https://localhost:5001: )를 사용합니다--incognito --new-window {URL}.
      • Mozilla Firefox: 자리 표시자가 {URL} 열 URL인 경우(예https://localhost:5001: )를 사용합니다-private -url {URL}.
    • 이름 필드에 이름을 입력합니다. 예들 들어 Firefox Auth Testing입니다.
    • 확인 단추를 선택합니다.
    • 앱 테스트를 반복할 때마다 브라우저 프로필을 선택할 필요가 없도록 하려면 기본값으로 설정 단추를 사용하여 프로필을 기본값으로 설정합니다.
    • 앱, 테스트 사용자 또는 공급자 구성을 변경할 때 IDE를 통해 브라우저를 닫습니다.

앱 업그레이드

개발 컴퓨터의 .NET Core SDK 또는 앱 내의 패키지 버전을 업그레이드하거나 앱 내 패키지 버전을 변경한 후 즉시 작동 중인 앱에서 오류가 발생할 수 있습니다. 경우에 따라 중요한 업그레이드를 수행할 때 일관되지 않은 패키지로 인해 응용 프로그램이 중단될 수 있습니다. 이러한 대부분의 문제는 다음 지침에 따라 수정할 수 있습니다.

  1. 명령 셸에서 dotnet nuget locals all --clear를 실행하여 로컬 시스템의 NuGet 패키지 캐시를 지웁니다.
  2. 프로젝트의 binobj 폴더를 삭제합니다.
  3. 프로젝트를 복원하고 다시 빌드합니다.
  4. 앱을 다시 배포하기 전에 서버의 배포 폴더에 있는 모든 파일을 삭제합니다.

참고 항목

앱의 대상 프레임워크와 호환되지 않는 패키지 버전의 사용은 지원되지 않습니다. 패키지에 대한 자세한 내용은 NuGet 갤러리 또는 FuGet 패키지 탐색기를 사용하세요.

Server 실행

호스트된 Blazor WebAssembly솔루션을 테스트하고 문제를 해결할 때 Server 프로젝트에서 앱을 실행하고 있는지 확인합니다.

사용자 검사

다음 User 구성 요소는 앱에서 직접 사용하거나 추가 사용자 지정의 기준으로 사용할 수 있습니다.

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

JWT(JSON Web Token)의 콘텐츠 검사

JWT(JSON Web Token)를 디코딩하려면 Microsoft의 jwt.ms 도구를 사용합니다. UI의 값은 브라우저에 남겨지지 않습니다.

인코딩된 JWT 예제(표시를 위해 축약됨):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Azure AAD B2C에 대해 인증하는 앱용 도구에 의해 디코딩된 JWT 예제:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/5cc15ea8-a296-4aa3-97e4-226dcc9ad298/v2.0/",
  "sub": "5ee963fb-24d6-4d72-a1b6-889c6e2c7438",
  "aud": "70bde375-fce3-4b82-984a-b247d823a03f",
  "nonce": "b2641f54-8dc4-42ca-97ea-7f12ff4af871",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

추가 리소스