Azure Active Directory B2C로 사용자 인증

Download Sample 샘플 다운로드

Azure Active Directory B2C는 소비자 지향 웹 및 모바일 애플리케이션에 대한 클라우드 ID 관리를 제공합니다. 이 문서에서는 Azure Active Directory B2C를 사용하여 Microsoft 인증 라이브러리를 사용하여 모바일 애플리케이션에 ID 관리를 통합하는 방법을 보여줍니다.

개요

ADB2C(Azure Active Directory B2C)는 소비자 지향 애플리케이션을 위한 ID 관리 서비스입니다. 이를 통해 사용자는 기존 소셜 계정 또는 사용자 지정 자격 증명(예: 전자 메일 또는 사용자 이름, 암호)을 사용하여 애플리케이션에 로그인할 수 있습니다. 사용자 지정 자격 증명 계정을 로컬 계정이라고 합니다.

Azure Active Directory B2C ID 관리 서비스를 모바일 애플리케이션에 통합하는 프로세스는 다음과 같습니다.

  1. Azure Active Directory B2C 테넌트 만들기.
  2. Azure Active Directory B2C 테넌트에 모바일 애플리케이션을 등록합니다.
  3. 등록 및 로그인에 대한 정책을 만들고 암호 사용자 흐름을 잊어버렸습니다.
  4. MSAL(Microsoft 인증 라이브러리)을 사용하여 Azure Active Directory B2C 테넌트를 사용하여 인증 워크플로를 시작합니다.

참고 항목

Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

Azure Active Directory B2C는 Microsoft, GitHub, Facebook, Twitter 등을 비롯한 여러 ID 공급자를 지원합니다. Azure Active Directory B2C 기능에 대한 자세한 내용은 Azure Active Directory B2C 설명서를 참조 하세요.

Microsoft 인증 라이브러리는 여러 애플리케이션 아키텍처 및 플랫폼을 지원합니다. MSAL 기능에 대한 자세한 내용은 GitHub의 Microsoft 인증 라이브러리를 참조하세요.

Azure Active Directory B2C 테넌트 구성

샘플 프로젝트를 실행하려면 Azure Active Directory B2C 테넌트를 만들어야 합니다. 자세한 내용은 Azure Portal에서 Azure Active Directory B2C 테넌트 만들기를 참조하세요.

테넌트를 만든 후에는 모바일 애플리케이션을 구성하려면 테넌트 이름테넌트 ID 가 필요합니다. 테넌트 ID와 이름은 테넌트 URL을 만들 때 생성되는 do기본 의해 정의됩니다. 생성된 테넌트 URL이 https://contoso20190410tenant.onmicrosoft.com/테넌트 IDcontoso20190410tenant.onmicrosoft.com 이고 테넌트 이름이contoso20190410tenant.인 경우 Azure Portal에서 테넌트 do기본 상단 메뉴에서 디렉터리 및 구독 필터를 클릭하여 찾습니다. 다음 스크린샷은 Azure 디렉터리 및 구독 필터 단추와 테넌트가 수행하는 작업을 보여 줍니다기본.

Tenant name in the Azure directory and subscription filter view

샘플 프로젝트에서 Constants.cs 파일을 편집하여 필드와 tenantId 필드를 설정합니다tenantName. 다음 코드에서는 테넌트가 설정해야 하는 경우 이러한 값을 설정하는 방법을 보여 기본 https://contoso20190410tenant.onmicrosoft.com/이러한 값을 포털의 값으로 바꿉니다.

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    ...
}

Azure Active Directory B2C에 모바일 애플리케이션 등록

사용자를 연결하고 인증하려면 먼저 모바일 애플리케이션을 테넌트에 등록해야 합니다. 등록 프로세스는 애플리케이션에 고유한 애플리케이션 ID 를 할당하고 인증 후 응답을 애플리케이션으로 다시 전송하는 리디렉션 URL 을 할당합니다. 자세한 내용은 Azure Active Directory B2C: 애플리케이션 등록을 참조하세요. 속성 보기의 애플리케이션 이름 뒤 나열된 애플리케이션에 할당된 애플리케이션 ID 를 알아야 합니다. 다음 스크린샷은 애플리케이션 ID를 찾을 수 있는 위치를 보여줍니다.

