Single Sign-On in Asp.net with Microsoft Entra ID (Azure Active Directory)

Single Sign-On in Asp.net with Microsoft Entra ID (Azure Active Directory)

What is Single Sign-On or SSO?

Single Sign-On (SSO) is an authentication process that allows users to access multiple applications or systems with a single login credential. Instead of remembering and entering separate login credentials for each application, users authenticate once and gain access to all the connected systems without needing to log in again. For example, if you log in to Gmail and try to go to Google Drive, the browser will automatically redirect you to Drive without asking for authentication again because it is already signed in for Gmail.


What is Microsoft Entra ID?

Microsoft Entra ID is the new name of Azure Active Directory. Microsoft Entra ID is a cloud-based identity and access management service, that provides functionalities such as user authentication, access control, and identity protection for applications and services that run on the Microsoft Azure cloud platform and also for applications that integrate with it, such as ASP.NET Core applications.


App Registration

First, we have to register the app, If we go to the Azure Portal, search and then click on the "Microsoft Entra ID" we will be forwarded to the Default Directory page, on the left side we will get "App registration" link. (you can go there from Azure portal or by this link https://entra.microsoft.com)



The following page will open, providing an app name, then select the supported account type and Select your platform from (Public Client/native, Web, Single-page application (SPA)) and provide your redirect URI, it means after the authentication it will be redirected to this URI.



Now clicking on the register button app will be registered and you will be forwarded to an app detail page.



In the authentification link, you will be able to add multiple links, which means you can use this app from different applications, you have to add the redirected URI here.



On the Certificate & Secrets link, click on "Client Secrets", you can add client secrets from here, on the right side give a description and expiration time then add. (copy this secret it will be needed later in ASP.net project)



You can add API, which means you can add API so those APIs will be accessible by this identity.



The app is registered, and now you can add users in Active Directory/Microsoft Entra ID. Login here https://entra.microsoft.com, then go to Identity -> User and add new users. You can Add the Role and Group of the user here.



Now, go to the Identity-> Applications and select your registered app, here you will be able to add your users in your application, So now this user has access to this app.



From the Dashboard/Overview, click endpoint you will get all the links we need for different purposes


In the pink colour, you will get the Client ID, and Tenant ID, copy those IDs for your application, there we will be using those.

Create a New web application (I am using WebForm, but you can use this way in any type of web application). Add the following NuGet packages


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

Update your WebConfig to store a few important keys, so we will be easily use this when it is needed in our application

<appSettings>
  <add key="ClientId" value="Client-Id" />
  <add key="TenantId" value="Tenant-Id" />
  <add key="RedirectUri" value="https://your-dite-address" />
  <add key="PostLogoutRedirectUri" value="https://your-dite-address/" />
  <add key="ClientSecret" value="Client-Secret" />
</appSettings>        

If you are using Asp.net core then use this in Program.cs or Startup.cs or if you are using Framework then add a class called Startup.cs and add the following code,

using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System.Threading.Tasks;

[assembly: OwinStartup(typeof(KcbPractice.FW.WebForm.Startup))]
namespace KcbPractice.FW.WebForm  //your project's namespace will be here
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"],
                Authority = string.Format("https://login.microsoftonline.com/{0}", System.Configuration.ConfigurationManager.AppSettings["TenantId"]), //"https://login.microsoftonline.com/bd745e71-0a55-48ef-874c-30b6fdd7421d",
                RedirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"],
                PostLogoutRedirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"], 
                ClientSecret = System.Configuration.ConfigurationManager.AppSettings["ClientSecret"],
                ResponseType = OpenIdConnectResponseType.IdToken,
                TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = true
                },
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = context =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("/Error");
                        return Task.FromResult(0);
                    }
                }
            });
        }
    }
}        

