How to do App Registration for Enterprise Application?

In this post we can see how to do an App Registration for a Web application so that it will become Enterprise Application.

Step 1  Open Azure Portal > Active Directory

Open Azure Portal > Go to Active Directory from Resources.

image

Step 2  Open App Registrations

Open App Registrations blade as shown below.

image

Step 3 Create New App Service

Click on the New Registration button. 

  • Enter Name for the service
  • Leave the default options
  • Enter the Redirect URI as the URL of your web application / web api

Click the Register button

Copy the Client ID  as displayed over there.

image

Step 3 Create Credentials

Go to the Certificates & secrets blade. 

  • Click on New client secret
  • Save changes

Copy the Password generated

image

Now you have the Client ID and the Client Secret for the App Registration.  Now any application authenticated using these will be given privilege of this App Registration.

Step 4  Open Enterprise Applications

Open Enterprise Applications blade from Active Directory.  Search for the name.

image

If you can find your Application – Congratulations!

You have just created an Enterprise Applications.  Now you can do the following & more with it.

  • Add Owners
  • Add Users
    • Internal & External
    • Enable Self-Servcie
  • Audit Logs
  • Troubleshoot

References

https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/what-is-application-management

Summary

In this post we have seen how to perform an App Registration.

C# 8.0 Features

C# 8.0 is available in .Net Core 3.0 & .Net Standard.

Using Declarations

Now we can use using as a declaration rather than as a block.

using var file = new System.IO.StreamWriter(“WriteLines2.txt”);

Here the variable file will be disposed after end of scope.

Static Local Functions

Static Local Functions can be created within a Method which will not consume any Instance variables.

int M()

{

int y = 5; int x = 7;

return Add(x, y);

static int Add(int left, int right) => left + right;

}

Default Interface Methods

We can add default methods in Interfaces.  This will help in later versions of Interfaces.

interface IDefaultInterface
{
     int GetAge()
     {
         return 18;
     }
}

New Switch Structure

public static RGBColor FromRainbow(Rainbow colorBand)

=> colorBand switch {

Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),

Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),

_ => throw new ArgumentException(message: “invalid enum value”, paramName: nameof(colorBand)), };

// Saves “case” statement

More

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

Minimal Code to Protect Web API with Azure AD

In this post we can see the most minimal code to protect a Web API with Azure AD.

This protected Web API can be used for both:

  • Frontend Flow with ID Token
  • Backend Flow with Access Token

Create App Registration

Create App Registration with ID Token & Access Token enabled.

Note down the Client ID & Tenant ID

Create Web API Project

Create a .net core web application, add a ToDo controller into it with get & post methods.

Configuration add the following section into app.config

“AzureActiveDirectory”: {
   “Instance”: “https://login.microsoftonline.com/”,
   “TenantId”: “YOUR-TENANT-ID”,
   “ClientId”: “YOUR-CLIENT-ID”
}

Startup Code

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace WebAPI
{
     public class StartupTest
     {
         public StartupTest(IConfiguration configuration)
         {
             Configuration = configuration;
         }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
         {
             var options = new AzureADOptions();
             Configuration.Bind(“AzureActiveDirectory”, options);

            services.AddAuthentication(op => { op.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; })
             .AddJwtBearer(op =>
             {
                 op.Authority = options.Instance + options.TenantId;
                 op.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                 {
                     ValidAudience = options.ClientId,
                     ValidateIssuer = false,
                     ValidateIssuerSigningKey = false
                 };
             });

            services.AddCors(o => o.AddPolicy(“MyPolicy”, builder =>
             {
                 builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
             }));

            services.AddMvc();
             services.Configure<MvcOptions>(op =>
             {
                 op.Filters.Add(new CorsAuthorizationFilterFactory(“CorsPolicy”));
             });
         }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
             else
             {
                 app.UseHsts();
             }

             app.UseHttpsRedirection();
             app.UseCors(“MyPolicy”);
             app.UseAuthentication();
             app.UseMvc();
         }
     }
}

Controller Code

