Win10/UWP開發—憑據保險箱PasswordVault

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 你們能夠進來一塊兒學習

相關文章
相關標籤/搜索