PasswordVault用户凭据保险箱其实并不算是Win10的新功能,早在Windows 8.0时代就已经存在了,本文仅仅是介绍在UWP应用中如何使用凭据保险箱进行安全存储和检索用户凭据。windows
那么什么是凭据保险箱呢?简单的说就是开发者能够在用户输入完凭证(通常是用户名和密码),凭证有效的状况下将该凭证存储在叫作"凭据保险箱"里,该凭据保险箱里的用户凭据将会自动漫游到用户设备的Windows帐户中并随时可以再次被App获取。安全
例如:有一个UWP的App运行在PC上,某用户在使用该App时登陆了本身的帐户并容许将帐户凭据保存在"凭据保险箱"中,那么当该用户再使用平板电脑、手机或者其余同一个Windows帐户的Windows设备时第一次打开该App,咱们就能够从Windows帐户中将该用户的数据漫游到新设备进行用户登陆的操做。async
说的简单点就是用户的帐户和密码会被漫游到Windows帐户中,往后及时是跨设备使用该App,只要设备Windows帐户没变,就能够实如今新设备上快捷登录的功能。ide
要想使用"凭据保险箱",咱们须要了解如下几个类:布局
– Windows.Security.Credentials.PasswordVault 表示凭据的"凭据保险箱"学习 保险箱的内容特定于应用程序或服务。应用程序和服务没法访问与其余应用程序或服务关联的凭据。ui – PasswordVault.Add(PasswordCredential credential); 添加一个凭证保险箱spa – PasswordVault.Remove(PasswordCredential credential); 移除一个凭证保险箱rest – PasswordVault.Retrieve(System.String resource, System.String userName); 读取一个凭证保险箱code – 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 你们能够进来一块儿学习