Azure AD B2C를 사용하여 Xamarin에서 사용자 인증

19856 단어
이 글에서 우리는 당신이 Xamarin을 사용하여 Azure AD B2C 인증을 실현하기 위해 무엇을 해야 하는지 연구할 것입니다.양식 응용 프로그램.이 비디오는 스트리밍에서 생중계되므로 팟캐스트 비디오를 즐겨보시면 here 또는 YouTube를 시청하실 수 있습니다.
혹시 사마린이 느껴지면iOS 및 Xamarin.안드로이드는 우리가 해야 할 일이다. 계속해서 댓글로 알려주거나 트위터에서 알려주세요:)

선결 조건

  • Azure 구독(무료 구독 얻기here)
  • Azure AD B2C 임차인(이 doc의 spin one 사용)
  • Visual Studio 또는 Visual Studio for Mac(이 예에서는 VS4Mac을 사용합니다)
  • Xamarin은 Android와 iOS 의존 항목을 가지고 있기 때문에 로컬에서 구축하고 디버깅할 수 있습니다(install Xamarin)
  • 응용 등록 만들기


    Xamarin 응용 프로그램의 사용자를 검증하고 관리하기 위해서는 AAD B2C에서 응용 프로그램 등록을 만들어야 합니다.이것은 사용자가 우리의 응용 프로그램에 로그인하고 등록하는 방법을 정의하고 우리의 응용 프로그램에 적당한 설정을 제공할 것이다.B2C 포털로 이동하여 새로운 애플리케이션 등록

    우리는 그것에게 의미 있는 이름을 지어주고 레지스터를 눌러야 한다

    이제 애플리케이션 등록 및 인증 탭으로 이동하여 새 플랫폼을 추가합니다.

    우리는 모바일 응용 프로그램을 개발하고 있기 때문에 모바일을 선택한 다음에 다음 그림에 따라 MSAL의 리디렉션 URI를 검사합니다.


    URI로 리디렉션하면 응용 프로그램이 지정됩니다.

    사용자 흐름 구성


    B2C는 사용자 흐름을 사용하여 사용자가 우리의 인증 플랫폼과 어떻게 상호작용하기를 원하는지 정의합니다.그들은 어떤 소셜네트워크서비스 업체(있다면), 어떻게 첫 등록을 하고, 어떻게 우리의 사용자로 하여금 그들의 계좌를 관리하게 할지 결정한다.나는 기본 흐름을 사용하는 것을 좋아한다. 왜냐하면 90퍼센트의 시간 동안 나의 요구를 만족시킬 수 있기 때문이다. 그러나 사용자 정의 흐름을 만들어서 서비스의 가장자리 사례를 완전히 만들 수 있다는 것을 알게 되어 기쁘다.
    이 예에서, 우리는 기본적인 로그인 등록 흐름을 사용합니다.이를 위해 B2C 임차인의 루트 디렉터리로 돌아가서'사용자 흐름'옵션을 열고'새 사용자 흐름'단추를 눌러야 합니다

    사용 가능한 흐름에서 등록과 로그인 흐름을 선택하고 창설 단추를 누르기 전에 추천하는 설정을 사용하십시오.

    우리는 세입자의 유일한 (B2C 세입자의 유일한 이름) 이름을 제공하고 신분 제공자를 설정해야 한다.기본값은 사용자 이름과 비밀번호이지만, 구글, 트위터, Github 등 다른 소셜 미디어 신분 공급자를 필요에 따라 추가할 수 있습니다.우리는 또한 다른 사용자 정의 OIDC 신분 제공 프로그램을 추가할 수 있습니다. 이렇게 하면 우리는 미리 정의된 -joy에 국한되지 않습니다!

    페이지 하단에서 우리는 등록과 로그인 기간에 수집하고 되돌아갈 속성을 설정해야 한다.그러기 위해서는 Showmore를 눌러야 합니다...그리고 수집하고 성명으로 되돌릴 정확한 속성을 선택하고 Ok를 누르면 변경 사항을 지속합니다.

    이제 Create 키를 눌러 새 사용자 흐름을 저장할 수 있습니다.
    이 때, 우리는 약간의 정보를 수집해야 한다. 우리는 Xamarin 응용 프로그램에서 이러한 정보를 사용하여 MSAL(auth 라이브러리)을 설정할 것이다
    애플리케이션 등록에서 다음이 필요합니다.
  • 응용 프로그램(클라이언트) Id:0b3eee66-0000-0000-d9318c4f589d
  • 임차인 이름: youB2CTenantName
  • 임차인 Id:yourB2CTenantName.onmicrosoft.com
  • 리디렉션 URI:msal0b3eee66-0000-0000-d9318c4f589d://auth
  • 사용 흐름 이름: b2c_1_sisu_xamarin(소문자가 더 좋음)
  • 이제 B2C 설정과 포털을 완성했습니다. 코드를 작성하기 시작할 수 있습니다!쓰러지다

    Xamarin에 AAD B2C 인증을 추가합니다.형식


    이 글에 대해 나는 신선한 바닐라 멜라닌부터 시작할 것이다.양식 항목.VS4Mac에서 나는 새롭고 빈 Xamarin을 만들었다.파일 -> 새 항목 옵션을 사용하여 항목 만들기

    그리고 의미 있는 이름을 지어주고 iOS와 안드로이드가 모두 선택되었는지 확인합니다.

    창설 단추를 누르기 전에, 해결 방안 파일이 정확해 보이고, git 파일이 추가되었는지 확인합니다. (기본적인 동작이지만 검사할 가치가 있습니다.)

    솔루션을 만들면 NuGet을 통해 MSAL 라이브러리를 추가할 수 있습니다.이 라이브러리는 라이브러리, iOS, Android 등 3개 항목에 추가되어야 합니다

    가장 간단한 방법은 Microsoft.Identity.Client을 검색하여 우리의 해결 방안에 추가할 수 있도록 선택하는 것이다.

    설치를 완료하기 위해 의존 항목 수락

    좋다그래서 지금 우리는 인코딩을 시작할 준비를 하고 있다...
    우선, 모든 설정 설정을 저장하기 위해 Constants.cs 클래스를 추가해야 합니다.다음 코드를 추가합니다.
    public static class Constants
    {
        public static readonly string TenantName = "YourTenantName";
        public static readonly string TenantId = "YourTenantName.onmicrosoft.com";
        public static readonly string ClientId = "834a4112-0000-0000-0000-860f082f0c8a";
        public static readonly string SignInPolicy = "b2c_1_sisu_xamarin";
        public static readonly string IosKeychainSecurityGroups = "com.<yourcompany>.<groupname>"; // e.g com.contoso.aadb2cauthentication
        public static readonly string[] Scopes = new string[] { "openid", "offline_access" };
        public static readonly string AuthorityBase = $"https://{TenantName}.b2clogin.com/tfp/{TenantId}/";
        public static readonly string AuthoritySignIn = $"{AuthorityBase}{SignInPolicy}";
    }
    
    다음 코드에 따라 인증을 구성하려면 App.xaml.cs에 코드를 추가해야 합니다.
    using Microsoft.Identity.Client;
    using Xamarin.Forms;
    
    namespace XamarinDemoWithB2C
    {
        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());
            }
    
            protected override void OnStart()
            {
            }
    
            protected override void OnSleep()
            {
            }
    
            protected override void OnResume()
            {
            }
        }
    }
    
    AuthenticationClient은 다른 페이지에서 사용자의 신분을 검증하는 데 사용되는 이름입니다.우리는 또한 UIParent 속성을 공개했는데, 우리가 안드로이드를 사용할 때, 이 속성은 내용 페이지를 채워야 한다.iOS 응용 프로그램의 경우null일 수 있습니다.
    이 점에서 코드는 컴파일되지 않을 것입니다. 왜냐하면 우리는 아직 존재하지 않는 LoginPage을 인용했기 때문입니다.이것을 추가하겠습니다.LoginPage은 다음 XAML을 포함하는 ContentPage이어야 합니다.
    <ContentPage.Content>
        <StackLayout Margin="30,40,30,0" HorizontalOptions="Center" VerticalOptions="Center" >
        <Button x:Name="SignInBtn" Text="Sign in" Clicked="OnSignInClicked"/>
        </StackLayout>
    </ContentPage.Content>
    
    보시다시피 우리는 Sign in 단추 하나만 있습니다. - 아주 간단하지만, 당신이 나에게 물어보면, 그것은 매우 실용적입니다.
    다음과 같이 코드 숨김에 로그인 기능인 LoginPage.xaml.cs을 구성해야 합니다.
    using System;
    using System.Linq;
    using Microsoft.Identity.Client;
    using Xamarin.Forms;
    
    namespace XamarinDemoWithB2C
    {
        public partial class LoginPage : ContentPage
        {
            public LoginPage()
            {
                InitializeComponent();
            }
    
            protected override async void OnAppearing()
            {
                try
                {
                    // Look for existing account
                    var accounts = await App.AuthenticationClient.GetAccountsAsync();
    
                    if (accounts.Count() >= 1)
                    {
                        AuthenticationResult result = await App.AuthenticationClient
                            .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
                            .ExecuteAsync();
    
                        await Navigation.PushAsync(new LoginResultPage(result));
                    }
                }
                catch
                {
                    // Do nothing - the user isn't logged in
                }
                base.OnAppearing();
            }
    
            async void OnSignInClicked(object sender, EventArgs e)
            { 
                AuthenticationResult result;
    
                try
                {
                    result = await App.AuthenticationClient
                        .AcquireTokenInteractive(Constants.Scopes)
                        .WithPrompt(Prompt.ForceLogin)
                        .WithParentActivityOrWindow(App.UIParent)
                        .ExecuteAsync();
    
                    await Navigation.PushAsync(new LoginResultPage(result));
                }
                catch(MsalClientException)
                {
    
                }
            }
        }
    }
    
    이 코드는 두 가지 기능이 있다.
  • 우선, OnAppearing 동안, 우리는 MSAL 캐시에 기존 계정이 존재하는지 확인하고, 묵묵적으로 id 영패를 얻으려고 시도했다.만약 실패한다면, 우리는 아무것도 하지 않을 것이다. 왜냐하면 우리는 사용자가 로그인 단추
  • 을 통해 페이지와 상호작용을 해야 하기 때문이다.
  • 그리고 SignIn_Clicked 이벤트를 연결하여 상호작용으로 사용자를 검증합니다.
  • 이 두 가지 상황에서 인증에 성공하면 사용자를 LoginResultPage으로 이동시켜 ID 영패에서 파생된 기본 정보를 표시하고자 합니다.
    퍼즐의 마지막 조각은 LoginResultPage이다.ID 영패에 대한 정보를 표시할 수 있도록 생성합니다.정상적인 응용 프로그램에서 이것은 절차의 일부분이 아니다.일반적으로 우리는 사용자 정보를 검색한 후에 사용자가 응용 프로그램의 나머지 부분을 계속 사용하도록 한다.그러나 이 예는 신분 검증에만 주목하기 때문에 절차에 한계가 있다.LoginResultPage.xaml을 열고 다음 XAML을 추가하여 필요한 정보를 표시하고 로그아웃 버튼을 제공합니다.
    <ContentPage.Content>
        <StackLayout Margin="0,30,30,0" HorizontalOptions="Center" VerticalOptions="Center">
            <Label x:Name="welcome"/>
            <Label x:Name="issuer"/>
            <Label x:Name="subject"/>
            <Label x:Name="audience"/>
            <Label x:Name="email"/>
    
            <StackLayout Margin="40,30,40,0" HorizontalOptions="Center" VerticalOptions="Center">
                <Button x:Name="SignOutBtn" Text="Sign out" Clicked="SignOutBtn_Clicked"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
    
    다음 코드에 ID 토큰을 열고 로그아웃 기능을 수행하기 위해 다음 코드를 추가합니다.
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using Microsoft.Identity.Client;
    using Xamarin.Forms;
    
    namespace XamarinDemoWithB2C
    {
        public partial class LoginResultPage : ContentPage
        {
            private AuthenticationResult authenticationResult;
    
            public LoginResultPage(AuthenticationResult authResult)
            {
                authenticationResult = authResult;        
                InitializeComponent();
            }
    
            protected override void OnAppearing()
            {
                GetClaims();
                base.OnAppearing();
            }
            private void GetClaims()
            {
                var token = authenticationResult.IdToken;
                if (token != null)
                {
                    var handler = new JwtSecurityTokenHandler();
                    var data = handler.ReadJwtToken(authenticationResult.IdToken);
                    var claims = data.Claims.ToList();
                    if (data != null)
                    { 
                        this.welcome.Text = $"Welcome {data.Claims.FirstOrDefault(x => x.Type.Equals("name")).Value}";
                        this.issuer.Text = $"Issuer: { data.Claims.FirstOrDefault(x => x.Type.Equals("iss")).Value}";
                        this.subject.Text = $"Subject: {data.Claims.FirstOrDefault(x => x.Type.Equals("sub")).Value}";
                        this.audience.Text = $"Audience: {data.Claims.FirstOrDefault(x => x.Type.Equals("aud")).Value}";
                        this.email.Text = $"Email: {data.Claims.FirstOrDefault(x => x.Type.Equals("emails")).Value}";
                    }
                }
            }
    
            async void SignOutBtn_Clicked(System.Object sender, System.EventArgs e)
            {
                await App.AuthenticationClient.RemoveAsync(authenticationResult.Account);
                await Navigation.PushAsync(new LoginPage());
            }
        }
    }
    
    JWT와 함께 작업할 수 있도록 NuGet 패키지를 추가해야 합니다.NuGet 패키지 관리자를 열고 시스템을 검색하고 추가합니다.모델을 식별합니다.토큰Jwt 가방.

    iOS별 구성


    응용 프로그램이 작동하기 위해서, 우리는 약간의 추가 설정이 필요하다.iOS 프로젝트에서 AppDelegate.cs 클래스를 열고 다음 코드를 추가합니다
    public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
    {
    AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
    return base.OpenUrl(app, url, options);
    }

    Android별 구성

    For Android to work, there is some more work we need to do. First, open the AndroidManifest.xml 및 다음과 같이 업데이트합니다.
    <?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.companyname.xamarindemowithb2c">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
    <application android:label="XamarinDemoWithB2C.Android" android:theme="@style/MainTheme">
    <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="msal<YourClientId>" android:host="auth" />
    </intent-filter>
    </activity>"
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    </manifest>

    Finally, we need to update the MainActivity.cs은 이렇게 보입니다.

    `
    using System;
    using Android.App;
    using Android.Content.PM;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.OS;
    using Microsoft.Identity.Client;
    using Android.Content;

    namespace XamarinDemoWithB2C.Droid
    {
    [Activity(Label = "XamarinDemoWithB2C", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
    protected override void OnCreate(Bundle savedInstanceState)
    {
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
    
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
            App.UIParent = this;
        }
    
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
        }
    }
    

    }
    `
    Notably, we added a new method OnActivityResult()은 인증 리셋 방향을 처리합니다. OnCreate에 이 코드App.UIParent = this;을 추가했습니다. 인증할 때 이 속성을 채워야 하기 때문입니다.

    그것들을 한데 모으다

    We can now build and run the project using the local emulator or a phone. If everything has been wired correctly you should be able to navigate to the app and authenticate as per the example below:

    If you just want to clone the app and run it on your end, check out the GitHub repo

    따라와

    We love streaming and we usually stream live twice a week on Twitch! But what we love more is to collaborate with developers and tackle real world scenarios. As such, if you're interested to code with us, if have questions/challenges that you want us to help you with or simply a suggestion on what to stream, then we would love for you to reach out. Join us live on the 425Show, follow and bookmark us:

    7am - 10am PT / 2pm - 5pm UTC
    7am - 9am PT / 2pm - 4pm UTC [Community Hours]

    Be sure to send your questions to us here, on Twitter ( , ) or email: [email protected]!

    좋은 웹페이지 즐겨찾기