(ASP.NET Framework +OWIN OpenID Connect + Auth code flow)

Overview:

In this post,we will demonstrate an ASP.NET web application that can sign in users with Azure Active Directory (Azure AD) accounts.

Authetication Flow

The below section gives an overview on how Authentication flow works in the solution.

  • The web browser sends a request to your site.
  • The site redirects to prompt for credentials.
  • Upon successful credential input,
  • An access token and redirect URL are sent back to the ASP.NET Web App.
  • The ASP.NET Web App receives the access token and then access the ASP.net Web App

OWIN middleware NuGet packages

Microsoft recommends you use the Microsoft.Identity.Web.OWIN NuGet package when developing a web API with ASP.NET.

You can set up the authentication pipeline with cookie-based authentication by using OpenID Connect in ASP.NET with OWIN middleware packages.

You can install these packages by running the following commands in Package Manager Console within Visual Studio:

Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Host.SystemWeb

OWIN startup class

The OWIN middleware uses a startup class that runs when the hosting process starts. In this quickstart, the startup.cs file is in the root folder. The following code shows the parameters that this quickstart uses:

public void Configuration(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(newCookieAuthenticationOptions());
    app.UseOpenIdConnectAuthentication(
        newOpenIdConnectAuthenticationOptions
        {
            // Sets the client ID, authority, and redirect URI as obtained from Web.configClientId = clientId,
            Authority = authority,
            RedirectUri = redirectUri,
            // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it’s using the home pagePostLogoutRedirectUri = redirectUri,
            Scope = OpenIdConnectScope.OpenIdProfile,
            // ResponseType is set to request the code id_token, which contains basic information about the signed-in userResponseType = OpenIdConnectResponseType.CodeIdToken,
            // ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application// To only allow users from a single organization, set ValidateIssuer to true and the ‘tenant’ setting in Web.config to the tenant name// To allow users from only a list of specific organizations, set ValidateIssuer to true and use the ValidIssuers parameterTokenValidationParameters = newTokenValidationParameters()
            {
                ValidateIssuer = false// Simplification (see note below)},
            // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to the OnAuthenticationFailed methodNotifications = newOpenIdConnectAuthenticationNotifications
            {
                AuthenticationFailed = OnAuthenticationFailed
            }
        }
    );
}

WhereDescription    
ClientIdThe application ID from the application registered in the Azure portal.
AuthorityThe security token service (STS) endpoint for the user to authenticate. It’s usually https://login.microsoftonline.com/{tenant}/v2.0 for the public cloud. In that URL, {tenant} is the name of your tenant, your tenant ID, or common for a reference to the common endpoint. (The common endpoint is used for multitenant applications.)
RedirectUriThe URL where users are sent after authentication against the Microsoft identity platform.
PostLogoutRedirectUriThe URL where users are sent after signing off.
ScopeThe list of scopes being requested, separated by spaces.
ResponseTypeThe request that the response from authentication contains an authorization code and an ID token.
TokenValidationParametersA list of parameters for token validation. In this case, ValidateIssuer is set to false to indicate that it can accept sign-ins from any personal, work, or school account type.
NotificationsA list of delegates that can be run on OpenIdConnect messages.

Authentication challenge

You can force a user to sign in by requesting an authentication challenge in your controller:

DEMO

Tutorial: Register an application with the Microsoft identity platform – Microsoft identity platform | Microsoft Learn

Tutorial: Prepare a web application for authentication – Microsoft identity platform | Microsoft Learn

Tutorial: Add sign in to an application – Microsoft identity platform | Microsoft Learn

Tutorial: Call an API and display the results – Microsoft identity platform | Microsoft Learn

Call the API and display the results

Under Pages, open the Index.cshtml.cs file and replace the entire contents of the file with the following snippet. Check that the project namespace matches your project name.

  1. using System.Text.Json;
  2. using Microsoft.AspNetCore.Mvc.RazorPages;
  3. using Microsoft.Identity.Web;
  4. using Microsoft.Identity.Abstractions;
  5.  namespace sign_in_webapp.Pages;
  6.  [AuthorizeForScopes(ScopeKeySection = “DownstreamApi:Scopes”)]
  7. public class IndexModel : PageModel
  8. {
  9.     private readonly ILogger<IndexModel> _logger;
  10.  
  11.     private readonly IDownstreamApi  _downstreamWebApi;
  12.  
  13.     public IndexModel(ILogger<IndexModel> logger,
  14.                         IDownstreamApi  downstreamWebApi)
  15.     {
  16.         _logger = logger;
  17.         _downstreamWebApi = downstreamWebApi;
  18.     }
  19.    public async Task OnGet()
  20.     {
  21.         using var response = await _downstreamWebApi.CallApiForUserAsync(“DownstreamApi”).ConfigureAwait(false);
  22.         if (response.StatusCode == System.Net.HttpStatusCode.OK)
  23.         {
  24.             var apiResult = await response.Content.ReadFromJsonAsync<JsonDocument>().ConfigureAwait(false);
  25.             ViewData[“ApiResult”] = JsonSerializer.Serialize(apiResult, new JsonSerializerOptions { WriteIndented = true });
  26.         }
  27.         else
  28.         {
  29.             var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
  30.             throw new HttpRequestException($”Invalid status code in the HttpResponseMessage: {response.StatusCode}: {error}”);
  31.         }
  32.     }
  33. }

Open Index.cshtml and add the following code to the bottom of the file. This handles how the information received from the API is displayed:

<p>Before rendering the page, the Page Model was able to make a call to Microsoft Graph’s <code>/me</code> API for your user and received the following:</p>

<p><pre><code class=”language-js”>@ViewData[“ApiResult”]</code></pre></p>

<p>Refreshing this page will continue to use the cached access token acquired for Microsoft Graph, which is valid for future page views will attempt to refresh this token as it nears its expiration.</p>

Test the application

The following screenshot appears, indicating that you have signed in to the application and have accessed your profile details from the Microsoft Graph API.

Conclusion

In conclusion, the Microsoft identity platform offers robust authentication and authorization capabilities for developers. Whether you’re creating workforce-facing apps or customer-facing services, understanding the platform’s features and following the quickstarts will empower you to build secure and reliable applications.

Happy coding! 🚀🔐👨‍💻

References:

Quickstart: Sign in to a web app & call an API – ASP.NET – Microsoft identity platform | Microsoft Learn

https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-web-app-aspnet-sign-in#how-the-sample-works

https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-web-app-dotnet-register-app

https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-web-app-dotnet-prepare-app?tabs=visual-studio

https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-web-app-dotnet-sign-in-users?tabs=visual-studio

https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-web-app-dotnet-call-api?tabs=visual-studio%2Cdotnet6

Leave a Reply

Discover more from Rajeev Singh | Coder, Blogger, YouTuber

Subscribe now to keep reading and get access to the full archive.

Continue reading