Application ID in the Azure application properties view

Microsoft 인증 라이브러리는 애플리케이션에 대한 리디렉션 URL이 "msal" 텍스트 앞에 접두사로 추가되고 뒤에 "auth"라는 엔드포인트가 잇는 애플리케이션 ID가 될 것으로 예상합니다. 애플리케이션 ID가 "1234abcd"이면 전체 URL이 됩니다 msal1234abcd://auth. 다음 스크린샷과 같이 애플리케이션에서 네이티브 클라이언트 설정을 사용하도록 설정하고 애플리케이션 ID를 사용하여 사용자 지정 리디렉션 URI를 만들어야 합니다.

Custom Redirect URI in the Azure application properties view

URL은 나중에 Android ApplicationManifest.xml 및 iOS Info.plist 모두에서 사용됩니다.

샘플 프로젝트에서 Constants.cs 파일을 편집하여 필드를 애플리케이션 ID설정합니다clientId. 다음 코드는 애플리케이션 ID 1234abcd인 경우 이 값을 설정하는 방법을 보여 줍니다.

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    ...
}

등록 및 로그인 정책 만들기 및 암호 정책 잊기

정책은 사용자가 계정 만들기 또는 암호 재설정과 같은 작업을 완료하기 위해 진행하는 환경입니다. 또한 정책은 사용자가 환경에서 돌아올 때 애플리케이션이 받는 토큰의 콘텐츠를 지정합니다. 계정 등록 및 로그인 모두에 대한 정책을 설정하고 암호를 재설정해야 합니다. Azure에는 일반 정책 만들기를 간소화하는 기본 제공 정책이 있습니다. 자세한 내용은 Azure Active Directory B2C: 기본 제공 정책을 참조하세요.

정책 설정을 완료하면 Azure Portal의 사용자 흐름(정책) 보기에 두 개의 정책이 있어야 합니다. 다음 스크린샷은 Azure Portal에서 구성된 두 가지 정책을 보여 줍니다.

Two configured policies in the Azure User flows (policies) view

샘플 프로젝트에서 Constants.cs 파일을 편집하여 정책 설정 중에 선택한 이름을 반영하도록 필드를 설정합니다 policySigninpolicyPassword.

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    static readonly string policySignin = "B2C_1_signupsignin1";
    static readonly string policyPassword = "B2C_1_passwordreset";
    ...
}

인증에 MSAL(Microsoft 인증 라이브러리) 사용

MSAL(Microsoft 인증 라이브러리) NuGet 패키지를 솔루션의 공유, .NET Standard 프로젝트 및 플랫폼 프로젝트에 Xamarin.Forms 추가해야 합니다. MSAL에는 인터페이스를 PublicClientApplicationBuilder 준수하는 개체를 생성하는 클래스가 IPublicClientApplication 포함되어 있습니다. MSAL은 With 절을 활용하여 생성자 및 인증 방법에 추가 매개 변수를 제공합니다.

샘플 프로젝트에서 App.xaml코드 숨김은 명명 AuthenticationClient 된 정적 속성을 정의하고 UIParent생성자에서 개체를 AuthenticationClient 인스턴스화합니다. 이 절은 WithIosKeychainSecurityGroup iOS 애플리케이션에 대한 보안 그룹 이름을 제공합니다. 이 절은 WithB2CAuthority 사용자를 인증하는 데 사용할 기본 기관 또는 정책을 제공합니다. 이 절은 WithRedirectUri 여러 URI가 지정된 경우 사용할 리디렉션 URI를 Azure Notification Hubs 인스턴스에 지시합니다. 다음 예제에서는 다음을 인스턴스화하는 방법을 보여 줍니다 PublicClientApplication.

