Identity

April 21, 2021 · View on GitHub

Table of Contents

Introduction

The Identity features add user authentication to your app and enable you to restrict your app (Forced Login) or provide restricted content (Optional Login) to authenticated users.

Both Forced Login and Optional Login use the Microsoft.Identity.Client (MSAL) NuGet package to authenticate the user using Azure Active Directory.

Once the user has been authenticated, the app will call the Microsoft Graph to retrieve user information. This info is displayed on the Navigation View (for project types Navigation Pane and Horizontal Navigation Pane), and also on the SettingsPage that also allows the user to log out.

Authentication Endpoints

You can choose between different ways to initialize the IdentityService, restricting hereby the allowed account types.

  1. InitializeWithAadAndPersonalMsAccounts() (Default) - allows Azure Active Directory Accounts and Personal Microsoft Accounts
  2. InitializeWithPersonalMsAccounts() - allows Personal Microsoft Accounts
  3. InitializeWithAadMultipleOrgs() - allows Azure Active Directory Accounts from any organization
  4. InitializeWithAadSingleOrg() - allows Azure Active Directory Accounts from the specified organization

The method you choose needs to allow the same account types as the ClientID you configure in Azure.

By choosing options 3 or 4 you can enable Windows Integrated Auth for domain joined machines. For more info regarding intergrated auth see Integrated Windows Authentication.

Understanding the authentication flow

The authentication process is initialized on app activation in the ActivationService (App.xaml.cs in Prism). First of all the IdentityService tries to get an AccessToken silently from the cache. This AccessToken is then passed to the Microsoft Graph to get user information.

If silently requesting the token from the cache fails, the interactive authentication process is triggered:

Forced Login

Apps with the Forced Login feature will be redirected to a LoginPage that can be used as a landing page and restricts the access to the rest of the pages.

Optional Login

Apps with Optional Login feature will show a LogIn button on the NavigationView (if available) and in the SettingsPage. While the user is not logged in only unrestricted pages are shown.

The following graphics explain the silent and interactive login process:

Silent LogIn

Identity Silent Login

Interactive LogIn

Interactive Silent Login

Further restricting access to authorized users

If you want to further restrict app access, the IdentityService provides a method called IsAuthorized() where you can include further authorization checks (i.e. check permissions in a database).

In Forced Login apps unauthorized users cannot log into the app, in Optional Login apps unauthorized users can login but will not see restricted pages.

Understanding the code

IdentityService (Core project)

This class is responsible for obtaining the AccessToken from the cache or via Windows Integrated or Interactive Auth. The class uses the MSAL NuGet library to connect with Azure Active Directory. The Identity service is uses a ClientID configured in the App.config. If you haven't done already create a ClientID following the steps on https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app and update the App.config IdentityClientId.

MicrosoftGraphService (Core project)

This class calls the Microsoft Graph to obtain the user information and the user photo. It can be extended adding methods that get info from other Microsoft Graph services.

UserDataService

This class consumes the MicrosoftGraphService and is responsible for storing the user information in the cache.

Forced Login code

Forced login adds a LoginPage with a button that allows the user to interactively login calling the IdentityService. When the user is logged in, the apps navigates to the ShellPage that gives access to the rest of the pages. When the user logs out, the LoginPage is shown again.

If the app is activated from activations other than LaunchActivation (for example DeepLinking or ToastNotification) the activation flow is intercepted by the IdentityService to ensure the user is logged in before redirecting to the requested page.

Optional Login code

Optional login allows the user to log in from the SettingsPage and the NavigationView (if available).

To restrict the access to a page and make it invisible and inaccessible for un-authenticated and un-authorized users you have to add the "Restricted" attribute to the page and limit its visibility on the ShellPage as shown below. (The MainPage and the SettingsPage should not be restricted):

1. Add the Restricted Attribute to the Views CodeBehind code

PageName.xaml.cs

namespace YourAppNamespace.Views
{
    [Restricted]
    public sealed partial class PageName : Page
    {
        public PageName()
        {
        }
    }
}

2. Bind the NavViewItems Visibility to the IsAuthorized property

ShellPage.xaml

<!--
Find MenuItems definition in page xaml code
-->
<winui:NavigationView.MenuItems>
    <!--
    Add Visibility to hide restricted pages.
    -->
    <winui:NavigationViewItem
        x:Uid="Shell_PageName"
        Icon="Document"
        helpers:NavHelper.NavigateTo="views:PageName"
        Visibility="{x:Bind ViewModel.IsAuthorized, Mode=OneWay}" />
</winui:NavigationView.MenuItems>

Calling the Microsoft.Graph

The MicrosoftGraphService class in the core project allows you to retrieve information of the user from the Microsoft Graph, calling the following endpoint using a HttpClient.

https://graph.microsoft.com/v1.0/

All calls need to add the AccessToken as an authentication header. If your app has a lot of interaction with the Graph, consider using the Microsoft Graph Client Library.

Terminology

In the context of authentication in general, there are a few concepts to keep in mind:

TermDefinition
JWT
  • JavaScript Web Token
  • A digitally signed, period-delimited string of data
  • Must be cryptographically validated by receiving application (usually an API call via HTTPS)
Access Token
  • The JWT returned by the auth provider, after the user has successfully authenticated
  • Passed to apps and services using HTTP Authorization header
  • Validated by the remote API, service, etc
Client ID
  • GUID assigned when app is registered in the AAD portal
  • Required for AAD authentication
Client Secret
  • A confidential key for server-side apps that act on behalf of a user or as a client independent of any user
  • Must be kept secure at all times
Integrated Auth
  • Also called Windows Integrated Authentication (WIA) silent authentication, or pass-through authentication
  • Uses the logged-in user’s domain credentials (Kerberos ticket) to silently authenticate the user via AAD
Kerberos
  • A network authentication standard and protocol used by Active Directory and AzureAD
Auth Endpoint
  • The URI the app uses to prompt the user to log in
Microsoft Graph
  • Microsoft’s web API surface for all things M365 and AzureAD
  • Not required for AAD authentication
Azure AD (AAD)
  • Microsoft’s hosted Active Directory service
  • Required for AAD authentication
Microsoft Account (MSA)
  • Consumer accounts used across Microsoft’s products and services (Xbox Live, Outlook.com, etc.)
  • Formerly called Passport and Windows LiveID
MSAL
  • Microsoft Authentication Library
  • Microsoft-owned, open-source .NET library for wrapping OIDC implementation specifically for AAD and consumer Microsoft accounts
Azure B2B
  • Business-to-business
  • B2B supports both consumer Microsoft accounts and AAD accounts from any tenant
  • Provides user policy and security controls identical to internal AAD
Azure B2C
  • Business-to-consumer
  • B2C supports AAD, consumer Microsoft accounts, and external account providers (e.g. Google, Facebook)
  • Serves as a middleman or proxy between AAD and external account providers
  • Uses a separate, segregated directory from B2B and internal AAD
OIDC
  • OpenID Connect
  • An open standard used by various authentication providers, including AAD
OAuth2
  • The previous open authentication standard; deprecated and superseded by OIDC
OpenID
  • The original open auth standard; deprecated and superseded by OAuth2

Additional resources