[Authorize]
    [ApiController]
    [Route(“api/[controller]”)]
    [EnableCors(“CorsPolicy”)]
    public class TodoListController : ControllerBase

Testing

You can create a Client App with the same Client ID and get the ID Token to access the API.

You can create a Postman Request with same Client ID & Client Secret and get the Access Token to access the API.

Azure Active Directory Learnings–Zero to Production

In this post I would like to note down the AAD aspects.  This would be helpful for anyone who wanted to Integrate Authentication & Authorization with their applications.

Azure Active Directory

AAD is an Identity management system hosted in Microsoft Azure cloud.  It can offer authentication & authorization for applications.

AAD can provide Authentication & Authorization for Web Applications, Desktop Applications & Mobile Applications as well.

OAuth2 & OpenID Connect

OAuth2 is an Authorization protocol.

OpenID Connect can be used for both Authentication & Authorization

Comparison of SAML vs OAuth2 vs OIDC

image

App Registration for Frontend

App Registration + ID Token

App Registration for Backend

App Registration + Client Credential Flow

App Registration for Frontend & Backend

App Registration + ID Token + Access Token

Pro-Tools

Following are few tools than can help in your adventure:

Azure AD Error–Invalid Grant–Application is not assigned to a Role for applciation

ERROR

“error”: “invalid_grant”,

“error_description”: “AADSTS501051: Application ‘5669c008-20c0-4118-AAAAAAA(APP-01) is not assigned to a role for the application ‘5669c008-20c0-4118-8f45-AAAAAAAA'(APP-01).

“error_codes”: [501051]

SOLUTION 1

Go to Portal > Active Directory > Enterprise Applications > > Choose your App > Set User assignment required to No

image

SOLUTION 2

Go to Users > Add User

Azure App Identity & Service Principal

Azure Service Principal is a Security Identity used for Apps & Background Services.  It will accomplish the Role of a User Identity require by Applications.  It is similar to Service Accounts of Windows in the past.

Advantages

Advantages of App Identity are following:

  • Allow multiple Apps to use the Same Identity
  • Can use Certificate to Authenticate instead of Passwords
  • No Password expiry overheads
  • Can restrict read/write access

image On App Registration two objects are create – App object & Service Principal object.

Setting Access at Subscription Level

We can set Access to the Service Principal object at the Subscription level.  Go to Home > Subscriptions > Access Control (IAM)

image

In the appearing window choose the App Registration created jus now & Select the Role.

image

Save changes for completing the Role assignment.

Access Scope

Access Scope is set at the following levels.

  • Subscription Level
  • Resource Group Level
  • Resource Level

References

https://docs.microsoft.com/en-us/azure-stack/operator/azure-stack-create-service-principals?view=azs-1910

Enable Azure Active Directory for a .Net Core 2.2 Web Application

In this article we can see how to configure Azure Active Directory for a .Net Core 2.2 Web Application.

Step 1: Create new Web Application

Create new Web Application of .Net Core 2.2 version.

image

Add Nuget Package following:

  • Microsoft.IdentityModel.Clients.ActiveDirectory

image

Step 2: Run the Application

Run the application & Copy the URL of it.

Step 3: App Registration

You can Refer this application below.

https://jeanpaul.cloud/2019/12/13/how-to-do-app-registration-for-enterprise-application/

Step 4: App User

Add a new user to the Enterprise Application.

Step 5: Modify the Configuration File

Modify the Configuration File as following:

{
   “Authentication”: {
     “ClientId”: “CLIENT ID FROM APP REG”,
     “ClientSecret”: “CLIENT SECRET FROM APP REG”,
     “Authority”: https://login.microsoftonline.com/ACTIVE DIRECTORY GUID,
     “PostLogoutRedirectUri”: “https://localhost:44372/”,
     “CallbackPath”: “/signin-oidc”,
     “ResponseType”: “code id_token”
   }
}

Leave the last 2 parameters as it the default OIDC middleware parameters.

Step 6: Replace Startup.cs

Replace Startup.cs with the following code.

