In this article, we will learn how to check if session variable is exist and redirect to login page if session expires.
We can achieve this using middleware, so I will explain you with 2 methods:-
1) Using only Middleware (Simplest Method)
2) Using Policy and Middleware
Method-1: Using Middleware (Simplest Method)
Here we will add a small code in middleware in Startup.cs and the work done. It will check if session value is null or not and redirect to login page. See below code in bold-
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//... Other Middlewares
app.UseSession();
app.Use(async (context, next) =>
{
string CurrentUserIDSession= context.Session.GetString("CurrentUserID");
if (!context.Request.Path.Value.Contains("/Account/Login"))
{
if (string.IsNullOrEmpty(CurrentUserIDSession))
{
var path = $"/Account/Login?ReturnUrl={context.Request.Path}";
context.Response.Redirect(path);
return;
}
}
await next();
});
//... Other Middlewares
}
Note:- Register Session Service in ConfigureServices method of Startup.cs as shown below:-
public void ConfigureServices(IServiceCollection services)
{
//... Other services
services.AddSession(options =>
{
options.Cookie.Name = "_aspnetCoreSession";
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.IsEssential = true;
});
//... Other services
}
Thats it !!
Method-2: Using Policy and Middleware
The logic behind is, we will create a policy "AuthorizeSessionPolicy" which will check session existence and return Fail and Succeed flag.
Then we will create a custom Middleware which will validate this policy, and if validation fails - HttpContext will redirect to Login Page with ReturnURL.
Note we are using Middleware to check the session globally which means in every request.
So refer below steps with code.
Steps:-
1) Create a Policy
2) Register the Policy in Startup.cs
3) Create a Custom Middleware Class which will check the policy
4) Call above Middleware in Configure method of Startup.cs to get called in every request
// =======================================================================
// Step-1: Create a Policy Class
// =======================================================================
public class AuthorizeWithSessionRequirement: IAuthorizationRequirement {
public AuthorizeWithSessionRequirement() {
}
}
public class AuthorizeSession: AuthorizationHandler < AuthorizeWithSessionRequirement > {
SignInManager < User > _signInManager;
SessionManager _sessionManager;
public AuthorizeSession(
SignInManager < User > signInManager,
SessionManager sessionManager) {
_signInManager = signInManager;
_sessionManager = sessionManager;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
AuthorizeWithSessionRequirement requirement) {
string lsUserId = _sessionManager.CurrentUserId;
if (string.IsNullOrEmpty(lsUserId)) {
_signInManager.SignOutAsync();
context.Fail();
} else {
context.Succeed(requirement);
}
//
return Task.CompletedTask;
}
}
// =======================================================================
// Step-2: Register Policy in Startup.cs
// =======================================================================
public void ConfigureServices(IServiceCollection services) {
services.AddAuthorization(options => {
options.AddPolicy("AuthorizeSessionPolicy", policy =>
policy.AddRequirements(new AuthorizeWithSessionRequirement()));
});
}
// =======================================================================
// Step-3: Create a Custom Middleware Class
// =======================================================================
public class CheckSessionExistMiddleware {
private readonly RequestDelegate _next;
public CheckSessionExistMiddleware(RequestDelegate next) {
_next = next;
}
public async Task Invoke(HttpContext context) {
if (!context.Request.Path.Value.Contains("/Account/Login")) {
var endPoint = context.Features.Get < IEndpointFeature > () ? .Endpoint; // To get Page
var authAttr = endPoint ? .Metadata ? .GetMetadata < AuthorizeAttribute > (); //To get Authorize attribute of page
// To check if page has authorize attribute with policy as "PolicyName"
if (authAttr != null && authAttr.Policy == "AuthorizeSessionPolicy") {
var authService = context.RequestServices.GetRequiredService < IAuthorizationService > ();
var result = await authService.AuthorizeAsync(context.User, context.GetRouteData(), authAttr.Policy);
if (!result.Succeeded) {
var path = $ "/Account/Login?ReturnUrl={context.Request.Path}";
context.Response.Redirect(path);
return;
}
}
}
await _next.Invoke(context);
}
}
public static class CheckSessionExistMiddlewareExtensions {
public static IApplicationBuilder UseCheckSessionExistMiddleware(this IApplicationBuilder builder) {
return builder.UseMiddleware < CheckSessionExistMiddleware > ();
}
}
// =======================================================================
// Step-4: Call above Middleware in Configure method of Startup.cs
// =======================================================================
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
// ... Other Middlewares
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseCheckSessionExistMiddleware();
app.UseAuthorization();
// ... Other Middlewares
}
// SessionManager Class
//================================================================
public class SessionManager
{
private readonly ISession _session;
public const string SessionKeyUserId = "_UserId";
public SessionManager(IHttpContextAccessor httpContextAccessor)
{
_session = httpContextAccessor.HttpContext.Session;
}
public void ClearSession()
{
// Clear all session. FYI - there is no Abandon method like ASP.Net WebForm
_session.Clear();
}
public string CurrentUserId
{
get
{
return _session.GetString(SessionKeyUserId) == null ? null : _session.GetString(SessionKeyUserId);
}
set
{
_session.SetString(SessionKeyUserId, value);
}
}
}
Thats it !!