• Win10/UWP开发—凭据保险箱PasswordVault


    PasswordVault用户凭据保险箱其实并不算是Win10的新功能,早在Windows 8.0时代就已经存在了,本文仅仅是介绍在UWP应用中如何使用凭据保险箱进行安全存储和检索用户凭据。

    那么什么是凭据保险箱呢?简单的说就是开发者可以在用户输入完凭证(一般是用户名和密码),凭证有效的情况下将该凭证存储在叫做"凭据保险箱"里,该凭据保险箱里的用户凭据将会自动漫游到用户设备的Windows账户中并随时能够再次被App获取。

    例如:有一个UWP的App运行在PC上,某用户在使用该App时登录了自己的账户并允许将账户凭据保存在"凭据保险箱"中,那么当该用户再使用平板电脑、手机或者其他同一个Windows账户的Windows设备时第一次打开该App,我们就可以从Windows账户中将该用户的数据漫游到新设备进行用户登录的操作。

    说的简单点就是用户的账户和密码会被漫游到Windows账户中,日后及时是跨设备使用该App,只要设备Windows账户没变,就可以实现在新设备上快捷登陆的功能。

    要想使用"凭据保险箱",我们需要了解以下几个类:

    – Windows.Security.Credentials.PasswordVault 表示凭据的"凭据保险箱"

    保险箱的内容特定于应用程序或服务。应用程序和服务无法访问与其他应用程序或服务关联的凭据。

    – PasswordVault.Add(PasswordCredential credential); 添加一个凭证保险箱

    – PasswordVault.Remove(PasswordCredential credential); 移除一个凭证保险箱

    – PasswordVault.Retrieve(System.String resource, System.String userName); 读取一个凭证保险箱

    – PasswordVault.FindAllByResource(System.String resource); 搜索与指定资源相匹配的凭据保险箱

    – Windows.Security.Credentials.PasswordCredential 表示凭据对象

    – PasswordCredential.PasswordCredential(System.String resource, System.String userName, System.String password); 创建一个凭据对象

    – PasswordCredential.UserName 凭据对象存储的UserName

    – PasswordCredential.Resource 凭据对象所属的资源名

    – PasswordCredential.Password 凭据对象存储的密码

     

    我们通过例子来看一下"凭据保险箱"是如何工作的(注:本文不考虑实现 记住密码 自动登陆 功能

    首先创建一个UWP通用项目,

    然后新建一个LoginPage页面,并将起始页改为LoginPage页面

    在LoginPage上布局出一个登陆框如下:

    xaml代码:

     1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
     2     <StackPanel Margin="0,0,0,128" HorizontalAlignment="Center" VerticalAlignment="Center">
     3         <StackPanel Orientation="Horizontal">
     4             <TextBlock Text="账  户:"/>
     5             <TextBox Text="{x:Bind UserName,Mode=TwoWay}" PlaceholderText="请输入您的账户" Width="240"/>
     6         </StackPanel>
     7         <StackPanel Margin="0,4" Orientation="Horizontal">
     8             <TextBlock Text="密  码:"/>
     9             <PasswordBox PlaceholderText="请输入您的密码" Password="{x:Bind Psw,Mode=TwoWay}" Width="240"/>
    10         </StackPanel>
    11  
    12         <CheckBox IsChecked="{x:Bind RoamCredential,Mode=TwoWay}"  Content="漫游我的登录凭证" HorizontalAlignment="Right" ToolTipService.ToolTip="勾选漫游凭证后,您的登录信息将被漫游到本机WindowsLive账户"  />
    13  
    14         <Grid Margin="0,12,0,0" >
    15             <Button  Click="{x:Bind QuickLogin}" Content="WindowsLive快捷登陆"/>
    16             <Button Click="{x:Bind Login}" Content="登  录" HorizontalAlignment="Right"/>
    17         </Grid>
    18     </StackPanel>
    19 </Grid>

    后台代码中,我们先实现"登录按钮"的Click方法:

     1         private async void Login(object sender, RoutedEventArgs args)
     2         {
     3             // 假设做用户账户和密码的验证工作(这里不考虑登录是否成功 一律登录成功)
     4             await ShowLoding();
     5             if (RoamCredential != true) return;
     6             //添加用户凭证到 PasswordVault
     7             var vault = new PasswordVault();
     8             vault.Add(new PasswordCredential(
     9                 _resourceName, UserName, Psw));
    10         }
    11  
    12         /// <summary>
    13         /// 显示登陆中Tip 并跳转到MainPage
    14         /// </summary>
    15         /// <returns>Null</returns>
    16         private async Task ShowLoding()
    17         {
    18             var dialog = new ContentDialog
    19             {
    20                 Title = "提示",
    21                 Content = "正在登录",
    22                 IsPrimaryButtonEnabled = true
    23             };
    24 #pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
    25             dialog.ShowAsync();
    26 #pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
    27  
    28             await Task.Delay(2000);
    29             dialog.Content = "登录成功";
    30             await Task.Delay(1000);
    31             dialog.Hide();
    32             Frame.Navigate(typeof(MainPage), _userName);
    33         }

    假设用户的用户名和密码验证通过情况下,如果用户允许保存凭据到 "凭据保险箱",我们就可以使用PasswordVault对象的Add方法添加到"凭据保险箱"里一个PasswordCredential 凭据对象,然后跳转到MainPage,并传递用户名。

    当用户点击使用"Windows账户快捷登陆"按钮时,我们首先去检测在该App的ResourceName下,一共有几个用户凭据,如果有多个则需要让用户选择一个账户进行登陆,代码如下:

     1 private async void QuickLogin(object sender, RoutedEventArgs args)
     2 {
     3     var credential = await GetCredentialFromLocker();
     4     if (credential == null) return;
     5     UserName = credential.UserName;
     6     Psw = credential.Password;
     7     await ShowLoding();
     8 }
     9 /// <summary>
    10 /// 获取密码凭证
    11 /// </summary>
    12 /// <returns>PasswordCredential</returns>
    13 private async Task<PasswordCredential> GetCredentialFromLocker()
    14 {
    15     PasswordCredential credential = null;
    16  
    17     var vault = new PasswordVault();
    18     var credentialList = vault.FindAllByResource(_resourceName);
    19     if (credentialList.Count > 0)
    20     {
    21         if (credentialList.Count == 1)
    22         {
    23             credential = credentialList[0];
    24         }
    25         else
    26         {
    27             _defaultUserName = await GetDefaultUserNameUI(credentialList.Select(s => s.UserName));
    28             if (!string.IsNullOrEmpty(_defaultUserName))
    29             {
    30                 //读取凭证
    31                 credential = vault.Retrieve(_resourceName, _defaultUserName);
    32             }
    33         }
    34     }
    35  
    36     return credential;
    37 }
    38  
    39 /// <summary>
    40 /// 获取一个用户名,如果存在多个用户凭证则选择一个
    41 /// </summary>
    42 /// <param name="userList">用户名集合</param>
    43 /// <returns>UserName</returns>
    44 private async Task<string> GetDefaultUserNameUI(IEnumerable<string> userList)
    45 {
    46     var userName = string.Empty;
    47     var dialog = new ContentDialog
    48     {
    49         Title = "账户选择",
    50         IsPrimaryButtonEnabled = true,
    51         IsSecondaryButtonEnabled = true,
    52         BorderThickness = new Thickness(0, 0, 1, 1),
    53         PrimaryButtonText = "确定",
    54         SecondaryButtonText = "取消"
    55     };
    56     var sp = new StackPanel();
    57     var tb = new TextBlock { Text = "请选择您要登录哪个账户:" };
    58     var cm = new ComboBox();
    59     foreach (var user in userList)
    60     {
    61         // ReSharper disable once PossibleNullReferenceException
    62         cm.Items.Add(new TextBlock
    63         {
    64             Text = user
    65         });
    66     }
    67     cm.SelectedIndex = 0;
    68     sp.Children.Add(tb);
    69     sp.Children.Add(cm);
    70     dialog.Content = sp;
    71     dialog.PrimaryButtonClick += (s, a) =>
    72     {
    73         // ReSharper disable once PossibleNullReferenceException
    74         userName = (cm.SelectedItem as TextBlock).Text;
    75     };
    76     dialog.SecondaryButtonClick += (s, a) => { dialog.Hide(); };
    77     await dialog.ShowAsync();
    78     return userName;
    79 }

    至此我们的App就支持了使用“凭据保险箱”功能,只要Windows账户一致,不论在什么windows设备上我们都可以做快捷登陆,下面是效果(本机demo的Win账户是公司的账户,和自己的手机上账户不一致,没法演示跨设备,不过我们可以使用删除App重新安装的方式来查看凭据是否被漫游了,答案是肯定的)

    推荐一个UWP开发群:53078485 大家可以进来一起学习

  • 相关阅读:
    105个软件测试工具大放送
    2016年开源巨献:来自百度的71款开源项目
    开源代码:Http请求封装类库HttpLib介绍、使用说明
    C#的HTTP开发包 HttpLib
    dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.
    Windows平台分布式架构实践
    Windows平台下利用APM来做负载均衡方案
    C# .net dotnet属性定义属性,以提供显示明称,默认值
    细说ASP.NET Forms身份认证
    IIS 7.5 Application Warm-Up Module
  • 原文地址:https://www.cnblogs.com/Aran-Wang/p/4816378.html
Copyright © 2020-2023  润新知