簡體   English   中英

使用 Azure AD B2C 登錄到 Xamarin Android 應用

[英]Sign in with Azure AD B2C to Xamarin Android app

在研究了使用 Xamarin 以 Android 平台(不是 Xamarin.Forms)為目標的 Azure AD B2C 的身份驗證原則一周后,我終於征求了一些建議。

我有一個帶有“登錄”按鈕的活動,我想在按鈕的觸摸事件上登錄到 Azure。 理想情況下,我希望在完成登錄步驟后收到令牌。

這是我到目前為止的代碼:

public class MainActivity : Activity
{
    public TaskCompletionSource<bool> ActivityResult { get; set; }
    public const int LocationActivityResult = 110;
    private static string AadInstance = "https://login.microsoftonline.com/{0}.onmicrosoft.com/";

    private PublicClientApplication _publicClientApplication;
    private string _authority;
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        //partie pour le sign in 

        EditText editTextEmail = FindViewById<EditText>(Resource.Id.editTextEmail);
        EditText editTextPassword = FindViewById<EditText>(Resource.Id.editTextPassword);
        Button signIn = FindViewById<Button>(Resource.Id.buttonSignIn);

        signIn.Click += async (sender, e) =>
        {

            ConnectivityManager connectivityManager = (ConnectivityManager)GetSystemService(ConnectivityService);
            NetworkInfo networkInfo = connectivityManager.ActiveNetworkInfo;
            if (networkInfo == null)
            {
                Toast.MakeText(this, "Aucune connexion internet", ToastLength.Short).Show();
                Intent intent = new Intent(this.ApplicationContext, typeof(NotInternetActivity));
                intent.SetFlags(ActivityFlags.NewTask);
                StartActivity(intent);
            }
            else
            {

                /////essai pour la connexion
                _authority = string.Format(AadInstance, _azureSettings.Tenant);
                _publicClientApplication = new PublicClientApplication(
                    _authority,
                    _azureSettings.ClientId

                );
                await AcquireTokenAsync();

                /////passe sur la nouvelle actvité

                Intent intent = new Intent(this.ApplicationContext, typeof(PlantsActivity));
                intent.SetFlags(ActivityFlags.NewTask);
                StartActivity(intent);

            }

        };

    }
    Authentication _azureSettings = new Authentication
    {
        ClientId = "ClientId",
        ForgotPasswordPolicy = "ForgotPasswordPolicy",
        SignInOrSignUpPolicy = "SignInOrSignUpPolicy",
        Tenant = "Tenant"

    };

    protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        if (requestCode.Equals(LocationActivityResult))
        {
            if (CrossGeolocator.Current.IsGeolocationEnabled)
                this.ActivityResult.TrySetResult(true);
            else
                this.ActivityResult.TrySetResult(false);
        }
        else
        {
            AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
        }
    }

    public class Authentication
    {
        public string Tenant { get; set; }
        public string ClientId { get; set; }
        public string SignInOrSignUpPolicy { get; set; }
        public string ForgotPasswordPolicy { get; set; }
    }

    public Task<AuthenticationResult> AcquireTokenSilentAsync()
    {
        string[] scopes = { _azureSettings.ClientId };
        var res = _publicClientApplication.AcquireTokenSilentAsync(scopes, "", _authority, _azureSettings.SignInOrSignUpPolicy, false);
        return _publicClientApplication.AcquireTokenSilentAsync(scopes, "", _authority, _azureSettings.SignInOrSignUpPolicy, false);
    }

    public async Task<AuthenticationResult> AcquireTokenAsync()
    {
        string[] scopes = { _azureSettings.ClientId };
        return await _publicClientApplication.AcquireTokenAsync(scopes, "", UiOptions.SelectAccount, string.Empty, null, _authority, _azureSettings.SignInOrSignUpPolicy);
    }
}

我現在把所有東西都放在同一個班級里,只是為了測試結果。 您可以給我的任何示例或您也可以指出我的 Xamarin.Android 上的任何文檔都會非常有幫助。

提前致謝。

所以在這上面花了幾個星期之后,我終於能夠做到了。

所以我的應用程序現在有一個 Azure AD B2C 后端,我可以從 Xamarin Android(本機)應用程序進行身份驗證並從我的 Easy Tables 訪問數據。

下面是它的工作原理:

您需要做的第一件事是從 Azure B2C 獲取令牌,因此一旦成功,authResult 將保存新用戶,您可以在其中訪問令牌和用戶名。

PublicClientApplication publicClientApplication = new PublicClientApplication(AuthParameters.Authority, AuthParameters.ClientId);
var authResult = await publicClientApplication.AcquireTokenSilentAsync(AuthParameters.Scopes, "", AuthParameters.Authority, AuthParameters.Policy, false);
//      await Navigation.PushAsync(new SecurePage());
var result = authResult.Token;

            textbox.Text = authResult.User.Name;

第二件事是通過 loginasync 將令牌發送到您的 mobileserviceclient。

JObject payload = new JObject();
payload["access_token"] = authResult.Token;
try
{
    var user = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
}

這是存儲所需數據的 AuthParameters 類:

public class AuthParameters
{
    public const string Authority = "https://login.microsoftonline.com/YOURSITE.onmicrosoft.com/";
    public const string ClientId = "Client ID from B2C APP";
    public static readonly string[] Scopes = { ClientId };
    public const string Policy = "POLICY_NAME_FROM_B2CTenant";
}

現在在 Azure 門戶上,你應該有一個活動的 Azure B2C 應用程序和一個移動服務客戶端。 他們應該聯系在一起,聯系他們的方式是通過這個鏈接

https://developer.xamarin.com/guides/xamarin-forms/cloud-services/authentication/azure-ad-b2c-mobile-app/

現在您應該能夠通過 MobileServiceClient 正常訪問您的簡易表

該代碼使用 MSAL .NET 和 Azure AD B2C 看起來是正確的。

唯一值得一提的(可能是有意的)是您的應用程序使用AcquireTokenAsyncAcquireTokenSilentAsync 通常,最好的模式是進行靜默調用(它將檢查令牌緩存中的令牌,如果無法為您提供有效的訪問令牌,則會失敗),然后在失敗時調用正常的AcquireTokenAsync

這將使擁有有效令牌的用戶不必在每次打開應用程序或您的應用程序需要令牌時都重復登錄。

Microsoft 有一個代碼示例,展示了如何將MSAL .NET (Xamarin) 與 Azure AD B2C 結合使用 一如既往, B2C 開發人員指南是查找文檔的好地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM