Requirements for Microsoft account sign-in (XAML)
[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]
Your Windows Runtime apps using C++, C#, or Visual Basic can sign users in and out with their Microsoft accounts so that your app can access their data in Microsoft cloud services like Outlook.com and Microsoft OneDrive.
Apply these guidelines when you design your app's sign-in and sign-out experience so that it provides a user experience that's consistent with other Windows Runtime apps. These guidelines also help your app keep the user's data secure.
Important The tutorial in this topic demonstrates a Windows Store app. You can also add Microsoft services to a Windows Phone Store app. Since the Windows Phone user interface does not support flyouts, however, you have to use pages in a Windows Phone Store app to implement the features for which flyouts are used in this topic.
Overview
Accessing users' data from Microsoft cloud services like Outlook.com and OneDrive requires that users sign in with their Microsoft account and give consent to access the data that the app requires. To help users keep their data secure from other users of their computer, your Windows Store app should also make it possible for the user to sign out of the app. This topic describes how to do that.
Important If your app does not enable users to sign out, it will be able access the users' data whenever they open the app from the user account with which they first signed in. Although this provides a great convenience to users who never share or lose their computer, it presents a possible security vulnerability if the computer is used by another person or if the computer is stolen. For these reasons, your Windows Store app should always indicate when it is signed in to a user's account and provide the option for the user to sign out.
These steps describe at a high level how your app can access the user's profile info. To see the detailed instructions, start here.
Add settings commands to your app
Add these two entries in the app's Settings pane.
Account
The Account command in the Settings pane shows the Flyout in which users can sign in to and sign out of their Microsoft account.
Privacy policy
The Privacy command in the Settings pane shows the Flyout that contains your app's privacy policy.
Provide a privacy policy
For more info, see the Windows and Windows Phone Store Policies.
Sign the user in
Your app can do this automatically when it starts, or it can allow the user to sign in only when it needs access to data that is stored in Microsoft cloud services like Outlook.com and OneDrive. The procedure for each method is described later in Signing users in.
Sign the user out
Consider how your app will be used. If it accesses data that the user might consider sensitive, your app should sign the user out automatically to prevent unauthorized access. But if the app is used in a more secure environment, you could leave it up to the user to sign out manually by using the Account settings command. The procedure for each method is described later in Signing users out.
Important
Users should always understand when the app is connected to their Microsoft account and when it isn't.
Show the sign-in state in the app's UI
Add some type of indication to your app's UI to show users when they are signed in and the app can access their info.
Note It's important for your app to let users know when they are signed in. This could be done as simply as by displaying their name or by listing elements that come from data that is stored in their Microsoft cloud service. For example, if your app displays users' photos from their OneDrive, it could display a list of their photos when they are signed in, and a message that they need to sign in if they are not signed in.
Add the required settings
This section describes how to add the required settings commands to the Settings pane.
Create the Privacy Flyout.
In Microsoft Visual Studio, in Solution Explorer, right-click the app and select the Add > New Item... command to add a new SettingsFlyout control.
In the Add New Item browser, select Installed > Visual C# > Windows Store to list the available items.
Select Settings Flyout from the list, enter Privacy.xaml in the Name field, and click Add.
Open Privacy.xaml, replace the TextbBlock.Text element with this one, and change the specified elements to match your app.
<!-- Replace the app class name in x:Class and xmlns:local --> <!-- with the class name of your app --> <SettingsFlyout x:Class="App.Privacy" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" IconSource="Assets/SmallLogo.png" Title="Privacy" d:DesignWidth="346"> <!-- This StackPanel acts as a root panel for vertical layout of the content sections --> <StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" > <!-- The StackPanel(s) below define individual content sections --> <!-- Content Section 1--> <StackPanel Style="{StaticResource SettingsFlyoutSectionStyle}"> <!-- Section 1 header --> <TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Privacy statement" /> <!-- Section 1 body --> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,25" TextWrapping="Wrap"> <TextBlock.Text> Your privacy statement here. </TextBlock.Text> </TextBlock> </StackPanel> <!-- Define more Content Sections below as necessary --> </StackPanel> </SettingsFlyout>
Add the assembly reference and the Privacy Flyout to the Settings pane in the app’s App.xaml.cs file, so it’s visible to the user.
// add the assembly for the Settings flyout using Windows.UI.ApplicationSettings; using System.Threading.Tasks;
protected override void onWindowCreated(WindowCreatedEventArgs args) { SettingsPane.GetForCurrentView().CommandsRequested += onCommandsRequested; } void onCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs e) { SettingsCommand privacyCommand = new SettingsCommand("privacy", "Privacy", (handler) => { Privacy privacyFlyout = new Privacy(); privacyFlyout.Show(); }); e.Request.ApplicationCommands.Add(privacyCommand); }
Note You can build your app now to make sure everything is OK so far.
Create the Account Flyout with a sign-in button.
The code in this step defines the layout for the Account Flyout shown in this screen shot.
In Solution Explorer, right-click the app and use the Add > New Item command to add a new SettingsFlyout.
In the Add New Item browser, select Installed > Visual C# > Windows Store to list the available items.
Select Settings Flyout control from the list, enter Account.xaml in the Name field, and click Add.
Open Account.xaml, replace the SettingsFlyout element with this one, and change the specified elements to match your app.
<!-- Replace the app class name in x:Class and xmlns:local --> <!-- with the class name of your app --> <SettingsFlyout x:Class="App.Account" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" IconSource="Assets/SmallLogo.png" Title="Account" d:DesignWidth="346"> <!-- Content Section 1--> <StackPanel x:Name="accountName"> <TextBlock Name="userName" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="Wrap" Margin="0,0,0,25" Text="You're not signed in."/> <!-- both buttons are defined to occupy the same place in the UI --> <!-- however only one is visible at a time, to prevent flicker or confusion --> <!-- they are defined as Collapsed so neither is visibly by default --> <Button x:Name="signInBtn" Click="SignInClick" Content="Sign in" Visibility="Collapsed"/> <Button x:Name="signOutBtn" Click="SignOutClick" Content="Sign out" Visibility="Collapsed"/> </StackPanel> </SettingsFlyout>
Add the assembly reference and the Account Flyout to the Settings pane in the app's App.xaml.cs file, so its visible to the user.
Note Add this code to the
onCommandsRequested
method in App.xaml.cs.SettingsCommand accountCommand = new SettingsCommand("account", "Account", (handler) => { Account accountFlyout = new Account(); accountFlyout.Show(); }); e.Request.ApplicationCommands.Add(accountCommand); }
Note You can't build your app yet because you must first add the handlers for the Sign in and Sign out buttons. This is described in the next steps.
This step describes how to get info from the user's profile so you can use that info to fill in the text fields and show the correct button on the Account Flyout.
Add the references to the Live SDK, and then create a method to get the user's name from his or her Microsoft account profile and write it to a TextBlock object in the UI. The method will sign the user in, if requested.
Define this method in the app's main code file—App.xaml.cs, for example. This enables all the pages in your app to call the method to display the user's name (if the user is signed in to his or her Microsoft account), or display the message that the user isn't signed in (if her or she is not).
This example signs the user in with a wl_basic scope, which is the smallest scope necessary to access the user's profile info. To protect the user's data from unauthorized access, your app should request the most restrictive scope that allows access to the desired data.
Important It's important that your app get the user's sign-in status directly from the Live SDK and that it doesn't cache the value. This practice prevents your app's view of the user's sign-in state from getting out of sync with the user's actual sign-in state, which is managed by the Live SDK.
using Microsoft.Live;
public static async Task updateUserName (TextBlock userName, Boolean signIn) { try { // Open Live Connect SDK client. LiveAuthClient LCAuth = new LiveAuthClient(); LiveLoginResult LCLoginResult = await LCAuth.InitializeAsync(); try { LiveLoginResult loginResult = null; if (signIn) { // Sign in to the user's Microsoft account with the required scope. // // This call will display the Microsoft account sign-in screen if // the user is not already signed in to their Microsoft account // through Windows 8. // // This call will also display the consent dialog, if the user has // has not already given consent to this app to access the data // described by the scope. // // Change the parameter of LoginAsync to include the scopes // required by your app. loginResult = await LCAuth.LoginAsync(new string[] { "wl.basic" }); } else { // If we don't want the user to sign in, continue with the current // sign-in state. loginResult = LCLoginResult; } if (loginResult.Status == LiveConnectSessionStatus.Connected) { // Create a client session to get the profile data. LiveConnectClient connect = new LiveConnectClient(LCAuth.Session); // Get the profile info of the user. LiveOperationResult operationResult = await connect.GetAsync("me"); dynamic result = operationResult.Result; if (result != null) { // Update the text of the object passed in to the method. userName.Text = string.Join(" ", "Hello", result.name, "!"); } else { // Handle the case where the user name was not returned. } } else { // The user hasn't signed in so display this text // in place of his or her name. userName.Text = "You're not signed in."; } } catch (LiveAuthException exception) { // Handle the exception. } } catch (LiveAuthException exception) { // Handle the exception. } catch (LiveConnectException exception) { // Handle the exception. } }
Tip You can call this method from the code behind your display pages to show the user whether they are signed in to their Microsoft account or not.
Add the sign-in and sign-out logic to the Account.xaml.cs code-behind file.
Add the references to the Live SDK, and create a method to query the user's sign-in state and update the UI of the Account Flyout to match.
using Microsoft.Live; using System.Threading.Tasks;
private async Task SetNameField(Boolean login) { // If login == false, just update the name field. await App.updateUserName(this.userName, login); // Test to see if the user can sign out. Boolean userCanSignOut = true; LiveAuthClient LCAuth = new LiveAuthClient(); LiveLoginResult LCLoginResult = await LCAuth.InitializeAsync(); if (LCLoginResult.Status == LiveConnectSessionStatus.Connected) { userCanSignOut = LCAuth.CanLogout; } if (this.userName.Text.Equals("You're not signed in.")) { // Show sign-in button. signInBtn.Visibility = Windows.UI.Xaml.Visibility.Visible; signOutBtn.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } else { // Show sign-out button if they can sign out. signOutBtn.Visibility = (userCanSignOut ? Windows.UI.Xaml.Visibility.Visible : Windows.UI.Xaml.Visibility.Collapsed); signInBtn.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } }
Add this method call to the constructor
Account()
to initialize the Flyout when a user opens it from the Settings pane.SetNameField(false);
Add the code to handle the event that fires when the Sign in button is tapped.
This method calls
SetNameField
to sign the user in and update the Account Flyout UI.private async void SignInClick(object sender, RoutedEventArgs e) { // This call will sign the user in and update the Account flyout UI. await SetNameField(true); }
Add the code to sign the user out when the Sign out button is tapped.
private async void SignOutClick(object sender, RoutedEventArgs e) { try { // Initialize access to the Live Connect SDK. LiveAuthClient LCAuth = new LiveAuthClient(); LiveLoginResult LCLoginResult = await LCAuth.InitializeAsync(); // Sign the user out, if he or she is connected; // if not connected, skip this and just update the UI if (LCLoginResult.Status == LiveConnectSessionStatus.Connected) { LCAuth.Logout(); } // At this point, the user should be disconnected and signed out, so // update the UI. this.userName.Text = "You're not signed in."; // Show sign-in button. signInBtn.Visibility = Windows.UI.Xaml.Visibility.Visible; signOutBtn.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } catch (LiveConnectException x) { // Handle exception. } }
Build your app and test the SettingsFlyouts that you just added.
The Account and Privacy commands to the Settings pane should appear, as shown in this screen shot.
When the app runs and the user isn't signed in to his or her Microsoft account, the user will see a Flyout similar to this one when he or she taps the Account command in the Settings pane.
If the user taps the Sign in button, the following screens appear.
The Microsoft account sign-in UI.
The Live Connect consent UI, if the user hasn't already given consent to this app.
After the user has signed in and given consent, he or she returns to the app.
If the user is already signed in to a Microsoft account and is able to sign out, a Flyout similar to this one appears.
If the user is already signed in to a Microsoft account and is not able to sign out, a Flyout similar to this one appears.
After the user has signed in, update the app's UI to show the user's name.
Note This code examples in this step just define the Flyouts for the Settings pane. You'll need to add the markup and the code to your app's display pages to show the user's name.
Signing users in
There are two approaches to signing users in to your Windows Store app. The one you pick depends on when your app needs the user to sign in.
If your app works when the user is not signed in, but the user must sign in to enable specific scenarios or features, have them sign in through an Account UI from the Settings pane described earlier.
For more info about signing users in, see Signing users in in the Live Connect documentation.
If your app doesn't work or doesn't provide a complete experience until the user signs in, show the Microsoft account sign-in dialog immediately after the app starts. To show this dialog, call the Microsoft.Live.LiveAuthClient.LoginAsync method.
Here's an example.
public LiveConnectSession Session { get { return _session; } set { _session = value; } } private async void InitAuth() { if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) { authClient = new LiveAuthClient(); LiveLoginResult authResult = await authClient.LoginAsync(new List<string>() { "wl.signin", "wl.basic", "wl.skydrive" }); if (authResult.Status == LiveConnectSessionStatus.Connected) { this.Session = authResult.Session; } } }
For more info, see Signing users in in the Live Connect documentation.
If your app works without needing the user to sign in first, but provides specific commands that integrate with Microsoft cloud services like Outlook.com and OneDrive, your app can show the Microsoft account sign-in UI when such a command is given. For example, a photo-editing app might have a Save photo to OneDrive command in its app bar. To support this scenario, add the code from this example to the app bar command handler for that command to sign the user in to his or her Microsoft account just before the code to save the photo. (The photo-saving code is not shown in this example.)
Here's an example that signs the user in from an app bar command.
private void AppBarSaveButton_Click(object sender, RoutedEventArgs e) { InitAuth(); } private async void InitAuth() { if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) { authClient = new LiveAuthClient(); LiveLoginResult authResult = await authClient.LoginAsync(new List<string>() { "wl.signin", "wl.basic", "wl.skydrive" }); if (authResult.Status == LiveConnectSessionStatus.Connected) { // An app-level property for the session. App.Session = authResult.Session; } } }
With single sign-on, users see the sign-in UI or the consent UI only if they need to sign in or grant consent. If they are already signed in to their Microsoft account and have given consent for the app to access their data, they don't see any additional UI.
Important
Make sure it is clear to the user when they are signed in to their Microsoft account.
Signing users out
In Windows 8, if an app can connect to resources by using the user's Microsoft account, it should provide the user with a way to sign out.
Note If the user signs in to Windows 8 with a Microsoft account or a local or domain account that is connected to a Microsoft account, providing a custom sign-out button has no effect.
To sign a user out, call the Microsoft.Live.LiveAuthClient.Logout() method.
Things to avoid
Make sure your app:
- Doesn't display text, controls, or sign-in and sign-out dialogs other than those previously described here. Using the Microsoft account sign-in experience helps reassure your users that your app can't directly access their Microsoft account credentials.
- Doesn't display custom sign-in or sign-out controls anywhere other than the Settings pane or as part of the app's task-command flow.