public partial class App : Application
{
    public static IPublicClientApplication AuthenticationClient { get; private set; }

    public static object UIParent { get; set; } = null;

    public App()
    {
        InitializeComponent();

        AuthenticationClient = PublicClientApplicationBuilder.Create(Constants.ClientId)
            .WithIosKeychainSecurityGroup(Constants.IosKeychainSecurityGroups)
            .WithB2CAuthority(Constants.AuthoritySignin)
            .WithRedirectUri($"msal{Constants.ClientId}://auth")
            .Build();

        MainPage = new NavigationPage(new LoginPage());
    }

    ...

참고 항목

Azure Notification Hubs 인스턴스에 하나의 리디렉션 URI만 정의된 AuthenticationClient 경우 절을 사용하여 리디렉션 URI를 지정하지 않고도 인스턴스가 WithRedirectUri 작동할 수 있습니다. 그러나 다른 클라이언트 또는 인증 방법을 지원하도록 Azure 구성이 확장되는 경우 항상 이 값을 지정해야 합니다.

OnAppearing 이전에 로그인한 사용자의 인증 토큰을 새로 고치는 호출 AcquireTokenSilentAsync 뒤에 있는 LoginPage.xaml.cs 코드의 이벤트 처리기입니다. 인증 프로세스는 성공하면 리디렉션 LogoutPage 되고 실패할 때 아무 작업도 수행하지 않습니다. 다음 예제에서는 다음의 자동 재인증 프로세스를 보여 있습니다.OnAppearing

public partial class LoginPage : ContentPage
{
    ...

    protected override async void OnAppearing()
    {
        try
        {
            // Look for existing account
            IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

            AuthenticationResult result = await App.AuthenticationClient
                .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch
        {
            // Do nothing - the user isn't logged in
        }
        base.OnAppearing();
    }

    ...
}

OnLoginButtonClicked 이벤트 처리기(로그인 단추를 클릭할 때 발생)가 호출AcquireTokenAsync됩니다. MSAL 라이브러리는 모바일 디바이스 브라우저를 자동으로 열고 로그인 페이지로 이동합니다. 기관이라고 하는 로그인 URL은 Constants.cs 파일에 정의된 테넌트 이름과 정책의 조합입니다. 사용자가 암호 잊기 옵션을 선택하면 예외를 제외하고 앱에 반환되며, 이 경우 잊은 암호 환경이 시작됩니다. 다음 예제에서는 인증 프로세스를 보여줍니다.

public partial class LoginPage : ContentPage
{
    ...

