Azure Active Directory Authentication to an API using ASP.NET Web Application and API using ASP.NET Core Web Application in Visual Studio 2019

How does Azure Active Directory Authentication work?
 
Step 1: 
Log in to Azure Active Directory

Step 2:
Successful
Azure Active Directory returns an access token
Unsuccessful
Azure Active Directory will deny you access

Step 3:
From your application you make a http request with the access token in the headers to the API
The API receives this token and goes to Azure Active Directory to check if this token is authorised.

Step 5:
Successful
If the API finds that the token is valid then you are granted access to the API and can use its methods such as GET< POST< PUT and DELETE
Unsuccessful
If the API finds that the token is invalid then you will be denied access to the API and will get a 401 unauthorised.



How to create an azure active directory authentication API using ASP.NET CORE Web Application with an Android demonstration

Step 1: API in Visual Studio
Creating the API
1a. In Visual Studio select "ASP.NET Core Web Application" and press create.
1b. Go to Authentication and press "Change" and select "work and schools account" and press ok (This sets up the Active Directory).
1c. Select "API" and press create.
Key info: Once these steps have been completed it creates an "App Registration" in your Azure portal for the API you have just created.
Altering the boilerplate API
1d. In “Startup.cs” add libraries:
- using Microsoft.AspNetCore.Mvc.Authorization;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
And change the default function “ConfigureServices” to look like this:
 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(o =>
            {
                o.Filters.Add(new AuthorizeFilter("default"));
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddAuthorization(o =>
            {
                o.AddPolicy("default", policy =>
                {
                    // Require the basic "Access app-name" claim by default
                    policy.RequireClaim("http://schemas.microsoft.com/identity/claims/scope", "user_impersonation");
                });
            });

            services
                .AddAuthentication(o =>
                {
                    o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(o =>
                {
                    o.Authority = Configuration["Authentication:Authority"];
                    o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        // Both App ID URI and client id are valid audiences in the access token
                        ValidAudiences = new List<string>
                        {
                        Configuration["Authentication:AppIdUri"],
                        Configuration["Authentication:ClientId"]
                        }
                    };
                });
            // Add claims transformation to split the scope claim value
            services.AddSingleton<IClaimsTransformation, AzureAdScopeClaimTransformation>();
        }
1e. Once the above is done you will notice a red line under “AzureAdScopeClaimTransformation” this is because we need to create this class.
Right click project → Add → Class (name it “AzureAdScopeClaimTransformation”) → Press Add
Once the created add the libraries:
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
And paste this into the class:
public class AzureAdScopeClaimTransformation : IClaimsTransformation
    {
        public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var scopeClaims = principal.FindAll("http://schemas.microsoft.com/identity/claims/scope").ToList();
            if (scopeClaims.Count != 1 || !scopeClaims[0].Value.Contains(' '))
            {
                // Caller has no scopes or has multiple scopes (already split)
                // or they have only one scope
                return Task.FromResult(principal);
            }

            Claim claim = scopeClaims[0];
            string[] scopes = claim.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            IEnumerable<Claim> claims = scopes.Select(s => new Claim("http://schemas.microsoft.com/identity/claims/scope", s));

            return Task.FromResult(new ClaimsPrincipal(new ClaimsIdentity(principal.Identity, claims)));
        }
    }


1f. In “AppSettings.Json” you need to add:
"AllowedHosts": "*",
"Authentication": {
    "Authority": "https://login.microsoftonline.com/{TenantId}",
    "ClientId": "{ApplicationId/ClientId}",
    "AppIdUri": "https://garethsanasheeappsinthesky.onmicrosoft.com/GarethApi210619"
  }

Step 2: In Azure Portal create new “App registration” for native application 
2a. Azure Active Directory → App registration (Legacy) → New Application Registration →
Enter a name of your choice
Application type: check native
Sign-On URL: https://localhost/ (you can choose whatever you like)
EXTRA INFO: Building native will not give you “API ID URI” (This is ok, its just to let you know.)
→ Press “Create”
2b. Select the native application you have just created from step above and press “Authentication”
Check “msal7e940c2d-6c27-462e-9511-618188cb8e99://auth”
Check “Accounts in this organizational directory only (Default Directory)”
Press “Save”
2c. Within the native application you are currently in press “API Permissions”
Add a permission → APIs my organization uses → Search and select for the API you created in step 1 → Check “user_impersonation” → Select “Add permission”

Step 3: Creating an App Service for a domain in Visual Studio 
3a. Right click the API project in Visual Studio → Select “Publish” → Follow the steps to create an App service → Press “Create” (Note: This takes a few minutes)
This will then open up the browser with your domain(https) and give you a 404 if you add “api/values” to the end of your domain(https) you will get a 401 unathroised (This is good!).
Key Info: Within your Azure portal it will create an App service app within App services 
Step 4: Linking the application with the API in Visual Studio
4a. Remember in step 1f in the “appsettings.json” we added this and now it is time to enter the correct information:
"AllowedHosts": "*",
"Authentication": {
    "Authority": "https://login.microsoftonline.com/{TenantId}",
    "ClientId": "{ApplicationId/ClientId}",
    "AppIdUri": "https://garethsanasheeappsinthesky.onmicrosoft.com/GarethApi210619"
  }

4b. Get the authority:
Your TenantId can be found somewhere within the “appsettings.json” file
Or
Go in Azure portal → Azure Active directory → app registrations → Select either the API or Native registration (They have the same TenantId) → You will see the TenantId in there.
4c. Get the ClientId:
Go to Azure portal → Azure Active directory → App registrations → Select the API registration →   You will see the ClientId in there
4d. Get the AppIdUri:
Go to Azure portal → Azure Active directory → App registrations (Legacy) → Select the API registration →   Settings → Properties →  You will see the AppIdUri in there
4e. The end result should look like this in you “appsettings.json”:
 "AllowedHosts": "*",
  "Authentication": {
    "Authority": "https://login.microsoftonline.com/a186d0b7-7480-40bd-a15b-5fad3eebf9fa",
    "ClientId": "04737b5b-b880-42f4-a31b-790388dff24a",
    "AppIdUri": "https://garethsanasheeappsinthesky.onmicrosoft.com/sanasheeApi270619"
  }

Step 5: Create the Android Project and make a call to the API with Azure active directory token which you get after signing in successfully 
5a. Go to Azure portal → Azure Active directory → App registrations → Select the native registration → quickstart → Select Android → follow the instructions to create Android project → Once completed open project in Android studio
5b. In main activity replaces the SCOPES Url with..
 Go to Azure portal → Azure Active directory → App registrations → Select the API registration → Expose an API → Copy scope and paste into android project to replace the current graph scope
5c. In main activity replaces the MSGRAPH_URL with..
Go to Azure portal → App Services → Select your App Service → You will URL on the screen → Copy and paste into Android project to replace the current msgraph_url
At the end of the URL add “api/values” so it will look like this:
https://sanasheeapi270619appservice.azurewebsites.net/api/values
5d. Before running the Android App, you need to publish the API in Visual Studio! Make sure you have added users to the Active directory in the AZure portal, as only those will be able to login.
5d. In Android Studio in the Volley request put a break point on the “onReponse” and “onError” when you sign in successfully you will hit the “onError” only because your return volley request is expecting an object but receives an array of values. If you see the error, you will see that the API has successfully got the data with authentication.

How to create an azure active directory authentication API using ASP.NET Web Application with an Android demonstration

Step 1: API in Visual Studio
1a. Create "ASP.NET Web Application(.NET Framework)"
1b. Change authentication to "Work and Schools"
1c. Select "Web API" and press "Create"
Key info: Once these steps have been completed it creates an "App Registration" in your Azure portal for the API you have just created.

Step 2: In Visual Studio run the project with "IIS Express" you will get an error
2a. Fix the error --> In "Web.config" you need to remove all the "<bindingRedirect ... />" --> Go to "Nuget Package Manager" and install "Newtonsoft.Json"
2b. Run with "ISS Express" and the project will run successfully.

Step 3: In Visual Studio publish the API to "App Services" you will get an error
3a. Fix the error --> Go to "Publish" and click the "pencil icon" which is next to release --> Click the "arrow" next to "File Publish Options" and check "Remove files at destination" --> press "Save"
3b. Press "publish" and the project will run successfully

Step 4: In Azure Portal create new “App registration” for native application 
4a. Azure Active Directory → App registration (Legacy) → New Application Registration →
Enter a name of your choice
Application type: check native
Sign-On URL: https://localhost/ (you can choose whatever you like)
EXTRA INFO: Building native will not give you “API ID URI” (This is ok, its just to let you know.)
→ Press “Create”
4b. Select the native application you have just created from step above and press “Authentication”
Check “msal7e940c2d-6c27-462e-9511-618188cb8e99://auth”
Check “Accounts in this organizational directory only (Default Directory)”
Press “Save”
4c. IMPORTANT: Within the native application you are currently in press “API Permissions”
Add a permission → APIs my organization uses → Search and select for the API you created in steps 3 → Check “user_impersonation” → Select “Add permission”

Comments

Popular posts from this blog

Big O asymptotic analysis/Big O notation

Basic Overview of Microsoft Azure?

Understanding the basics of REST API with HTTP and JSON