Now create two pages, in this project, I have created Login.aspx and Default.aspx file. In my application, I set Login.Aspx as default. So when this application is run the Login.aspx.cs page will be executed first. Here page wise codes,

  1. Login.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="KcbPractice.FW.WebForm.Login" %>

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link rel="stylesheet"  integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <style>
        body, html {
            height: 100%;
            margin: 0;
        }

        .centered-form {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100%;
            background-color: #f2f2f2; /* Optional: to give a background color to the entire page */
        }

        .form-container {
            width: 350px;
            border: 1px solid lightgray;
            border-radius: 10px;
            padding: 20px;
            background-color: lightgray;
            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); /* Optional: to add a subtle shadow effect */
        }

            .form-container hr {
                border: 0;
                border-top: 1px solid #ccc;
                margin: 10px 0;
            }
    </style>
</head>
<body>
    <form id="form1" runat="server" class="centered-form">
        <div class="form-container">
            <asp:Label ID="lbnStatus" runat="server" Text="Please sign to enter the secured site througn MEI-SSO" CssClass="form-text"></asp:Label>
            <hr />
            <asp:Button ID="btnSignIn" runat="server" Text="Sign In" CssClass="btn btn-secondary" OnClick="btnSignIn_Click" />
        </div>
    </form>
</body>
</html>
        

2. Login.aspx.cs

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace KcbPractice.FW.WebForm
{
    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.IsAuthenticated)
            {
                Response.Redirect("~/Default.aspx");
            }
        }

        protected void btnSignIn_Click(object sender, EventArgs e)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties { RedirectUri = "/" },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType
                );
        }
    }
}        

3. Default.aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="KcbPractice.FW.WebForm._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <main>
        <section class="row" aria-labelledby="aspnetTitle">
            <h1 id="aspnetTitle">Kcb-Practice [FW WebForm]</h1>
            <hr />
        </section>

        <div class="row">
            <div>
                <h2>Welcome to this secured page!</h2>
                <asp:Label ID="lblUserName" runat="server" Text="Label"></asp:Label>
                <asp:Button ID="btnSignOut" runat="server" Text="Sign Out" CssClass="btn btn-danger" OnClick="btnSignOut_Click" />
            </div>
        </div>
    </main>

</asp:Content>        

4. Default.aspx.cs

using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Owin.Security.Cookies;
using System.Configuration;

namespace KcbPractice.FW.WebForm
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Request.IsAuthenticated)
            {
                Response.Redirect("~/Login.aspx");
            }
            else
            {
                if (!IsPostBack)
                {
                    if (Session["UserName"] == null && User.Identity.IsAuthenticated)
                    {
                        Session["UserName"] = User.Identity.Name;
                    }

                    lblUserName.Text = "Welcome, " + (string)Session["UserName"];
                }
            }
        }

        protected void btnSignOut_Click(object sender, EventArgs e)
        {
            HttpContext.Current.GetOwinContext().Authentication.SignOut(
                new AuthenticationProperties { RedirectUri = ConfigurationManager.AppSettings["PostLogoutRedirectUri"] },
                OpenIdConnectAuthenticationDefaults.AuthenticationType,
                CookieAuthenticationDefaults.AuthenticationType
            );
        }
    }
}        

Running the application:

The LonIn form where it is asking for sign-in, when you click on sign-in it challenges the identity and a Microsoft login screen will appear.

Provide the right email and password or related information, if it authenticates then it will be redirected to the Home/Default page.

Here you go, you are safely landed on the Home page, After authentication through "Microsoft Entra ID". If you log out it will then send you to the login page again.

My friend, that's all. Thanks for being with me so far.

Md. Kamruzzaman

Software Engineer | .NET | C# | Javascript | Angular | AWS | Problem Solver | Software Design

9 个月

Authentication Mughal Kartik Chandra Biswas

Rony Barua

SQA Lead at IT Magnet | ISTQB | CEH | CHFI | QA Automation | API Test | Talent Acquisition | Teacher | Mentor

9 个月

Good example

要查看或添加评论,请登录

Kartik Chandra Biswas的更多文章

社区洞察

其他会员也浏览了