概述
本主题说明如何通过客户端应用程序对应用服务移动应用的用户进行身份验证。 在本教程中,你将使用应用服务支持的标识提供者向 Xamarin Forms 快速入门项目添加身份验证。 在移动应用成功进行身份验证和授权后,将显示用户 ID 值,你将能够访问受限的表数据。
先决条件
为获得最佳本教程结果,建议先完成 “创建 Xamarin Forms 应用 ”教程。 完成本教程后,你将拥有一个 Xamarin Forms 项目,该项目是一个多平台 TodoList 应用。
如果不使用下载的快速入门服务器项目,则必须将身份验证扩展包添加到项目中。 有关服务器扩展包的详细信息,请参阅 使用适用于 Azure 移动应用的 .NET 后端服务器 SDK。
注册应用以进行身份验证并配置应用服务
首先,需要在标识提供者的站点上注册应用,然后在移动应用后端设置提供程序生成的凭据。
请根据提供商的具体说明配置您的首选身份提供商。
对要在应用中支持的每个提供商重复上述步骤。
将应用添加到允许的外部重定向 URL
安全身份验证要求为应用定义新的 URL 方案。 这样,身份验证系统就可以在身份验证过程完成后重定向回应用。 在本教程中,我们将在整个过程中使用 URL 方案 appname 。 但是,可以使用你选择的任何 URL 方案。 它应该是您移动应用程序独有的。 若要在服务器端启用重定向,请执行以下作:
在 Azure 门户中,选择应用服务。
单击“ 身份验证/授权 ”菜单选项。
在 “允许的外部重定向 URL”中,输入
url_scheme_of_your_app://easyauth.callback
。 此字符串中的 url_scheme_of_your_app 是移动应用程序的 URL 方案。 它应遵循协议的正常 URL 规范(仅使用字母和数字,以字母开头)。 应记下所选字符串,因为需要在多个位置使用 URL 方案调整移动应用程序代码。单击“确定”。
单击“ 保存”。
限制对经过身份验证的用户的权限
默认情况下,移动应用后端中的 API 可以匿名调用。 接下来,需要限制仅对经过身份验证的客户端的访问。
Node.js 后端(通过 Azure 门户):
在移动应用设置中,单击 “简易表 ”并选择表。 单击“ 更改权限”,仅为所有权限选择“ 经过身份验证的访问权限 ”,然后单击“ 保存”。
.NET 后端 (C#):
在服务器项目中,导航到 控制器>TodoItemController.cs。 将
[Authorize]
属性添加到 TodoItemController 类,如下所示。 若要仅限制对特定方法的访问,还可以仅将此属性应用于这些方法而不是类。 重新发布服务器项目。[Authorize] public class TodoItemController : TableController<TodoItem>
Node.js 后端(通过 Node.js 代码) :
若要要求对表访问进行身份验证,请将以下行添加到 Node.js 服务器脚本:
table.access = 'authenticated';
有关详细信息,请参阅 “如何:要求身份验证才能访问表”。 若要了解如何从网站下载快速入门代码项目,请参阅 如何:使用 Git 下载 Node.js 后端快速入门代码项目。
将身份验证添加到可移植类库
移动应用使用 MobileServiceClient 上的 LoginAsync 扩展方法通过应用服务身份验证登录用户。 此示例使用服务器管理的身份验证流,该流在应用中显示提供程序的登录接口。 有关详细信息,请参阅 服务器管理的身份验证。 若要在生产应用中提供更好的用户体验,应考虑改用 客户端管理的身份验证。
若要使用 Xamarin Forms 项目进行身份验证,请在应用的可移植类库中定义 IAuthenticate 接口。 然后将 “登录 ”按钮添加到可移植类库中定义的用户界面,单击该按钮开始身份验证。 成功身份验证后,数据将从移动应用后端加载。
为应用支持的每个平台实现 IAuthenticate 接口。
在 Visual Studio 或 Xamarin Studio 中,使用可移植名称打开项目App.cs,即 可移植 类库项目,然后添加以下
using
语句:```csharp using System.Threading.Tasks; ```
在App.cs中,在
IAuthenticate
类定义之前立即添加以下App
接口定义。```csharp public interface IAuthenticate { Task<bool> Authenticate(); } ```
若要使用特定于平台的实现初始化接口,请将以下静态成员添加到 App 类。
```csharp public static IAuthenticate Authenticator { get; private set; } public static void Init(IAuthenticate authenticator) { Authenticator = authenticator; } ```
从可移植类库项目中打开 TodoList.xaml,在现有按钮后面添加 buttonsPanel 布局元素中的以下 Button 元素:
```xml <Button x:Name="loginButton" Text="Sign-in" MinimumHeightRequest="30" Clicked="loginButton_Clicked"/> ```
此按钮触发由服务器管理的与移动应用后端进行的身份验证。
从可移植类库项目打开TodoList.xaml.cs,然后将以下字段添加到
TodoList
类:```csharp // Track whether the user has authenticated. bool authenticated = false; ```
将 OnAppearing 方法替换为以下代码:
```csharp protected override async void OnAppearing() { base.OnAppearing(); // Refresh items only when authenticated. if (authenticated == true) { // Set syncItems to true in order to synchronize the data // on startup when running in offline mode. await RefreshItems(true, syncItems: false); // Hide the Sign-in button. this.loginButton.IsVisible = false; } } ```
此代码可确保仅在经过身份验证后从服务刷新数据。
将 Clicked 事件的以下处理程序添加到 TodoList 类:
```csharp async void loginButton_Clicked(object sender, EventArgs e) { if (App.Authenticator != null) authenticated = await App.Authenticator.Authenticate(); // Set syncItems to true to synchronize the data on startup when offline is enabled. if (authenticated == true) await RefreshItems(true, syncItems: false); } ```
保存更改并重新生成可移植类库项目,验证无错误。
将身份验证添加到 Android 应用
本部分介绍如何在 Android 应用项目中实现 IAuthenticate 接口。 如果不支持 Android 设备,请跳过本部分。
在 Visual Studio 或 Xamarin Studio 中,右键单击 droid 项目,然后选择 “设为启动项目”。
按 F5 键在调试器中启动项目,然后验证应用启动后是否确实抛出了一个状态码为401(未授权)的未处理异常。 生成 401 代码是因为后端上的访问仅限于授权用户。
在 Android 项目中打开MainActivity.cs,并添加以下
using
语句:```csharp using Microsoft.WindowsAzure.MobileServices; using System.Threading.Tasks; ```
更新 MainActivity 类以实现 IAuthenticate 接口,如下所示:
```csharp public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity, IAuthenticate ```
通过添加 MobileServiceUser 字段和 IAuthenticate 接口所需的 Authenticate 方法更新 MainActivity 类,如下所示:
```csharp // Define an authenticated user. private MobileServiceUser user; public async Task<bool> Authenticate() { var success = false; var message = string.Empty; try { // Sign in with Facebook login using a server-managed flow. user = await TodoItemManager.DefaultManager.CurrentClient.LoginAsync(this, MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}"); if (user != null) { message = string.Format("you are now signed-in as {0}.", user.UserId); success = true; } } catch (Exception ex) { message = ex.Message; } // Display the success or failure message. AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.SetMessage(message); builder.SetTitle("Sign-in result"); builder.Create().Show(); return success; } public override void OnResume() { base.OnResume(); Xamarin.Essentials.Platform.OnResume(); } ```
如果使用 Facebook 以外的标识提供者,请为 MobileServiceAuthenticationProvider 选择其他值。
通过在
<application>
元素内添加以下 XML 来更新AndroidManifest.xml文件:<activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity" android:launchMode="singleTop" android:noHistory="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="{url_scheme_of_your_app}" android:host="easyauth.callback" /> </intent-filter> </activity>
将
{url_scheme_of_your_app}
替换为您自己的 URL 方案。在调用
LoadApplication()
MainActivity 类之前,将以下代码添加到 MainActivity 类的 OnCreate 方法:```csharp // Initialize the authenticator before loading the app. App.Init((IAuthenticate)this); ```
此代码可确保在应用加载之前初始化验证器。
重新生成应用,运行它,然后使用所选的身份验证提供程序登录,并验证你能否以经过身份验证的用户身份访问数据。
故障排除
应用程序崩溃 Java.Lang.NoSuchMethodError: No static method startActivity
在某些情况下,支持包中的冲突在 Visual Studio 中仅显示为警告,但应用程序在运行中会因这个异常而崩溃。 在这种情况下,需要确保项目中引用的所有支持包具有相同的版本。
Azure 移动应用 NuGet 包具有 Xamarin.Android.Support.CustomTabs
Android 平台的依赖项,因此,如果你的项目使用较新的支持包,则需要直接安装具有所需版本的此包以避免冲突。
将身份验证添加到 iOS 应用
本部分介绍如何在 iOS 应用项目中实现 IAuthenticate 接口。 如果不支持 iOS 设备,请跳过本部分。
在 Visual Studio 或 Xamarin Studio 中,右键单击 iOS 项目,然后选择 “设为启动项目”。
按 F5 键在调试器中启动项目,然后验证应用启动后是否确实抛出了一个状态码为401(未授权)的未处理异常。 生成 401 响应是因为后端上的访问仅限于授权用户。
在 iOS 项目中打开AppDelegate.cs,并添加以下
using
语句:```csharp using Microsoft.WindowsAzure.MobileServices; using System.Threading.Tasks; ```
更新 AppDelegate 类以实现 IAuthenticate 接口,如下所示:
```csharp public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IAuthenticate ```
通过在 AppDelegate 类中添加 MobileServiceUser 字段以及实现由 IAuthenticate 接口所需的 Authenticate 方法来更新它,如下所示:
```csharp // Define an authenticated user. private MobileServiceUser user; public async Task<bool> Authenticate() { var success = false; var message = string.Empty; try { // Sign in with Facebook login using a server-managed flow. if (user == null) { user = await TodoItemManager.DefaultManager.CurrentClient .LoginAsync(UIApplication.SharedApplication.KeyWindow.RootViewController, MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}"); if (user != null) { message = string.Format("You are now signed-in as {0}.", user.UserId); success = true; } } } catch (Exception ex) { message = ex.Message; } // Display the success or failure message. UIAlertController avAlert = UIAlertController.Create("Sign-in result", message, UIAlertControllerStyle.Alert); avAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(avAlert, true, null); return success; } ```
如果使用 Facebook 以外的标识提供者,请为 [MobileServiceAuthenticationProvider] 选择其他值。
请按如下方式通过添加 OpenUrl 方法的重载来更新 AppDelegate 类:
```csharp public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) { if (TodoItemManager.DefaultManager.CurrentClient.ResumeWithURL(app, url, options)) return true; return base.OpenUrl(app, url, options); } ```
在调用
LoadApplication()
之前,将以下代码行添加到 FinishedLaunching 方法:```csharp App.Init(this); ```
此代码可确保在加载应用之前初始化验证器。
打开 Info.plist 并添加 URL 类型。 将 标识符 设置为所选名称,将 URL 方案 设置为应用的 URL 方案,将 角色 设置为“无”。
重新生成应用,运行它,然后使用所选的身份验证提供程序登录,并验证你能否以经过身份验证的用户身份访问数据。
将身份验证添加到 Windows 10(包括 Phone)应用项目
本部分介绍如何在 Windows 10 应用项目中实现 IAuthenticate 接口。 相同的步骤适用于通用 Windows 平台(UWP)项目,但使用 UWP 项目(带有指出的更改)。 如果不支持 Windows 设备,请跳过本部分。
在 Visual Studio 中,右键单击 UWP 项目,然后选择 “设置为启动项目”。
按 F5 键在调试器中启动项目,然后验证应用启动后是否确实抛出了一个状态码为401(未授权)的未处理异常。 发生 401 响应是因为后端上的访问仅限于授权用户。
打开 Windows 应用项目的MainPage.xaml.cs,并添加以下
using
语句:```csharp using Microsoft.WindowsAzure.MobileServices; using System.Threading.Tasks; using Windows.UI.Popups; using <your_Portable_Class_Library_namespace>; ```
将
<your_Portable_Class_Library_namespace>
替换为可移植类库的命名空间。更新 MainPage 类以实现 IAuthenticate 接口,如下所示:
public sealed partial class MainPage : IAuthenticate
通过添加 MobileServiceUser 字段和 IAuthenticate 接口所需的 Authenticate 方法更新 MainPage 类,如下所示:
```csharp // Define an authenticated user. private MobileServiceUser user; public async Task<bool> Authenticate() { string message = string.Empty; var success = false; try { // Sign in with Facebook login using a server-managed flow. if (user == null) { user = await TodoItemManager.DefaultManager.CurrentClient .LoginAsync(MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}"); if (user != null) { success = true; message = string.Format("You are now signed-in as {0}.", user.UserId); } } } catch (Exception ex) { message = string.Format("Authentication Failed: {0}", ex.Message); } // Display the success or failure message. await new MessageDialog(message, "Sign-in result").ShowAsync(); return success; } ```
如果使用 Facebook 以外的标识提供者,请为 MobileServiceAuthenticationProvider 选择其他值。
在调用
LoadApplication()
之前,在 MainPage 类的构造函数中添加以下代码行:```csharp // Initialize the authenticator before loading the app. <your_Portable_Class_Library_namespace>.App.Init(this); ```
将
<your_Portable_Class_Library_namespace>
替换为可移植类库的命名空间。如果使用 UWP,请将以下 OnActivated 方法重写添加到 App 类:
```csharp protected override void OnActivated(IActivatedEventArgs args) { base.OnActivated(args); if (args.Kind == ActivationKind.Protocol) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; MobileServiceClientExtensions.ResumeWithURL(TodoItemManager.DefaultManager.CurrentClient,protocolArgs.Uri); } } ```
打开 Package.appxmanifest 并添加 协议 声明。 将 显示名称 设置为所选的名称,并将 “名称 ”设置为应用的 URL 方案。
重新生成应用,运行它,然后使用所选的身份验证提供程序登录,并验证你能否以经过身份验证的用户身份访问数据。
后续步骤
完成此基本身份验证教程后,请考虑继续学习以下教程之一: