Azure AD Authentication with OWIN for ASP.NET WEB Forms Applicaiton - How to logout user after configurable inactive time

Padmasekhar Pottepalem 1 Reputation point
2022-01-28T02:46:03.497+00:00

We have an application which is build using ASP.NET WEB Forms (.NET Framework 4.6.2). Previously, we were using Windows authentication to authenticate user. Now, we want to change it to Azure AD authentication with MFA with OWIN (Open Id Connect) framework. I was able to do a POC till Azure AD authentication and MFA. However, we have another requirement that, Application should ask user for username and password to re-authenticate after 15 min in active time. I am unable to do this. Even, I am not sure whether it is possible with OpenId connect and Azure because I am new to Azure and SSO. Can someone please help me how I can achieve this? This is really important to us.

I have set Cookie expire time as well but, when cookie is expired it is internally re-authenticating user without asking username and password.

I have attached my Startup class.

using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Microsoft.Owin.Host.SystemWeb;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Notifications;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace AzureADWebForms
{
    public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
        //private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
        private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutUri"];
        private static string redirectUri = ConfigurationManager.AppSettings["ida:redirectUri"];
        //private string authority = aadInstance + tenantId;
        private string authority = string.Empty;
        public Startup()
        {
            authority = Path.Combine(aadInstance, tenantId);
            //authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, aadInstance, tenant);
        }


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

            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                ExpireTimeSpan = TimeSpan.FromMinutes(2),
                //SlidingExpiration = true,
                Provider = new CookieAuthenticationProvider
                {
                    OnResponseSignIn = OnCustomResponseSignIn,
                    OnValidateIdentity = OnMyCustomValidateIdentity
                }
            });

            app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                RedirectUri = redirectUri,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                Scope = OpenIdConnectScope.OpenIdProfile,
                //ResponseType = OpenIdConnectResponseType.IdToken,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                UseTokenLifetime = false,
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = OnAuthenticationFailed,
                    RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                    SecurityTokenValidated = OnSecurityTokenValidated 
                }

            });

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }

        private void OnCustomResponseSignIn(CookieResponseSignInContext context)
        {
            //context.Properties.AllowRefresh = true;
            //context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(2);

            var ticks = context.Options.SystemClock.UtcNow.AddHours(10).UtcTicks;
            context.Properties.Dictionary.Add("absolute", ticks.ToString());
        }

        private Task OnMyCustomValidateIdentity(CookieValidateIdentityContext context)
        {
            bool reject = true;
            string value;
            if (context.Properties.Dictionary.TryGetValue("absolute", out value))
            {
                long ticks;
                if (Int64.TryParse(value, out ticks))
                {
                    reject = context.Options.SystemClock.UtcNow.UtcTicks > ticks;
                }
            }
            if (reject)
            {
                context.RejectIdentity();
                // optionally clear cookie
                //ctx.OwinContext.Authentication.SignOut(ctx.Options.AuthenticationType);
            }

            return Task.FromResult(0);
        }


        private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification
Microsoft Security Microsoft Entra Microsoft Entra ID
{count} votes

1 answer

Sort by: Most helpful
  1. Shweta Mathur 30,296 Reputation points Microsoft Employee Moderator
    2022-01-28T12:26:17.737+00:00

    Hi @Padmasekhar Pottepalem ,

    Thanks for reaching out.

    ASP.net core provides ExpireTimespan which controls how much time the authentication ticket stored in the cookie will remain valid from the point it is created.

      .Services.ConfigureApplicationCookie(options =>  
        {  
            options.SlidingExpiration = false;  
            options.ExpireTimeSpan = TimeSpan.FromMinutes(15);  
        });  
    

    CookieAuthenticationOptions.ExpireTimespan is the option that allows you to set how long the issued cookie is valid for. As mentioned, the cookie is valid for 15 minutes from the time of creation. Once those 15 minutes are up the user will have to sign back in because the SlidingExpiration is set to false and it will not re-issued any request in halfway through ExpireTimespan.

    Also, a cookie-based authentication provider without ASP.NET Core Identity can also be used using absolute expiration time which can be set with ExpiresUtc.

    new AuthenticationProperties  
        {  
            IsPersistent = true,  
            ExpiresUtc = DateTime.UtcNow.AddMinutes(20)  
        });  
    

    You can try either of ExpireTimeSpan or ExprireUtc , However, when ExpiresUtc is set, it overrides the value of the ExpireTimeSpan option of CookieAuthenticationOptions,if set.

    Reference : Absolute Cookie Expiration

    Thanks,
    Shweta

    --------------------------

    Please remember to "Accept Answer" if answer helped you.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.