웹 API를 호출하는 데스크톱 앱: 대화형으로 토큰 획득

다음 예에서는 Microsoft Graph로 사용자 프로필을 읽기 위해 대화형으로 토큰을 가져오는 최소한의 코드를 보여 줍니다.

MSAL.NET 코드

string[] scopes = new string[] { "user.read" };

var app = PublicClientApplicationBuilder.Create("YOUR_CLIENT_ID")
    .WithDefaultRedirectUri()
    .Build();

var accounts = await app.GetAccountsAsync();

AuthenticationResult result;
try
{
    result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
      .ExecuteAsync();
}
catch (MsalUiRequiredException)
{
    result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}

필수 매개 변수

AcquireTokenInteractive에는 하나의 필수 매개 변수 scopes가 있습니다. 이 매개 변수는 토큰이 필요한 범위를 정의하는 문자열의 열거형을 포함합니다. Microsoft Graph용 토큰인 경우 “권한” 섹션에서 각 Microsoft Graph API의 API 참조에서 필요한 범위를 찾을 수 있습니다. 예를 들어, 사용자의 연락처를 나열하려면 User.ReadContacts.Read 모두를 범위로 사용해야 합니다. 자세한 내용은 Microsoft Graph 사용 권한 참조를 참조하세요.

데스크톱 및 모바일 애플리케이션 모두에서 .WithParentActivityOrWindow를 사용하여 부모를 지정하는 것이 중요합니다. 대부분의 경우 요구 사항이며 그러지 않으면 MSAL은 예외를 throw합니다.

데스크톱 애플리케이션의 경우 부모 창 핸들을 참조하세요.

모바일 애플리케이션의 경우 Activity(Android) 또는 UIViewController(iOS)를 제공합니다.

MSAL.NET의 선택적 매개 변수

WithParentActivityOrWindow

UI는 대화형이기 때문에 중요합니다. AcquireTokenInteractive에는 부모 UI를 지원하는 플랫폼에서 부모 UI를 지정할 수 있는 선택적 매개 변수가 하나 있습니다. 데스크톱 애플리케이션에서 사용할 경우 .WithParentActivityOrWindow는 플랫폼에 따라 형식이 다릅니다.

또는 화면에 로그인 대화 상자가 표시되는 위치를 컨트롤하지 않으려는 경우 선택적 부모 창 매개 변수를 생략하여 창을 만들 수 있습니다. 이 옵션은 다른 백 엔드 서비스에 대한 호출을 전달하는 데 사용되며 사용자 조작을 위한 창이 필요하지 않은 명령줄 기반 애플리케이션에 적용됩니다.

// net45
WithParentActivityOrWindow(IntPtr windowPtr)
WithParentActivityOrWindow(IWin32Window window)

// Mac
WithParentActivityOrWindow(NSWindow window)

// .NET Standard (this will be on all platforms at runtime, but only on .NET Standard platforms at build time)
WithParentActivityOrWindow(object parent).

설명:

  • .NET Standard에서 필요한 object 값은 Android의 경우 Activity, iOS의 경우UIViewController, Mac의 경우 NSWindow, Windows의 경우 IWin32Window 또는 IntPr입니다.

  • Windows에서는 임베디드 브라우저가 올바른 UI 동기화 컨텍스트를 가져올 수 있도록 UI 스레드에서 AcquireTokenInteractive를 호출해야 합니다. UI 스레드에서 호출하지 않으면 메시지가 올바르게 펌프되지 않고 UI가 교착 상태에 빠질 수 있습니다. 이미 UI 스레드에 있지 않은 경우 UI 스레드에서 MSAL(Microsoft 인증 라이브러리)을 호출하는 한 가지 방법은 WPF(Windows Presentation Foundation)에서 Dispatcher를 사용하는 것입니다.

  • WPF를 사용하는 경우, WPF 컨트롤에서 창을 가져오려면 WindowInteropHelper.Handle 클래스를 사용할 수 있습니다. 그러면 호출이 WPF 컨트롤(this)에서 이루어집니다.

    result = await app.AcquireTokenInteractive(scopes)
                      .WithParentActivityOrWindow(new WindowInteropHelper(this).Handle)
                      .ExecuteAsync();
    

WithPrompt

WithPrompt()는 프롬프트를 지정하여 사용자와의 대화형 작업을 제어하는 데 사용합니다. Microsoft.Identity.Client.Prompt 구조체를 사용하여 정확한 동작을 제어할 수 있습니다.