    async void OnLoginButtonClicked(object sender, EventArgs e)
    {
        AuthenticationResult result;
        try
        {
            result = await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch (MsalException ex)
        {
            if (ex.Message != null && ex.Message.Contains("AADB2C90118"))
            {
                result = await OnForgotPassword();
                await Navigation.PushAsync(new LogoutPage(result));
            }
            else if (ex.ErrorCode != "authentication_canceled")
            {
                await DisplayAlert("An error has occurred", "Exception message: " + ex.Message, "Dismiss");
            }
        }
    }

    ...
}

OnForgotPassword 메서드는 로그인 프로세스와 유사하지만 사용자 지정 정책을 구현합니다. OnForgotPassword는 특정 기관을 제공할 수 있는 다른 오버로드AcquireTokenAsync를 사용합니다. 다음 예제에서는 토큰을 획득할 때 사용자 지정 기관을 제공하는 방법을 보여줍니다.

public partial class LoginPage : ContentPage
{
    ...
    async Task<AuthenticationResult> OnForgotPassword()
    {
        try
        {
            return await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .WithB2CAuthority(Constants.AuthorityPasswordReset)
                .ExecuteAsync();
        }
        catch (MsalException)
        {
            // Do nothing - ErrorCode will be displayed in OnLoginButtonClicked
            return null;
        }
    }
}

인증의 마지막 조각은 로그아웃 프로세스입니다. OnLogoutButtonClicked 이 메서드는 사용자가 로그아웃 단추를 누를 때 호출됩니다. 모든 계정을 반복하고 해당 토큰이 무효화되었는지 확인합니다. 아래 샘플에서는 로그아웃 구현을 보여 줍니다.

public partial class LogoutPage : ContentPage
{
    ...
    async void OnLogoutButtonClicked(object sender, EventArgs e)
    {
        IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

        while (accounts.Any())
        {
            await App.AuthenticationClient.RemoveAsync(accounts.First());
            accounts = await App.AuthenticationClient.GetAccountsAsync();
        }

        await Navigation.PopAsync();
    }
}

iOS

iOS에서는 Azure Active Directory B2C에 등록된 사용자 지정 URL 체계를 Info.plist등록해야 합니다. MSAL은 이전에 Azure Active Directory B2C에 모바일 애플리케이션 등록에 설명된 특정 패턴을 준수하는 URL 체계를 기대합니다. 다음 스크린샷은 Info.plist의 사용자 지정 URL 체계를 보여 줍니다.

MSAL에는 다음 스크린샷과 같이 Entitilements.plist등록된 iOS의 키 집합 자격도 필요합니다.

Azure Active Directory B2C가 권한 부여 요청을 완료하면 등록된 리디렉션 URL로 리디렉션됩니다. 사용자 지정 URL 체계를 사용하면 iOS에서 모바일 애플리케이션을 시작하고 URL을 시작 매개 변수로 전달합니다. 이 매개 변수는 애플리케이션 클래스의 재정의 AppDelegate 에 의해 OpenUrl 처리되고 환경 제어를 MSAL에 반환합니다. 구현은 OpenUrl 다음 코드 예제에 나와 있습니다.

using Microsoft.Identity.Client;

namespace TodoAzure.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        ...
        public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
        {
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
            return base.OpenUrl(app, url, options);
        }
    }
}

Android

Android에서는 Azure Active Directory B2C에 등록된 사용자 지정 URL 체계를 AndroidManifest.xml 등록해야 합니다. MSAL은 이전에 Azure Active Directory B2C에 모바일 애플리케이션 등록에 설명된 특정 패턴을 준수하는 URL 체계를 기대합니다. 다음 예제에서는 AndroidManifest.xml 사용자 지정 URL 체계를 보여줍니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.xamarin.adb2cauthorization">
  <uses-sdk android:minSdkVersion="15" />
  <application android:label="ADB2CAuthorization">
    <activity android:name="microsoft.identity.client.BrowserTabActivity">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- example -->
        <!-- <data android:scheme="msalaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" android:host="auth" /> -->
        <data android:scheme="INSERT_URI_SCHEME_HERE" android:host="auth" />
      </intent-filter>
    </activity>"
  </application>
</manifest>

MainActivity 호출 중에 OnCreate 애플리케이션에 개체를 UIParent 제공하도록 클래스를 수정해야 합니다. Azure Active Directory B2C가 권한 부여 요청을 완료하면 AndroidManifest.xml 등록된 URL 체계로 리디렉션됩니다. 등록된 URI 체계로 인해 Android는 URL을 사용하여 메서드를 시작 매개 변수로 호출 OnActivityResult 하고, 여기서 메서드에서 처리합니다 SetAuthenticationContinuationEventArgs .

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        Forms.Init(this, bundle);
        LoadApplication(new App());
        App.UIParent = this;
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
    }
}

유니버설 Windows 플랫폼

유니버설 Windows 플랫폼 MSAL을 사용하기 위해 추가 설정이 필요하지 않습니다.

프로젝트 실행

가상 또는 물리적 디바이스에서 애플리케이션을 실행합니다. 로그인 단추를 탭하면 브라우저가 열리고 로그인하거나 계정을 만들 수 있는 페이지로 이동합니다. 로그인 프로세스를 완료한 후 애플리케이션의 로그아웃 페이지로 돌아가야 합니다. 다음 스크린샷은 Android 및 iOS에서 실행되는 사용자 로그인 화면을 보여줍니다.