services | platforms | author | level | client | service | endpoint |
---|---|---|---|---|---|---|
active-directory |
dotnet |
jmprieur |
300 |
ASP.NET Core 2.0 |
ASP.NET Core 2.0 |
AAD V1 |
This sample contains a web API running on ASP.NET Core 2.0 protected by Azure AD. The web API is accessed by an ASP.NET Core 2.0 web application on behalf of the signed-in user. The ASP.NET Web application uses the OpenID Connect middleware and the Active Directory Authentication Library (ADAL.NET) to obtain a JWT bearer token for the signed-in user using the OAuth 2.0 protocol. The bearer token is passed to the web API, which validates the token and authorizes the user using the JWT bearer authentication middleware.
For more information about how the protocols work in this scenario and other scenarios, see Authentication Scenarios for Azure AD.
This sample has been updated to ASP.NET Core 2.0. Looking for previous versions of this code sample? Check out the tags on the ASP.NET Core 1.0 branch.
The web API, TodoListService, maintains an in-memory collection of to-do items per authenticated user. The authenticated user carries the same to-do list across multiple instances of the web app in this sample as well as native clients like the .NET native (WPF) client.
The ASP.NET Core 2.0 web app, TodoListWebApp enables a user to:
- Sign in. The first time a user signs in, a consent screen prompts the user for permission to access TodoListService and obtain user profile information from Azure Active Directory. Since this is a web app, hosted in a browser, it can be that the user gets immediately signed-in benefiting from Single Sign On with other web applications.
- Select Todo List in the app's navigation bar. The user may then:
- See the list of to-do items exposed by Web API for the signed-in identity,
- Add more to-do items (buy clicking on Add item).
- Sign out.
On subsequent returns to the web app, the user's session is persisted locally in a cookie and reauthentication is not required.
Note
If you want to run this sample on Azure Government, see the "Azure Government Deviations" section at the bottom of this page.
- .NET Core for Windows
- Visual Studio 2017
- An Azure Active Directory (Azure AD) tenant
- A user account in the Azure AD tenant This sample will not work with a Microsoft account (formerly Windows Live account).
From your shell or command line:
git clone https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore.git
There are two projects in this sample. Each needs to be registered in your Azure AD tenant.
- Sign in to the Azure portal.
- On the top bar, click on the signed-in account. Under Directory, select the Azure AD tenant where the app will be registered.
- In the navigation on the left, select More Services >. Scroll down and select Azure Active Directory.
- Select App registrations and then select + New application registration.
- Enter TodoListService for Name. For Application type, select *Web app / API'. For Sign-on URL, enter the base URL for the sample web API project (by default
https://localhost:44351
). Select the Create button to create the app registration. - From the list of app registrations, select the newly created application, select Settings, and then select Properties. Note the following information for reference in later steps:
- The domain of the Azure AD tenant in App ID URI. Only the domain, such as
contoso.onmicrosoft.com
is required. Omit the rest of the URI. - Application ID
- The domain of the Azure AD tenant in App ID URI. Only the domain, such as
- Return to the list of app registrations. Select the Endpoints button. Note the GUID (formatted
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
) from any of the endpoint URLs. This is the Tenant ID. Omit the rest of the URL.
Note
By default, the list of app registrations is filtered to My apps. To see the app that was just registered, select All apps. in the filter dropdown near the top of the blade.
- Return to the list of app registrations. Select + New application registration.
- Enter TodoListWebApp for Name. For Application type, select Web app / API. For Sign-on URL, enter the base URL for the sample web app project (by default
http://localhost:17945/signin-oidc
). Select the Create button to create the app registration. - From the list of app registrations, select the newly created application, select Settings, and then select Properties. Note the Application ID for reference in later steps.
- On the same blade, set the
Logout Url
property tohttps://localhost:44371/Account/EndSession
. Select Save. - From the Settings blade, select Keys. Add a new key by entering a key description and duration of either 1 year or 2 years. Select Save. Note the displayed key value for later steps. Be sure the key value is copied correctly, as it is will not be displayed again. Should the key value be lost, a new key must be created.
- From the Settings blade, select Required permissions. Select + Add, and then select Select an API. Type TodoListService in the textbox and press Enter. Select the web API from the list and then select the Select button. Select Select Permissions. Tick the checkbox next to Access TodoListService and then select the Select button. Select the Done button.
- In the Settings blade, under API Access, select Required permissions. Click on the Grant Permissions and when prompted press Yes. Once the web app is granted access to the webapi you should see the following message: Successfully granted permissions to the application for your account. To grant permissions for all users, please have an admin consent to the application.
- Open the solution in Visual Studio.
- In the TodoListService project, open the
appsettings.json
file. - Find the
Domain
property and replace the value with the AAD tenant domain. - Find the
TenantId
property and replace the value with the Tenant ID. - Find the
ClientId
property and replace the value with the Application ID property of the TodoListService application.
Warning
Follow these steps carefully. The Application ID property of both app registrations are used below.
- In the TodoListWebApp project, open the
appsettings.json
file. - Find the
Domain
property and replace the value with the AAD tenant domain. - Find the
TenantId
property and replace the value with the Tenant ID. - Find the
ClientId
property and replace the value with the Application ID of the TodoListWebApp app. - Find the
ClientSecret
and replace the value with the key value for the TodoListWebApp app. - Find the
TodoListResourceId
property and replace the value with the Application ID of the TodoListService app
In the solution properties, set both projects as startup projects. Set TodoListService to run first. Clean the solution, rebuild it, and then run it.
On startup, the web API displays an empty web page. This is expected behavior.
Explore the sample by signing in into the web app, clicking on "Todo List", signing again if needed, adding items to the To Do list, signing-out, and starting again. Since the authenticated session is stored in a cookie, the application doesn't require logging in again if the previous session was never signed out.
Note
The To Do list is stored in memory in this sample. Each time the TodoListService API is stopped, any to-do lists are reset.
The code for the service is exactly the same as the service used in the active-directory-dotnet-native-aspnetcore sample. Please refer to that sample for more information.
The code for the ASP.NET web app is based on the code of the active-directory-dotnet-webapp-openidconnect-aspnetcore sample. Please read the "About The code" section of that sample first.
Then, based on that code, the following modifications were applied. This commit details the incremental changes described below:
- Update of the AzureAdOptions class to add a property to compute the
Authority
from theinstance
and thetenantID
, and adding two other configuration options forClientSecret
, theresourceId
of TodoListService (its clientId) and the base address for this service. - Added a
TodoListItem
in models to deserialize the Json sent by the TodoListService - Added a
NaiveSessionCache
class in a new Utils folder which serves as a token cache which livetime is the duration of the session. Updated theStartup.cs
file accordingly to add sessions. - Added a
TodoListController
and aTodo
view, as well as a "Todo List" entry in the toolbar of the Web API. This is where most of the interesting code is - Updated the
SignOut()
method of theAccountController
to clear the cache for the user when s/he signs-out. - Updated
AzureAdAuthenticationBuilderExtensions.cs
to request an authorization code, and redeem it, getting an access token to the Azure AD graph (https://graph.windows.com), so that the token cache contains a token for the user. This token will be used by theTodoController
to request another token for the TodoListService
This scenario is slightly different than the same scenario in ASP.NET (not Core). Note the following line in AzureAdAuthenticationBuilderExtensions.cs:
options.ResponseType = "id_token code";
Unlike ASP.NET, ASP.NET Core 2.0 uses an implicit flow by default. Without overriding the response type (default id_token), the OnTokenValidated
event is fired instead of OnAuthorizationCodeReceived
. The line above requests both id_token and code, so that OnTokenValidated
is called first. This ensures that context.Principal
has a non-null value representing the signed-in user when OnAuthorizeationCodeReceived
is called.
If you are using Visual Studio 2017
- Edit the TodoListService's properties (right click on
TodoListService.csproj
, and choose Properties) - In the Debug tab:
- Check the Launch browser field to
https://localhost:44351/api/todolist
- Change the App URL field to be
https://localhost:44351
as this is the URL registered in the Azure AD application representing our Web API. - Check the Enable SSL field
- Check the Launch browser field to
The same kind of modifications can be made on the TodoListWebApp.csproj
project.
Warning
Ensure that all of the app registration steps reflect any changes made to the URLs, or the sample won't function.
To this sample to Azure:
- Update the various URLs (reply URLs, Base URL) in the appsettings.json files
- Add Reply URLs pointing to the deployed location, for both applications in the Azure portal
In order to run this sample on Azure Government you can follow through the steps above with a few variations:
- Step 2:
- You must register this sample for your AAD Tenant in Azure Government by following Step 2 above in the Azure Government portal.
- Step 3:
- Before configuring the sample, you must make sure your Visual Studio is connected to Azure Government.
- Navigate to the appsettings.json files for both the TodoListService web API and TodoListWebApp web application. Replace the "Instance" property in the Azure AD section with
https://login.microsoftonline.us/
.
Once those changes have been accounted for, you should be able to run this sample on Azure Government.
The scenarios involving Azure Active directory with ASP.NET Core are described in ASP.Net Core | Security | Authentication | Azure Active Directory. From this page, you can access the related samples