What we will use
- OAuth 2.0 middleware
- ASP.NET WebAPI 2.2
- Authentication Project Template: Organization Account
- Azure Active Directory
- Native Application e.g. Windows Form App
- Azure AD Authentication Library (ADAL) for .NET 2.x
The ‘Authority’ / ‘Identity Provider’ – Azure AD
Resources often offload most of the authentication functions to an external services provider, commonly known as an authority or an identity provider.
With those functions out of the way, the only authentication task left is to verify that authentication succeeded at the authority. This typically involves examining a security token, a data fragment issued by an authority to a caller upon successful authentication.
Security tokens are usually crafted according to a specific format, digitally signed by a key that will unequivocally identify the issuing authority, and contain some data that uniquely ties the token to the target resource. When the resource receives a request, it looks for an accompanying token. If it finds one that meets the required validation attributes, the caller is authenticated.
Create a WebAPI Project with Organizational Accounts
- Cloud – Single Organization
- Domain/AD Tenant – yourorganization.onmicrosoft.com
- Access Level – Single Sign On (i.e. lets the directory issue tokens for your application)
- Other access level include “Read/ReadWrite Directory data” using the REST Graph API
Setup:
In Startup.Auth.cs
// ida:Tenant – yourorganization.onmicrosoft.com
// ida:Audience – https://yourorganization.onmicrosoft.com/MyWebAPIProjectName
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings[“ida:Tenant”],
TokenValidationParameters = new TokenValidationParameters {
ValidAudience = ConfigurationManager.AppSettings[“ida:Audience”]
},
});
Publish the WebAPI App.
The app.Use* naming convention adds a middleware implementation to the OWIN pipeline. The added middleware inspects the incoming request to see if the HTTP header Authorization contains a security token. If it finds a token, it validates the issuing authority, the integrity, expiration date.
If the token looks good, the middleware projects its content in a principal. If it isn’t, sends back an error code.
If there’s no token, the middleware simply lets the call go through without creating a principal (i.e. anonymous). [Authorize] decides whether the request should be served or access denied.
The Audience value is the identifier by which the Web API is known to Windows Azure AD. Any tokens carrying a different Audience are meant for another resource and should be rejected.
The middleware uses that Tenant property value to read all the other properties (such as which key should be used to verify the token’s signatures) that determine the validity of a token.
Register the Native Client App with Azure AD
- Go to Active Directory –> Application
- Add Application (Web Client / Native Client)
- Add Redirect URI
More AD configuration for the client app
- Click the Configure tab
- Copy the Client ID
- Add/Select the target WebAPI server application and then hit save
Create Native Client App
- Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
// Get token
AuthenticationContext ac = new AuthenticationContext(
// Azure -> AD -> Domain -> https://login.windows.net/ + AD tenant/domain name
“https://login.windows.net/yourorganization.onmicrosoft.com“);
AuthenticationResult ar =
ac.AcquireToken(
// WebAPIApp web.config ‘s ida:Audience
“https://yourorganization.onmicrosoft.com/MyWebAPI”,
// Azure -> AD -> Application -> clientapp’s CLIENT ID
“8a39841b-7dcc-4b92-b546-a0799bae312c”,
// Azure -> AD -> Application -> clientapp’s REDIRECT URIS
new Uri(“https://mynativeclient”));
// Call Web API
string authHeader = ar.CreateAuthorizationHeader();
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get, “https://mywebapi.azurewebsites.net/Api/Values”);
request.Headers.TryAddWithoutValidation(“Authorization”, authHeader);
HttpResponseMessage response = await client.SendAsync(request);
string responseString = await response.Content.ReadAsStringAsync();
MessageBox.Show(responseString);
When I provide the credentials of any valid user from my directory tenant, I get a token back. The subsequent code presents the token to the Web API in the request headers. The security middleware validates it. Because all validation parameters are a match, it sends back HTTP status code 200 with the results.
If click the button again. You’ll get a token back right away, without being prompted. That’s because ADAL has a built-in token cache that keeps track of the tokens. It even takes care of silently refreshing expired tokens whenever possible.
Reference: http://msdn.microsoft.com/en-us/magazine/dn463788.aspx
https://vincenthomedev.wordpress.com/2014/11/30/azure-active-directory-for-mvc-webapi/