(mainly the changes are in ConfigureServices() and Configure() method)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace AADenableBlog
{
     public class Startup
     {
         public Startup(IConfiguration configuration)
         {
             Configuration = configuration;
         }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
         public void ConfigureServices(IServiceCollection services)
         {
             services.AddAuthentication(auth =>
             {
                 auth.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                 auth.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
             })
               .AddCookie()
               .AddOpenIdConnect(opts =>
               {
                   Configuration.GetSection(“Authentication”).Bind(opts);

                  opts.Events = new OpenIdConnectEvents
                   {
                       OnAuthorizationCodeReceived = async ctx =>
                       {
                           HttpRequest request = ctx.HttpContext.Request;

                          string currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                           var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);

                          var authContext = new AuthenticationContext(ctx.Options.Authority);

                          string resource = “https://graph.microsoft.com”;
                           AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                               ctx.ProtocolMessage.Code, new Uri(currentUri), credential, resource);

                          ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                       }
                   };
               });

            services.Configure<CookiePolicyOptions>(options =>
             {
                 options.CheckConsentNeeded = context => true;
                 options.MinimumSameSitePolicy = SameSiteMode.None;
             });

             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
         }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
             else
             {
                 app.UseExceptionHandler(“/Home/Error”);
                 app.UseHsts();
             }

            app.UseHttpsRedirection();
             app.UseStaticFiles();
             app.UseAuthentication();
             app.UseCookiePolicy();

            app.UseMvc(routes =>
             {
                 routes.MapRoute(
                     name: “default”,
                     template: “{controller=Home}/{action=Index}/{id?}”);
             });
         }
     }
}

Step 7: Modify Controller

Modify the Home Controller as following:

[Microsoft.AspNetCore.Authorization.Authorize]

public class HomeController : Controller

// This will ensure Login prompt will prompt whenever the Controller method is accessed.

Step 8: Run the Application

Run the application & It should prompt you for the Login.  Enter the Credentials.

You can see the Login prompt.

image

Enter your New User credentials and you will be redirected to the Home Screen.

Download

The source can be downloaded here.

https://azuretrendz.files.wordpress.com/2019/12/aadenableblog.zip

Summary

In this article we have seen how to configure Azure Active Directory for a .Net Core 2.2 Web Application.

How to Install Swagger for .Net 2.2 Web API?

I had a “WTHek” time installing Swagger, the documentation tool.

Solution

So here is how to install Swagger in the right way.

Create a new Web API project.

Create a new Web API project in .Net Core 2.2

Ensure it is compiling fine.

Run Package Manager

Go to your Web API project & Run Package Manager command

Install-Package Swashbuckle.AspNetCore -Version 5.0.0-rc4

Install-Package Microsoft.OpenApi.Models

Add Code to ConfigureServices() method

Towards the last.

services.AddSwaggerGen(c =>
{
c.SwaggerDoc(“v1”, new OpenApiInfo { Title = “My API”, Version = “v1” });
});

// Resolve namespace for OpenApiInfo

Add Code to Configure() method

app.UseSwagger();

app.UseSwaggerUI(c =>

{
c.SwaggerEndpoint(“/swagger/v1/swagger.json”, “API V1”);

});

 

Run the Application

 

You should be able to access the Swagger documentation as below:

http://localhost/swagger

More Debugging

If you missed any [HttpGet] attributes also swagger will give above “swagger.json” error.

Open the Output window to view which Controller method is causing trouble.

Azure API Management

Following are the advantages of Azure API Management

Platform Independence enabling multiple clients to call the API through Standard protocols.

Service Evolution enabling adding new functionalities regardless of the clients.

Discoverability enabling documentation on existing services Discoverable by clients.

Backward Compatibility to ensure old version clients are still supported

Security prevents from automated attacks

Caching for faster & cost effective responses

API-First Approach enables Designing application with API consumption in mind.

RESTful enabling usage of HTTP & Common HTTP Verbs GET, PUT, POST, DELETE for CRUD operations, Stateless Request Model enabling easier Scalability.