Getting Started
Updated Wednesday, April 04, 2018
In this blog post we will add Restful web services using Web API 2.0 in MS Visual Studio, protect our APIs with Azure Active Directory using OAuth 2.0, OIDC, and JSON web tokens, allow implicit flow and Cross-Origin Resource Sharing (CORS) to a JavaScript front-end (in this case an Angular 4 client) to consume data from our web services.
The prerequisites required to follow this project are a basic understanding of Angular 2/4, Azure App Services, and ASP.Net Web APIs.
To get an understanding of the implicit authentication flow, Microsoft provides a helpful diagram as noted below.
General protocol diagram:
Prerequisite versions of the libraries/frameworks used in this project:
- Node >= 6.9.x
- NPM >= 3.x.x
- Angular CLI = 1.4.9 (4.4.6 LTS)
- If BootStrap is required for your project: Install Bootstrap by using the command: npm install bootstrap –save
- Add any css / javascript files as needed (css can be referenced in the .angular-cli.json "styles" section)
- If deployment is required through Visual Studio Online
- Setup a Git or TFS account
- Setup a Visual Studio Team Services account - https://www.visualstudio.com/team-services/
To begin, start by configuring Azure to host your domain, web applications, and Azure Active Directory registrations.
Azure
Overview:
- Create a domain (this is necessary if you are creating a new Azure Active Directory).
- Create two web applications (one for the client and one for the Web API backend).
- Register two new AAD (Azure Active Directory) Applications.
- Configure the applications.
- Add CORS origin from the Client URL (optional - CORS can be implemented within the Web API backend on controllers for more granular origin, header, and method permissions).
Create a domain (This can take several hours for Azure to finalize the domain) in most projects you will likely be working with a client who has an existing domain with users and admins already created:
1) To create the domain, click Virtual networks -> Add -> and fill in the required fields – Name, Address space, Subscription, Resource group, Location, Subnet, and Address range then click Create and wait until the domain is fully created.
Create two web applications (one for the client and one for the Web API backend):
1) Click on New -> Web + Mobile -> Web App.
2) Fill in the required fields for App Name, Subscription, Resource Group (Create New), OS, and App Service plan/Location (choose the nearest server) then click Create.
3) Repeat the steps above to create a second web application, use App names to differentiate between your Client and API web applications.
Register two new Azure Active Directory Applications (again one for the client and one for your backend API):
1) Click Azure Active Directory -> App registrations -> New application registration.
2) Fill in the required fields for Name, Application type (Web app / API), and Sign-on URL (the URL of the Client Web App created earlier) and click Create.
3) Repeat the registration steps above to create a second AAD registration, and again use Names to differentiate between your Client and API AAD registrations.
After successfully creating our domain, applications and registrations in Azure, we can configure them to work with Azure Active Directory, our client, and Web APIs.
Configure the newly created Azure applications:
Overview:
- Set the oauth2AllowImplicitFlow setting in the Manifest to true.
- Add Required Permissions to the API AAD.
- Change the Home page URLs to include SSL (https://).
- Change the App ID URI to be on your domain (https://yourDomain.onmicrosoft.com/yourClientOrAPIURL).
- Change the Home page and Reply URLs to include SSL (https://)
Set the oauth2AllowImplicitFlow setting in the Manifest to true:
This setting allows our client application to get tokens from Azure without performing a backend server credential exchange, so the authorized users can sign in, maintain session, and get tokens from our API all within our client-side code. To facilitate implicit flow, we can use a library such adal.js, but for our Angular 4 project we will use the angular-oauth2-oidc library to handle the flow and user identity as shown later in this tutorial.
1) Click on Azure Active Directory -> App registrations -> and click on your client application.
2) Click on Manifest to edit your registered AAD client.
3) On line 17 change “oauth2AllowImplicityFlow” from false to true.
Add Required Permissions:
Now that our client AAD is set to allow implicit flow, we need to add the required permissions from the API AAD to the Client AAD.
1) Click on Azure Active Directory -> App registrations -> and select your AAD client application registration.
2) Click on All settings -> Required permissions -> Add.
3) Click on “1 Select an API”, search for your API AAD in the search box (your API will not be visible until you specifically search for it).
4) Your API AAD will appear below the search box, click on your API then click the Select button.
5) Click on “2 Select permissions” -> check all permissions -> click the Select button.
Grant Permissions:
Finalize adding permissions by granting the permissions to the API AAD.
1) Click All Settings -> Required permissions -> select your newly added API AAD -> Click Grant Permissions
Change the Home page and Reply URLs (both client and API AAD Registered Apps) to SSL (https://) and Change the App ID URI to be on your domain e.g. (https://yourDomain.onmicrosoft.com/yourClientOrAPIURL):
1) Click All settings -> Properties
Change the App ID URI field to include SSL (https://) and make sure it is on your domain as shown below, https://hyoyoegmail.onmicrosoft.com/... (this URI uniquely identifies your API and Client). Keep note of this URI as it will be used to configure other settings.
Also add https:// to the Home page URL field (this is the URL your API and Client are published on).
Finally click Save.
Change the Home page and Reply URLs (both client and API AAD Registered Apps) to SSL (https://):
1) Click All settings -> Reply URLs
Your reply URLs should include your client web app URL (homepage) and your callback URL (YourHomepageURL/.auth/login/aad/callback) as shown below. Add these URLs if they do not already exist, and Add https:// to both.
Optionally add https://localhost to run in your local environment).
API example:
Client example:
Add CORS (Cross-Origin Resource Sharing) to the Client URL (optional - CORS can be implemented on the Web API backend on your API controllers for more granular origin, header, and method permissions):
We add CORS to explicitly allow our backend APIs to grant permission to access selected resources from a server on a different origin (domain).
1) Select your API App Service (Web App).
Click Dashboard -> Select your API app.
2) Scroll down to CORS and add your Client Web APP URL(s) and Localhost to run locally.
Click CORS -> in the textbox add your Homepage URL -> Click Save.
Creating our back-end Web APIs in Visual Studio
Web API 2.0:
Overview:
- Create a new Web API application with No Authentication.
- Update the default Values Controller or return the default values.
- Add Connected Services - Authentication with Azure Active Directory or Manually add the authentication code below and necessary packages.
- Add CORS (add CORS directly in the Web API Web App Service in Azure as shown above or optionally directly in your API controllers).
- Configure Web.config
- Configure WebApiConfig.cs
- Add the [Authorize] attribute to your controller.
Create a new Web API application with No Authentication:
Add Connected Services - Authentication with Azure Active Directory or Manually add authentication code and necessary packages:
The easiest way to get the packages and code to authenticate and validate is to Add Authentication with Azure Active Directory as a Connected Service.
1) After creating your Web API project, in Solution Explorer Click Connected Services.
Click Authentication with Azure Active Directory -> Enter your domain -> Enter your App ID URI (the unique API URI from Azure) -> Click Use settings from an existing Azure AD application… -> Click Finish.
If you are not able to add a Connected Service or do not have access to the AAD Domain, you will need to manually add the packages and Code necessary to authenticate.
1) Add the required NuGet Packages:
- Owin
- Owin.Host.SystemWeb
- Owin.Security
- Owin.Security.ActiveDirectory
- Owin.Security.Jwt
- Owin.Security.Oauth
- IdentityModel.Tokens.Jw
For CORS and Json support also add:
- AspNet.Cors
- AspNet.WebApi.Cors
- Json
After adding these packages your packages.config should be like the example below.
Example of packages.config:
[crayon-62b8711790066088700669/]
2) Add a Startup.cs class to the root of your project with the following code:
[crayon-62b8711790082101886587/]
3) In the WebApiConfig.cs class add CORS and Json support:
[crayon-62b8711790087650974520/]
4) In the Startup.Auth.cs class update the code as:
[crayon-62b871179008b037663249/]
5) In the Web.config add these app Settings:
[crayon-62b8711790090197881438/]
We can now update our Azure Active Directory API application with the values from our Web.config above so the server can communicate with our Web APIs:
Update the Web.Config file with the values below.
1) The ClientId is the Application ID of our AAD API registered application:
2) The Tenant is the Active Directory Domain / Directory located in the Dashboard:
3) The Audience is the AAD API App ID URI located in properties:
4) And the Password is the key we will generate:
In the settings of your API Web App Click Keys
5) While here in Azure we will generate the key necessary for our Web API.
Give the key a Description and select if you want it to expire.
Click Save, after saving, the key is generated and displayed.
6) Save this key somewhere because it will be hidden going forward.
Copy and paste the key value as the password value in your Web.config.
<add key="ida:Password" value="your generated key here" />
7) Add the [Authorize] attribute to the controllers you want to protect:
[crayon-62b8711790097732580273/]
oauth2 and oidc client side using Angular CLI 1.49 and Webpack:
We can now tackle our frontend setup and configuration.
Overview:
- Create a new Angular CLI application.
- Install necessary dependencies.
- Update app.module.ts.
- Update app.component.ts.
Create a new Angular CLI application:
Follow the QuickStart guide from - https://angular.io/guide/quickstart
e.g. ng new nameOfYourApp
Install necessary dependencies:
https://www.npmjs.com/package/angular-oauth2-oidc
Use the command: npm i angular-oauth2-oidc
After installing the angular-oauth2-oidc package we need to import the OAuthService and UrlHelperService.
Update the app.module.ts:
[crayon-62b871179009d963266886/]
Update the app.component.ts:
We will update the ConfigureAuth() function so the values will match your specific configuration, but these will be the minimum required properties to Login, redirect, logout, set session storage, validate tokens, and perform a silent refresh. Azure’s default token expiration time is 60 mins, so a token refresh is necessary for users to continue after an hour.
[crayon-62b87117900a2716429566/]
Back in Azure, we will need several values to fill in the ConfigureAuth() values above. These values can be found in the Azure Endpoints and well known configuration settings provided by Microsoft at: https://login.microsoftonline.com/YOURTENANTIDHERE/.well-known/openid-configuration
Take Note: To find the Tenant ID for the link above we need the Azure Active Directory Tenant ID. Azure lists the Tenant ID as Directory ID see the image below:
Click Azure Active Directory -> Properties -> the Directory ID is your Tenant ID.
Complete the ConfigureAuth() function values as below.
ConfigureAuth() values:
this.oauthService.jwks = https://login.microsoftonline.com/common/discovery/keys
this.oauthService.issuer = https://sts.windows.net/{yourTenantID}
this.oauthService.loginUrl = https://login.microsoftonline.com/{yourTenantID}/oauth2/authorize
this.oauthService.logoutUrl = https://login.microsoftonline.com/{yourTenantID}/oauth2/logout
this.oauthService.clientId = AAD Client Application ID
In your AAD Client settings use the Application ID.
this.oauthService.resource = AAD API App ID URI
In your AAD API
Click Azure Active Directory -> All settings -> Properties -> use your App ID URI.
Finally, setup an Angular Service, Component, and HTML view to get and display your API data.
Example Service:
[crayon-62b87117900b2914951376/]
Example Component:
[crayon-62b87117900f2892187704/]
Example HTML:
[crayon-62b87117900fc099051094/]
Example app.component.html
[crayon-62b8711790100040330608/]
Summary
If you’ve made it this far, congratulations! You now have a fully functional Rest API protected by Azure Active Directory, using OAuth 2.0, OIDC, and JSON web tokens.
This project flow is extremely useful in scenarios where your client has an existing Active Directory with requirements where web services are necessary.
From here, you could authorize any number of applications, such as a mobile application to get data from your AAD authorized APIs. This tutorial shows the possibilities of using Azure and Azure Active Directory to authenticate, pass user identity, and secure and deliver data using the modern approach of passing web tokens.
Resources:
Well known configuration settings provided by Microsoft:
https://login.microsoftonline.com/YOURTENANTIDHERE/.well-known/openid-configuration
Overview of OAuth2 per Microsoft:
Overview of OIDC per Microsoft:
https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-oidc
Angular-Oauth2-Oidc JavaScript library:
https://github.com/manfredsteyer/angular-oauth2-oidc
Check Token values:
Resources to take CI/CD to the next level with schedule releases:
https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/triggers
Resources to Protect from broken builds and implement code reviews:
https://docs.microsoft.com/en-us/vsts/git/branch-policies
Last updated:
04/04/2018
Users feedback ( 2 )