将身份验证添加到 Xamarin.iOS 应用

概述

本主题说明如何通过客户端应用程序对应用服务移动应用的用户进行身份验证。 在本教程中,将使用应用服务支持的标识提供者向 Xamarin.iOS 快速入门项目添加身份验证。 在移动应用成功进行身份验证和授权后,将显示用户 ID 值,你将能够访问受限的表数据。

必须先完成本教程 创建 Xamarin.iOS 应用。 如果不使用下载的快速入门服务器项目,则必须将身份验证扩展包添加到项目中。 有关服务器扩展包的详细信息,请参阅 使用适用于 Azure 移动应用的 .NET 后端服务器 SDK

注册应用以进行身份验证并配置应用服务

首先,需要在标识提供者的站点上注册应用,然后在移动应用后端设置提供程序生成的凭据。

  1. 请根据提供商的具体说明配置您的首选身份提供商。

  2. 对要在应用中支持的每个提供商重复上述步骤。

将应用添加到允许的外部重定向 URL

安全身份验证要求为应用定义新的 URL 方案。 这样,身份验证系统就可以在身份验证过程完成后重定向回应用。 在本教程中,我们将在整个过程中使用 url 方案 appname。 但是,可以使用你选择的任何 URL 方案。 它应该是您移动应用程序独有的。 若要在服务器端启用重定向,请执行以下作:

  1. Azure 门户中,选择应用服务。

  2. 单击 身份验证/授权 菜单选项。

  3. 允许的外部重定向URL中,输入 url_scheme_of_your_app://easyauth.callback。 此字符串中的 url_scheme_of_your_app 是移动应用程序的 URL 方案。 它应遵循协议的正常 URL 规范(仅使用字母和数字,以字母开头)。 应记下所选字符串,因为需要在多个位置使用 URL 方案调整移动应用程序代码。

  4. 单击“确定”。

  5. 单击“ 保存”。

限制对经过身份验证的用户的权限

默认情况下,移动应用后端中的 API 可以匿名调用。 接下来,需要限制仅对经过身份验证的客户端的访问。

  • Node.js 后端(通过 Azure 门户)

    在移动应用设置中,单击“简易表” 并选择表。 单击 “更改权限”,选择 “仅限身份验证访问” 作为所有权限的设置,然后单击 “保存”

  • .NET 后端 (C#)

    在服务器项目中,导航至 Controllers>TodoItemController.cs。 将 [Authorize] 属性添加到 TodoItemController 类,如下所示。 若要仅限制对特定方法的访问,还可以仅将此属性应用于这些方法而不是类。 重新发布服务器项目。

      [Authorize]
      public class TodoItemController : TableController<TodoItem>
    
  • Node.js 后端(通过 Node.js 代码)

    若要要求对表访问进行身份验证,请将以下行添加到 Node.js 服务器脚本:

      table.access = 'authenticated';
    

    有关详细信息,请参阅 如何要求身份验证才能访问表。 若要了解如何从网站下载快速入门代码项目,请参阅 如何:使用 Git下载 Node.js 后端快速入门代码项目。

  • 在 Visual Studio 或 Xamarin Studio 中,在设备或模拟器上运行客户端项目。 验证应用启动时是否引发了状态代码为 401(未授权)的未经处理的异常。 错误事件被记录到调试器的控制台。 因此,在 Visual Studio 中,应在输出窗口中看到故障。

    发生此未经授权的失败是因为应用尝试以未经身份验证的用户身份访问移动应用后端。 TodoItem 表现在需要进行身份验证。

接下来,将更新客户端应用,以使用经过身份验证的用户从移动应用后端请求资源。

将身份验证添加到应用

在本部分中,你将修改应用以显示登录屏幕,然后再显示数据。 应用启动时,它不会连接到应用服务,也不会显示任何数据。 用户首次执行刷新手势后,将显示登录屏幕;成功登录后,将显示待办事项列表。

  1. 在客户端项目中,打开文件 QSTodoService.cs ,并将以下 using 语句和 MobileServiceUser 访问器添加到 QSTodoService 类:

    using UIKit;
    
    // Logged in user
    private MobileServiceUser user;
    public MobileServiceUser User { get { return user; } }
    
  2. 使用以下定义将名为 Authenticate 的新方法添加到 QSTodoService

    public async Task Authenticate(UIViewController view)
    {
        try
        {
            AppDelegate.ResumeWithURL = url => url.Scheme == "{url_scheme_of_your_app}" && client.ResumeWithURL(url);
            user = await client.LoginAsync(view, MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}");
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine (@"ERROR - AUTHENTICATION FAILED {0}", ex.Message);
        }
    }
    

    注释

    如果使用 Facebook 以外的标识提供者,请将上面传递给 LoginAsync 的值更改为以下值之一: MicrosoftAccountTwitterGoogleWindowsAzureActiveDirectory

  3. 打开 QSTodoListViewController.cs。 修改 ViewDidLoad 的方法定义,以在结尾处删除对 RefreshAsync() 的调用:

    public override async void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    
        todoService = QSTodoService.DefaultService;
        await todoService.InitializeStoreAsync();
    
        RefreshControl.ValueChanged += async (sender, e) => {
            await RefreshAsync();
        }
    
        // Comment out the call to RefreshAsync
        // await RefreshAsync();
    }
    
  4. 修改方法 RefreshAsync ,以便在 User 属性为 null 时进行身份验证。 在方法定义顶部添加以下代码:

    // start of RefreshAsync method
    if (todoService.User == null) {
        await QSTodoService.DefaultService.Authenticate(this);
        if (todoService.User == null) {
            Console.WriteLine("couldn't login!!");
            return;
        }
    }
    // rest of RefreshAsync method
    
  5. 打开 AppDelegate.cs,添加以下方法:

    public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
    {
        if (client.ResumeWithURL(app, url, options))
            return true;
        return base.OpenUrl(app, url, options);
    }
    
  6. 打开 Info.plist 文件,导航到“高级”部分中的 URL 类型。 现在配置 URL 类型的 标识符URL 方案 ,然后单击“ 添加 URL 类型”。 URL 方案 应与 {url_scheme_of_your_app} 相同。

  7. 在 Visual Studio 中,连接到 Mac 主机或 Visual Studio for Mac,运行面向设备或模拟器的客户端项目。 验证应用是否不显示任何数据。

    通过下拉项目列表来执行刷新手势,这将导致登录屏幕出现。 成功输入有效凭据后,应用将显示待办事项列表,并且可以对数据进行更新。