이 구조체는 다음 상수를 정의합니다.

  • SelectAccount는 사용자가 세션을 보유한 계정을 포함하는 계정 선택 대화 상자를 제시하도록 STS(보안 토큰 서비스)를 강제합니다. 이 옵션이 기본값입니다. 사용자가 여러 ID 중에서 사용할 수 있게 하려는 경우 유용합니다.

    이 옵션은 MSAL이 ID 공급자에게 prompt=select_account를 보내도록 유도합니다. 이 옵션은 계정, 사용자의 세션 유무와 같은 사용 가능한 정보를 기반으로 최상의 환경을 제공합니다. 특별한 이유가 없는 한 변경하지 마세요.

  • Consent는 애플리케이션에서 이전에 동의가 부여된 경우에도 사용자에게 동의를 묻는 프롬프트를 강제로 표시할 수 있습니다. 이 경우 MSAL이 ID 공급자에게 prompt=consent를 보냅니다. 조직 거버넌스에서 사용자가 애플리케이션을 열 때마다 동의 대화 상자가 표시되도록 요구하는 일부 보안 중심 애플리케이션에서 이 옵션을 사용할 수 있습니다.

  • ForceLogin은 사용자 프롬프트가 필요하지 않은 경우에도 애플리케이션에서 사용자에게 자격 증명 프롬프트를 표시하도록 설정할 수 있습니다. 이 옵션은 토큰 획득에 실패한 경우 사용자가 다시 로그인하도록 할 때 유용합니다. 이 경우 MSAL이 ID 공급자에게 prompt=login를 보냅니다. 조직에서는 거버넌스에 따라 사용자가 애플리케이션의 특정 부분에 액세스할 때마다 로그인해야 하는 보안 중심 애플리케이션에서 이 옵션을 사용하는 경우가 있습니다.

  • Create는 ID 공급자에게 prompt=create를 전송하여 외부 ID에 대한 등록 환경을 트리거합니다. Azure AD B2C(Azure Active Directory B2C) 앱은 이 프롬프트를 보내면 안 됩니다. 자세한 내용은 앱에 셀프 서비스 등록 사용자 흐름 추가를 참조하세요.

  • Never(.NET 4.5 및 Windows 런타임에만 해당)는 사용자에게 메시지를 표시하지 않습니다. 대신 숨겨진 포함된 웹 보기에 저장된 쿠키를 사용하려고 합니다.

    이 옵션 사용에 실패할 수 있습니다. 실패하는 경우 AcquireTokenInteractive는 UI 상호 작용이 필요함을 알리기 위해 예외를 throw합니다. 그런 다음, 다른 Prompt 매개 변수를 사용합니다.

  • NoPrompt는 ID 공급자에게 어떤 프롬프트도 보내지 않습니다. ID 공급자는 사용자에게 가장 적합한 로그인 환경(Single Sign-On 또는 계정 선택)을 결정합니다.

    이 옵션은 Azure AD B2C에서 프로필 정책을 편집하는 데 필요합니다. 자세한 내용은 Azure AD B2C specifics(Azure AD B2C 관련 사항)를 참조하세요.

WithUseEmbeddedWebView

이 메서드를 사용하면 포함된 웹 보기 또는 시스템 웹 보기(사용 가능한 경우)를 강제로 사용하도록 지정할 수 있습니다. 자세한 내용은 Usage of web browsers(웹 브라우저의 용도)를 참조하세요.

var result = await app.AcquireTokenInteractive(scopes)
                    .WithUseEmbeddedWebView(true)
                    .ExecuteAsync();

WithExtraScopeToConsent

이 한정자는 처음에 여러 리소스에 대한 사용자 동의를 받고 증분 동의를 사용하지 않으려는 고급 시나리오에 필요합니다. 개발자는 일반적으로 MSAL.NET 및 Microsoft ID 플랫폼에 증분 동의를 사용합니다. 자세한 내용은 처음에 여러 리소스에 대한 사용자 동의 받기를 참조하세요.

var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
                     .WithExtraScopeToConsent(scopesForVendorApi)
                     .ExecuteAsync();

WithCustomWebUi

웹 UI는 브라우저를 호출하는 메커니즘입니다. 이 메커니즘은 전용 UI WebBrowser 컨트롤일 수도 있고 브라우저 열기를 위임하는 방법일 수도 있습니다. MSAL은 대부분의 플랫폼에 대한 웹 UI 구현을 제공하지만, 다음과 같은 경우 브라우저를 직접 호스트해야 할 수 있습니다.

  • 데스크톱에 Blazor, Unity 및 Mono와 같이 MSAL에서 명시적으로 지원하지 않는 플랫폼이 있습니다.
  • 애플리케이션의 UI를 테스트할 때 Selenium과 함께 사용할 수 있는 자동화된 브라우저를 사용하려는 경우.
  • MSAL을 실행하는 앱과 브라우저가 서로 다른 프로세스에 있는 경우.

