向 Windows 应用添加身份验证

本主题演示如何向移动应用添加基于云的身份验证。在本教程中,使用 Azure 应用服务支持的标识提供者向移动应用的通用 Windows 平台 (UWP) 快速入门项目添加身份验证。在移动应用后端成功进行身份验证和授权后,显示用户 ID 值。

本教程基于移动应用快速入门。必须先完成移动应用入门教程。

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

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

  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#):

    在服务器项目中,导航到“控制器” > “TodoItemController.cs”。 将 [Authorize] 属性添加到“TodoItemController”类,如下所示。 若要限制为仅可访问特定方法,还可只向这些方法应用此属性(而非类)。 重新发布服务器项目。

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

    若要访问表时需验证身份,请向 Node.js 服务器脚本添加以下行:

    table.access = 'authenticated';
    

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

现在,可以验证是否已禁用对后端的匿名访问。将 UWP 应用项目设为启动项目后,部署并运行该应用;验证启动该应用后,是否会引发状态代码为 401(“未授权”)的未处理异常。发生此异常的原因是应用尝试以未经身份验证的用户身份访问移动应用代码,但 TodoItem 表现在要求身份验证。

接下来,更新应用,以便在从应用服务请求资源之前对用户进行身份验证。

向应用程序添加身份验证

  1. 在 UWP 应用项目文件 MainPage.xaml.cs 中,添加以下代码片段:

    // Define a member variable for storing the signed-in user. 
    private MobileServiceUser user;
    
    // Define a method that performs the authentication process
    // using a Microsoft sign-in. 
    private async System.Threading.Tasks.Task<bool> AuthenticateAsync()
    {
        string message;
        bool success = false;
        try
        {
            // Change 'MobileService' to the name of your MobileServiceClient instance.
            // Sign-in using MicrosoftAccount authentication.
            user = await App.MobileService
                    .LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount, "{url_scheme_of_your_app}");
            message =
                string.Format("You are now signed in - {0}", user.UserId);
    
            success = true;
        }
        catch (InvalidOperationException)
        {
            message = "You must log in. Login Required";
        }
    
        var dialog = new MessageDialog(message);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
        return success;
    }
    

    此代码使用 MicrosoftAccount 登录对用户进行身份验证。 如果使用的标识提供者不是 MicrosoftAccount,请将上述 MobileServiceAuthenticationProvider 的值更改为提供者的值。

  2. 替换 MainPage.xaml.cs 中的 OnNavigatedTo() 方法。 接下来,向应用添加用于触发身份验证的“登录” 按钮。

     protected override async void OnNavigatedTo(NavigationEventArgs e)
     {
         if (e.Parameter is Uri)
         {
             App.MobileService.ResumeWithURL(e.Parameter as Uri);
         }
     }
    
  3. 将以下代码片段添加到 MainPage.xaml.cs:

    private async void ButtonLogin_Click(object sender, RoutedEventArgs e)
    {
        // Login the user and then load data from the mobile app.
        if (await AuthenticateAsync())
        {
            // Switch the buttons and load items from the mobile app.
            ButtonLogin.Visibility = Visibility.Collapsed;
            ButtonSave.Visibility = Visibility.Visible;
            //await InitLocalStoreAsync(); //offline sync support.
            await RefreshTodoItems();
        }
    }
    
  4. 打开 MainPage.xaml 项目文件,找到定义“保存”按钮的元素,将其替换为以下代码:

    <Button Name="ButtonSave" Visibility="Collapsed" Margin="0,8,8,0" 
            Click="ButtonSave_Click">
        <StackPanel Orientation="Horizontal">
            <SymbolIcon Symbol="Add"/>
            <TextBlock Margin="5">Save</TextBlock>
        </StackPanel>
    </Button>
    <Button Name="ButtonLogin" Visibility="Visible" Margin="0,8,8,0" 
            Click="ButtonLogin_Click" TabIndex="0">
        <StackPanel Orientation="Horizontal">
            <SymbolIcon Symbol="Permissions"/>
            <TextBlock Margin="5">Sign in</TextBlock> 
        </StackPanel>
    </Button>
    
  5. 将以下代码片段添加到 App.xaml.cs:

     protected override void OnActivated(IActivatedEventArgs args)
     {
         if (args.Kind == ActivationKind.Protocol)
         {
             ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;
             Frame content = Window.Current.Content as Frame;
             if (content.Content.GetType() == typeof(MainPage))
             {
                 content.Navigate(typeof(MainPage), protocolArgs.Uri);
             }
         }
         Window.Current.Activate();
         base.OnActivated(args);
     }
    
  6. 打开 Package.appxmanifest 文件,导航到“声明”,在“可用声明”下拉列表中,选择“协议”并单击“添加”按钮。 现在,配置协议声明的属性。 在“显示名称”中,添加要向应用程序的用户显示的名称。 在“名称”中,添加 {url_scheme_of_your_app}。
  7. 按 F5 键运行该应用,单击“登录”按钮,然后使用所选的标识提供者登录到该应用。 成功登录后,该应用运行时不会出错,用户能够查询后端,并对数据进行更新。

在客户端上存储身份验证令牌

前一示例显示了标准登录,这要求在该应用每次启动时客户端同时联系标识提供者和应用服务。 此方法不仅效率低下,而且如果很多客户尝试同时启动应用,会遇到关于使用率的问题。 更好的方法是缓存应用服务返回的授权令牌,并在使用基于提供者的登录之前首先尝试使用此令牌。

Note

无论使用的是客户端管理的还是服务管理的身份验证,都可以缓存应用服务颁发的令牌。本教程使用服务管理的身份验证。

后续步骤

完成此基本身份验证教程后,请考虑继续学习以下教程之一:

  • 为应用启用脱机同步 了解如何使用移动应用后端向应用添加脱机支持。 借助脱机同步,最终用户即使在没有网络连接时也能够与移动应用进行交互(查看、添加或修改数据)。