Skip to content

Commit 28056e1

Browse files
committed
[ENHANCEMENT] Ensure Stateless flag functions as designed for session management
1 parent 4ea1aca commit 28056e1

File tree

8 files changed

+80
-53
lines changed

8 files changed

+80
-53
lines changed

rls/packages/API.Library.6.1.18.nupkg

76.4 KB
Binary file not shown.

rls/packages/API.Library.6.1.19.nupkg

76.6 KB
Binary file not shown.

rls/packages/API.Library.6.1.20.nupkg

76.6 KB
Binary file not shown.

rls/packages/API.Library.6.1.21.nupkg

76.7 KB
Binary file not shown.

src/API.Library/API.Library.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
<PackageId>API.Library</PackageId>
1313
<Product>API Library</Product>
1414
<Copyright>Central Statistics Office, Ireland</Copyright>
15-
<Version>6.1.21</Version>
15+
<Version>6.1.22</Version>
1616
<Authors>Central Statistics Office, Ireland</Authors>
1717
<SignAssembly>False</SignAssembly>
1818
<RepositoryUrl>https://github.com/CSOIreland/Server-API-Library</RepositoryUrl>
1919
<PackageReleaseNotes>
20-
- [BUG FIX] Added cache storage of the key GET_WITH_CAS_TIMEOF_EXCEPTION key to store the datetime value of when the GetWithCas exception occurred.
21-
- [BUG FIX] Fixes for session to not be expired and System.ArgumentOutOfRangeException when calling GetWithCas.
20+
[ENHANCEMENT] Ensure Stateless flag functions as designed for session management
2221
</PackageReleaseNotes>
2322
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
2423
<RestoreLockedMode>true</RestoreLockedMode>

src/API.Library/Entities/API.Common.cs

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ public Common()
114114
//Log.Instance.Info("AD Username: " + ApiServicesHelper.ApiConfiguration.Settings["API_AD_USERNAME"]);
115115
//Log.Instance.Info("AD Password: ********"); // Hide API_AD_PASSWORD from logs
116116

117+
118+
117119
// Check if the request is Stateless
118120
if (Convert.ToBoolean(ApiServicesHelper.ApiConfiguration.Settings["API_STATELESS"]))
119121
{
@@ -122,7 +124,7 @@ public Common()
122124
if (userPricipalCache.hasData)
123125
{
124126
isAuthenticated = true;
125-
var userPricipalCacheDeserialized = Utility.JsonDeserialize_IgnoreLoopingReference<ExpandoObject>(userPricipalCache.data.ToString());
127+
var userPricipalCacheDeserialized = Utility.JsonDeserialize_IgnoreLoopingReference<ExpandoObject>(userPricipalCache.data.ToString());
126128
UserPrincipal = userPricipalCacheDeserialized == null ? null : userPricipalCacheDeserialized;
127129
Log.Instance.Info("Authentication retrieved from Cache");
128130
}
@@ -137,7 +139,7 @@ public Common()
137139
UserPrincipal = ApiServicesHelper.ActiveDirectory.CreateAPIUserPrincipalObject(UserPrincipal);
138140

139141
// Set the cache to expire at midnight
140-
if (ApiServicesHelper.CacheD.Store_BSO<dynamic>("API", "Common", "Authenticate", NetworkIdentity,Utility.JsonSerialize_IgnoreLoopingReference(UserPrincipal), DateTime.Today.AddDays(1)))
142+
if (ApiServicesHelper.CacheD.Store_BSO<dynamic>("API", "Common", "Authenticate", NetworkIdentity, Utility.JsonSerialize_IgnoreLoopingReference(UserPrincipal), DateTime.Today.AddDays(1)))
141143
{
142144
Log.Instance.Info("Authentication stored in Cache");
143145
}
@@ -152,26 +154,36 @@ public Common()
152154
// Call the SessionID to initiate the Session
153155
Log.Instance.Info("Session ID: " + context.Session.Id);
154156

155-
isAuthenticated = AuthenticateByType();
156-
157-
// Initiate a new Session only when authentication works.
158-
if (isAuthenticated != null)
157+
var user = context.Session.GetString(UserPrincipal_Container);
158+
if (user == null)
159159
{
160-
// Save the serialized userPrincipal in the Session
161-
//context.Session[UserPrincipal_Container] = Utility.JsonSerialize_IgnoreLoopingReference(UserPrincipal);
162-
Log.Instance.Info("Authentication stored in Session");
160+
isAuthenticated = AuthenticateByType();
161+
162+
// Initiate a new Session only when authentication works.
163+
if (isAuthenticated != null)
164+
{
165+
// Save the serialized userPrincipal in the Session
166+
167+
//set userprincipal to be a smaller object
168+
UserPrincipal = ApiServicesHelper.ActiveDirectory.CreateAPIUserPrincipalObject(UserPrincipal);
169+
string upString = Utility.JsonSerialize_IgnoreLoopingReference(UserPrincipal);
170+
context.Session.SetString(UserPrincipal_Container, upString);
171+
Log.Instance.Info("Authentication stored in Session");
172+
}
173+
163174
}
164-
}
165-
else
166-
{
167-
isAuthenticated = true;
168175

169-
// Call the SessionID to initiate the Session
170-
Log.Instance.Info("Session ID: " + context.Session.Id);
176+
else
177+
{
178+
isAuthenticated = true;
179+
180+
// Call the SessionID to initiate the Session
181+
Log.Instance.Info("Session ID: " + context.Session.Id);
182+
// Deserialise userPrincipal from Session
183+
UserPrincipal = Utility.JsonDeserialize_IgnoreLoopingReference(context.Session.GetString(UserPrincipal_Container));
184+
Log.Instance.Info("Authentication retrieved from Session");
185+
}
171186

172-
// Deserialise userPrincipal from Session
173-
//UserPrincipal = Utility.JsonDeserialize_IgnoreLoopingReference((string)(context.Session[UserPrincipal_Container]));
174-
Log.Instance.Info("Authentication retrieved from Session");
175187
}
176188
}
177189

@@ -252,7 +264,8 @@ public Common()
252264
else
253265
{
254266
//if account is enabled
255-
if(UserPrincipal.Enabled) {
267+
if (UserPrincipal.Enabled)
268+
{
256269
return true;
257270
}
258271
else
@@ -408,7 +421,8 @@ internal async Task returnResponseAsync(HttpContext context, string message, Can
408421
throw new TaskCanceledException();
409422
}
410423

411-
if (context.Response.HasStarted) {
424+
if (context.Response.HasStarted)
425+
{
412426
sourceToken.Cancel(true);
413427

414428
if (sourceToken.IsCancellationRequested)
@@ -447,24 +461,25 @@ internal Cookie CheckCookie(string SessionCookieName, HttpContext httpContext)
447461
//httpContext.Request.Headers.Add("Cookie", "session=\"84c2f0b319460ee991924908198d46795049c83f1ebdfcaf90bd899c8d9d0bd2\";");
448462

449463
Cookie sessionCookie = new Cookie();
450-
464+
451465
if (!string.IsNullOrEmpty(SessionCookieName))
452-
{
453-
//need to create a cookie using the value and the SessionCookieName
454-
string testSessionCookieValue = httpContext.Request.Cookies[SessionCookieName];
466+
{
467+
//need to create a cookie using the value and the SessionCookieName
468+
string testSessionCookieValue = httpContext.Request.Cookies[SessionCookieName];
455469

456-
if (!string.IsNullOrEmpty(testSessionCookieValue))
457-
{
458-
sessionCookie.Name = SessionCookieName;
459-
sessionCookie.Value = testSessionCookieValue;
460-
}
470+
if (!string.IsNullOrEmpty(testSessionCookieValue))
471+
{
472+
sessionCookie.Name = SessionCookieName;
473+
sessionCookie.Value = testSessionCookieValue;
474+
}
461475
}
462476
return sessionCookie;
463477
}
464478

465479
internal void GatherTraceInformation(dynamic apiRequest, Trace trace)
466480
{
467-
if (ApiServicesHelper.CacheConfig.API_CACHE_TRACE_ENABLED) {
481+
if (ApiServicesHelper.CacheConfig.API_CACHE_TRACE_ENABLED)
482+
{
468483
//gather trace information
469484
trace.TrcParams = MaskParameters(apiRequest.parameters.ToString());
470485
trace.TrcIp = apiRequest.ipAddress;
@@ -476,7 +491,7 @@ internal void GatherTraceInformation(dynamic apiRequest, Trace trace)
476491
trace.TrcUsername = apiRequest.userPrincipal.SamAccountName.ToString();
477492
}
478493
}
479-
}
494+
}
480495
}
481496

482497
/// <summary>

src/API.Library/Middleware/ServiceConfiguration.cs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Enyim.Caching;
2-
using Enyim.Caching.Configuration;
32
using log4net.Config;
43
using Microsoft.AspNetCore.Builder;
54
using Microsoft.AspNetCore.HttpOverrides;
@@ -15,38 +14,38 @@ public static class ServiceConfiguration
1514
public static IServiceCollection AddApiLibrary(this IServiceCollection service, WebApplicationBuilder builder)
1615
{
1716
var loggingOptions = builder.Configuration.GetSection("Log4NetCore").Get<Log4NetProviderOptions>();
18-
17+
1918
//log name of the machine for identification purposes
2019
log4net.GlobalContext.Properties["MachineName"] = System.Environment.MachineName;
2120
builder.Logging.AddLog4Net(loggingOptions);
22-
21+
2322
//watches for any changes to log4net config file
2423
XmlConfigurator.ConfigureAndWatch(new FileInfo(loggingOptions.Log4NetConfigFileName));
2524

2625
Log.Instance.Info("service configration started");
27-
26+
2827
// Add services to the container.
2928
builder.Services.Configure<ForwardedHeadersOptions>(options =>
3029
{
31-
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
30+
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
3231
});
33-
32+
3433
builder.Services.AddHttpContextAccessor();
3534

3635
service.Configure<CacheSettings>(builder.Configuration.GetSection("CacheSettings"));
37-
service.Configure<ADOSettings>(builder.Configuration.GetSection("ADOSettings"));
38-
service.Configure<APIConfig>(builder.Configuration.GetSection("API_Config"));
39-
service.Configure<APPConfig>(builder.Configuration.GetSection("APP_Config"));
40-
service.Configure<APISettings>(builder.Configuration.GetSection("API_SETTINGS"));
36+
service.Configure<ADOSettings>(builder.Configuration.GetSection("ADOSettings"));
37+
service.Configure<APIConfig>(builder.Configuration.GetSection("API_Config"));
38+
service.Configure<APPConfig>(builder.Configuration.GetSection("APP_Config"));
39+
service.Configure<APISettings>(builder.Configuration.GetSection("API_SETTINGS"));
4140
service.Configure<BlockedRequests>(builder.Configuration.GetSection("Blocked_Requests"));
4241
service.Configure<APIPerformanceSettings>(builder.Configuration.GetSection("APIPerformanceSettings"));
4342

4443
service.AddEnyimMemcached();
4544
service.AddSingleton<ICacheConfig, CacheConfig>();
46-
service.AddSingleton<IApiConfiguration, ApiConfiguration>();
47-
service.AddSingleton<IAppConfiguration, APPConfiguration>();
48-
service.AddSingleton<IWebUtility, WebUtility>();
49-
service.AddSingleton<IMemcachedClient, MemcachedClient>();
45+
service.AddSingleton<IApiConfiguration, ApiConfiguration>();
46+
service.AddSingleton<IAppConfiguration, APPConfiguration>();
47+
service.AddSingleton<IWebUtility, WebUtility>();
48+
service.AddSingleton<IMemcachedClient, MemcachedClient>();
5049
service.AddSingleton<ICacheD, MemCacheD>();
5150
service.AddSingleton<IActiveDirectory, ActiveDirectory>();
5251
service.AddSingleton<IFirebase, Firebase>();
@@ -58,6 +57,9 @@ public static IServiceCollection AddApiLibrary(this IServiceCollection service,
5857
service.AddSingleton<ICleanser, Cleanser>();
5958
service.AddSingleton<ISanitizer, Sanitizer>();
6059

60+
61+
62+
6163
var sp = service.BuildServiceProvider();
6264
var ADOSettings = sp.GetService<IOptions<ADOSettings>>();
6365
var APISettings = sp.GetService<IOptions<APISettings>>();
@@ -85,7 +87,7 @@ public static IServiceCollection AddApiLibrary(this IServiceCollection service,
8587

8688
//we need to load API config here as needed for application to work.
8789
ApiServicesHelper.ApiConfiguration = sp.GetRequiredService<IApiConfiguration>();
88-
if(ApiServicesHelper.ApiConfiguration.Settings == null)
90+
if (ApiServicesHelper.ApiConfiguration.Settings == null)
8991
{
9092
ApiServicesHelper.ApplicationLoaded = false;
9193
}
@@ -97,11 +99,22 @@ public static IServiceCollection AddApiLibrary(this IServiceCollection service,
9799
ApiServicesHelper.Sanitizer = sp.GetRequiredService<ISanitizer>();
98100
ApiServicesHelper.Cleanser = sp.GetRequiredService<ICleanser>();
99101

100-
101-
if (ApiServicesHelper.APPConfig.enabled && ApiServicesHelper.ApplicationLoaded)
102+
103+
if (ApiServicesHelper.APPConfig.enabled && ApiServicesHelper.ApplicationLoaded)
102104
{
103105
//load APP config here as if can't load application wont work
104-
ApiServicesHelper.AppConfiguration = sp.GetRequiredService<IAppConfiguration>();
106+
ApiServicesHelper.AppConfiguration = sp.GetRequiredService<IAppConfiguration>();
107+
}
108+
bool isStateless = Convert.ToBoolean(ApiServicesHelper.ApiConfiguration.Settings["API_STATELESS"]);
109+
if (!isStateless)
110+
{
111+
service.AddSession(options =>
112+
{
113+
options.IdleTimeout = TimeSpan.FromMinutes(30);//We set Time here
114+
options.Cookie.HttpOnly = true;
115+
options.Cookie.IsEssential = true;
116+
options.Cookie.Name = "apiSessionCookie";
117+
});
105118
}
106119

107120
Log.Instance.Info("All API setup completed");

test/API.Test/API.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</ItemGroup>
2020

2121
<ItemGroup>
22-
<PackageReference Include="API.Library" Version="6.1.17" />
22+
<PackageReference Include="API.Library" Version="6.1.18" />
2323
</ItemGroup>
2424

2525
<ItemGroup>

0 commit comments

Comments
 (0)