이를 위해서는 MSAL에 start Url을 제공해야 합니다. Start Url은 사용자가 사용자 이름과 같은 항목을 입력할 수 있도록 브라우저에 표시되어야 합니다. 인증이 완료되면 앱에서 MSAL로 Microsoft Entra ID에서 제공한 코드를 포함하는 end Url을 전달해야 합니다. end Url의 호스트는 항상 redirectUri입니다. end Url을 가로채려면 다음 중 하나를 수행하세요.

  • redirect Url이 적중될 때까지 브라우저 리디렉션을 모니터링합니다.
  • 모니터링하는 URL로 브라우저가 리디렉션되도록 합니다.

WithCustomWebUi는 공용 클라이언트 애플리케이션에서 자체 UI를 제공하는 데 사용할 수 있는 확장성 지점입니다. 사용자가 ID 공급자의 /Authorize 엔드포인트를 통과하여 로그인 및 동의하도록 할 수도 있습니다. 이렇게 하면 MSAL.NET이 인증 코드를 사용하고 토큰을 가져올 수 있습니다.

예를 들어, Visual Studio에서 WithCustomWebUi를 사용하여 Electrons 애플리케이션(예: Visual Studio Feedback)으로 하여금 웹 상호 작용을 제공하되 대부분의 작업을 MSAL.NET이 처리하도록 할 수 있습니다. UI 자동화를 제공하려는 경우에도 WithCustomWebUi를 사용할 수 있습니다.

공용 클라이언트 애플리케이션에서 MSAL.NET은 PKCE(Proof Key for Code Exchange) 표준을 사용하여 보안이 준수되도록 합니다. 오직 MSAL.NET만 코드를 사용할 수 있습니다. 자세한 내용은 RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients(RFC 7636 - OAuth 공용 클라이언트에 의한 코드 교환을 위한 증명 키)를 참조하세요.

using Microsoft.Identity.Client.Extensions;
WithCustomWebUI 사용

WithCustomWebUI를 사용하려면 다음 단계를 수행합니다.

  1. ICustomWebUi 인터페이스를 구현합니다. 자세한 내용은 이 GitHub 페이지를 참조하세요.

  2. AcquireAuthorizationCodeAsync 메서드 하나를 구현하고 MSAL.NET에서 계산하는 인증 코드 URL을 적용합니다.

  3. 그런 다음 사용자가 ID 공급자와 상호 작용한 후, ID 공급자가 구현을 호출하는 데 사용했을 URL과 인증 코드를 함께 반환하도록 합니다. 문제가 발생하면 MSAL과의 상호 작용을 위해 구현에서 MsalExtensionException 예외를 throw해야 합니다.

  4. AcquireTokenInteractive 호출에서, 사용자 지정 웹 UI 인스턴스를 전달하여 .WithCustomUI() 한정자를 사용합니다.

    result = await app.AcquireTokenInteractive(scopes)
                      .WithCustomWebUi(yourCustomWebUI)
                      .ExecuteAsync();
    

MSAL.NET 팀은 UI 테스트가 이 확장성 메커니즘을 사용할 수 있도록 수정했습니다. 관심이 있다면 MSAL.NET 소스 코드에서 SeleniumWebUI 클래스를 보세요.

SystemWebViewOptions를 사용하여 우수한 환경 제공하기

MSAL.NET 4.1 SystemWebViewOptions에서 다음을 지정할 수 있습니다.

  • 시스템 웹 브라우저에서 로그인 또는 동의 오류가 발생한 경우 이동할 URI(BrowserRedirectError) 또는 표시할 HTML 조각(HtmlMessageError)
  • 로그인 또는 동의에 성공한 경우 이동할 URI(BrowserRedirectSuccess) 또는 표시할 HTML 조각(HtmlMessageSuccess).
  • 시스템 브라우저를 시작하기 위해 실행할 작업. OpenBrowserAsync 대리자를 설정하여 자체 구현을 제공할 수 있습니다. 이 클래스는 두 개의 브라우저를 위한 기본 구현도 제공합니다. Microsoft Edge의 경우 OpenWithEdgeBrowserAsync이고, Chromium의 Microsoft Edge의 경우 OpenWithChromeEdgeBrowserAsync입니다.

이 구조체를 사용하려면 다음 예와 같은 코드를 작성합니다.

IPublicClientApplication app;
...

options = new SystemWebViewOptions
{
 HtmlMessageError = "<b>Sign-in failed. You can close this tab ...</b>",
 BrowserRedirectSuccess = "https://contoso.com/help-for-my-awesome-commandline-tool.html"
};

var result = app.AcquireTokenInteractive(scopes)
                .WithEmbeddedWebView(false)       // The default in .NET
                .WithSystemWebViewOptions(options)
                .Build();

그 밖의 선택적 매개 변수

AcquireTokenInteractive의 다른 모든 선택적 매개 변수에 대해 알아보려면 AcquireTokenInteractiveParameterBuilder를 참조하세요.

다음 단계

이 시나리오의 다음 문서로 이동하여 데스크톱 앱에서 웹 API를 호출합니다.