services | platforms | author | level | client | service | endpoint |
---|---|---|---|---|---|---|
active-directory |
dotnet |
jmprieur |
400 |
.NET 4.5 Web App (MVC) |
ASP.NET Web API |
AAD V1 |
This sample shows how to build an MVC web application that uses Azure AD for sign-in using the OpenID Connect protocol and provides Single Sign Out across web apps.
For more information about how the OpenID Connect protocol works in this scenario, see the OpenID Connect Session Management Specfication.
If you would like to get started immediately, skip this section and jump to How To Run The Sample.
This MVC 5 web application allows the user to sign in to the application with an AAD account. Once signed in, if the user signs out of another application that has been authenticated using the same AAD tenant, this application will automatically sign the user out and display a message notifying the user. Similarly, when the user signs out of this application, they will be signed out of any other applications that use the same AAD tenant and that have implemented Single Sign Out.
This sample will demonstrate the Single Sign Out capability by using the Azure Management Portal as a second application that uses AAD for authentication.
- Visual Studio 2017
- An Internet connection
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see How to get an Azure AD tenant
- A user account in your Azure AD tenant. This sample will not work with a Microsoft account (formerly Windows Live account). Therefore, if you signed in to the Azure portal with a Microsoft account and have never created a user account in your directory before, you need to do that now.
From your shell or command line:
git clone https://github.com/Azure-Samples/active-directory-dotnet-web-single-sign-out.git
Given that the name of the sample is pretty long, and so are the name of the referenced NuGet pacakges, you might want to clone it in a folder close to the root of your hard drive, to avoid file size limitations on Windows.
There are one projects in this sample. Each needs to be separately registered in your Azure AD tenant. To register these projects, you can:
- either follow the steps in the paragraphs below (Step 2 and Step 3)
- or use PowerShell scripts that:
- automatically create for you the Azure AD applications and related objects (passwords, permissions, dependencies)
- modify the Visual Studio projects' configuration files.
If you want to use this automation, read the instructions in App Creation Scripts
As a first step you'll need to:
- Sign in to the Azure portal.
- On the top bar, click on your account, and then on Switch Directory.
- Once the Directory + subscription pane opens, choose the Active Directory tenant where you wish to register your application, from the Favorites or All Directories list.
- Click on All services in the left-hand nav, and choose Azure Active Directory.
In the next steps, you might need the tenant name (or directory name) or the tenant ID (or directory ID). These are presented in the Properties of the Azure Active Directory window respectively as Name and Directory ID
-
In the Azure Active Directory pane, click on App registrations and choose New application registration.
-
Enter a friendly name for the application, for example 'WebApp-DistributedSignOut-DotNet' and select 'Web app / API' as the Application Type.
-
For the Sign-on URL, enter the base URL for the sample. By default, this sample uses
https://localhost:44308/
. -
Click Create to create the application.
-
In the succeeding page, Find the Application ID value and record it for later. You'll need it to configure the Visual Studio configuration file for this project.
-
Then click on Settings, and choose Properties.
-
For the App ID URI, replace the guid in the generated URI 'https://<your_tenant_name>/<guid>', with the name of your service, for example, 'https://<your_tenant_name>/WebApp-DistributedSignOut-DotNet' (replacing
<your_tenant_name>
with the name of your Azure AD tenant) -
From the Settings | Reply URLs page for your application, update the Reply URL for the application to be
https://localhost:44308/
-
For Logout URL, provide the value
https://localhost:44308/Account/EndSession
-
From the Settings menu, choose Keys and add a new entry in the Password section:
- Type a key description (of instance
app secret
), - Select a key duration of either In 1 year, In 2 years, or Never Expires.
- When you save this page, the key value will be displayed, copy, and save the value in a safe location.
- You'll need this key later to configure the project in Visual Studio. This key value will not be displayed again, nor retrievable by any other means, so record it as soon as it is visible from the Azure portal.
- Type a key description (of instance
-
Configure Permissions for your application. To that extent, in the Settings menu, choose the 'Required permissions' section and then, click on Add, then Select an API, and type
Microsoft Graph
in the textbox. Then, click on Select Permissions and select User.Read.
In the steps below, "ClientID" is the same as "Application ID" or "AppId".
Open the solution in Visual Studio to configure the projects
- Open the
WebApp-DistributedSignOut-DotNet\Web.Config
file - Find the app key
ida:Tenant
and replace the existing value with your Azure AD tenant name. - Find the app key
ida:ClientId
and replace the existing value with the application ID (clientId) of theWebApp-DistributedSignOut-DotNet
application copied from the Azure portal. - Find the app key
ida:AppKey
and replace the existing value with the key you saved during the creation of theWebApp-DistributedSignOut-DotNet
app, in the Azure portal. - Find the app key
ida:PostLogoutRedirectUri
and replace the existing value with the base address of the WebApp-DistributedSignOut-DotNet project (by defaulthttps://localhost:44308/
).
Clean the solution, rebuild the solution, and run it. NOTE: Be sure not to run the sample in Internet Explorer, or you will get unexpected behavior. Sign into the application by clicking one of the tabs, such as "About." Be sure to sign in with a user that can also sign in to the Azure Management Portal. Once signed in, sign in to the Azure Management Portal as well. Try signing out of either application; you will be signed out of the other in a matter of seconds.
For the most part, you can simply cut and paste the code from this sample into your OWIN application in order to provide Single Sign Out functionality. But for a deeper understanding of the code and the OpenID Connect Session Managment protocol, take a look at the following five files:
In _Layout.cshtml
, you simply need to render the _SingleSignOut.cshtml partial view, so that the Single Sign Out related javascript is loaded into every page in the application.
This partial view is where the majority of the action takes place. In order to know when to perform Single Sign Out, the application needs a way to check the status of the user's session with Azure AD. This could be achieved by polling AAD periodically, but would incur more network cost than is necessary. Instead, the application will periodically check the value of a cookie that is set by AAD on login, as directed by the OpenID Connect Session Management specfication. Only if the value of the cookie has changed will the application then submit a request to AAD to check the status of the user's session with AAD. AAD provides a "CheckSessionIframe" to peform this check for you that is used in this sample.
When a page in the application loads, the javascript loads the CheckSessionIframe in a hidden iFrame. On a periodic basis, it triggers the CheckSessionIFrame to check the AAD cookie and notify the application of any changes. If a change in the AAD session has been detected, the iFrame is pointed to AAD's authorize endpoint, submitting an authorization request to AAD without requring user interaction (since the iFrame is hidden, of course). The result of this authorization request will be processed by the OWIN OpenIDConnect Middleware, described below in Startup.Auth.cs
.
In AccountController.cs
, there are two actions to note. The SessionChanged
action is a shortcut that is used to construct the authorization request that is submitted to AAD. The javascript submits an ajax request to this action, which subsequently issues an OpenID Connect challenge. This challenge triggers OWIN to construct an authorization request and submit it to AAD. But instead of allowing OWIN to submit the authorization request, the request is intercepted in Startup.Auth.cs
's RedirectToIdentityProvider
notification and is returned to the originating javascript via SessionChanged
as the result of the ajax request. In this way, the javascript does not have to construct an authorization request on its own.
The other action to note is SingleSignOut
, which actually signs the user out of the application and displays a message telling the user that a Single Sign Out has occurred.
Presents the Single Sign Out occurred message to the user.
In Startup.Auth.cs
, two OpenIDConnectAuthenticationNotifications
callbacks are used to process the authorization request result from AAD. If the request fails, it can be interpreted as the user needing to reauthenticate with AAD (and that the user should be signed out of the application). OWIN triggers the AuthenticationFailed
callback, which signs the user out using the SingleSignOut
action.
If the authorization request succeeds, there are two possibilities. First, that the user is still authenticated with AAD and no Single Sign Out is necessary. Second, that the user is authenticated with AAD but as a different user than before. In this case, a Single Sign Out is necessary. In either case, OWIN triggers the AuthorizationCodeRecieved
callback, which handles each case individually.
Use Stack Overflow to get support from the community.
Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before.
Make sure that your questions or comments are tagged with [adal
dotnet
].
If you find a bug in the sample, please raise the issue on GitHub Issues.
To provide a recommendation, visit the following User Voice page.
If you'd like to contribute to this sample, see CONTRIBUTING.MD.
This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
For more information, check out the following links