I am creating a .Net Core web API V3 project and in that project, I have a requirement:
On every request check the SESSION, if it is ACTIVE then proceed else STOP the request and throw BAD REQUEST error.
Now In my application, I have a SESSION table in my database and in that table I have a few columns among which I have
Active (bit),
Last Activity (Datetime(2)),
Ended (Datetime(2)) column
What I need:
1- I need to update LastActivity column on every REQUEST on API.
2- And in that context, we should validate that we have already set the session timeout value to 2 minutes in appSettings.json so then on every request we should first validate that if the time from LastActivity and current DateTime minutes is not greater then 2 minutes, if it is, then throws BadRequest error and stop the execution, else let it go and update the LastActivity column to current DateTime.
What I Have Already Done (And is not working)
using System;
using System.Linq;
using DataAccess.Dtos;
using DataAccess.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Service.Contracts;
namespace Motorlogs.API.Shared
{
public class SessionActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
ISessionService _ISessionService = null;
IConfiguration _IConfiguration = null;
if (LoggedInUser.SessionId != null)
{
Session session = _ISessionService.GetSessions(x => x.SID == LoggedInUser.SessionId).FirstOrDefault();
if (session != null)
{
if (session.Active == false)
{
context.Result = new BadRequestObjectResult("Session Expired! Please login again.");
return;
}
if (!session.LastActivity.HasValue)
{
session.LastActivity = DateTime.Now;
_ISessionService.UpdateSession(session);
}
else
{
var lastActivityTime = session.LastActivity;
var currentTime = DateTime.Now;
var requestDuration = currentTime.Subtract((DateTime)lastActivityTime);
var sessionTimeOutMinutes = TimeSpan.FromMinutes(int.Parse(_IConfiguration.GetSection("AppSettings:SessionExpiryTime").Value)).Minutes;
if (requestDuration.Minutes >= sessionTimeOutMinutes)
{
session.Ended = DateTime.Now;
session.Active = false;
_ISessionService.UpdateSession(session);
context.Result = new BadRequestObjectResult("Session Expired! Please login again.");
return;
}
else
{
session.LastActivity = DateTime.Now;
_ISessionService.UpdateSession(session);
}
}
}
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
// our code after action executes
}
}
}
And in Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MotorlogsContext>(x =>
x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc(option => option.EnableEndpointRouting = false)
//.AddNewtonsoftJson(options =>
// options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects)
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.ASCII.GetBytes(
Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout =
TimeSpan.FromMinutes(int.Parse(Configuration.GetSection("AppSettings:SessionExpiryTime")
.Value));
});
var identitySettingsSection = Configuration.GetSection("EmailConfiguration");
services.Configure<EmailConfiguration>(identitySettingsSection);
services.AddAutoMapper(typeof(Startup));
services.AddSignalR(hubOptions =>
{
hubOptions.EnableDetailedErrors = true;
hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(1);
});
services.AddHttpContextAccessor();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSignalR();
services.AddHostedService<NotificationsHostedService>();
// This is the line I added for my SessionActionFilter
services.AddScoped<SessionActionFilter>();
return ConfigureIoC(services);
}
Article I referred:
https://code-maze.com/action-filters-aspnetcore/
Thanks.