diff --git a/src/Authentication/Controllers/LogoutController.cs b/src/Authentication/Controllers/LogoutController.cs
index a95ecb3c..b8182d38 100644
--- a/src/Authentication/Controllers/LogoutController.cs
+++ b/src/Authentication/Controllers/LogoutController.cs
@@ -96,6 +96,8 @@ public ActionResult FrontchannelLogout()
CookieOptions opt = new CookieOptions() { Domain = _generalSettings.HostName, Secure = true, HttpOnly = true };
Response.Cookies.Delete(_generalSettings.SblAuthCookieName, opt);
Response.Cookies.Delete(_generalSettings.JwtCookieName, opt);
+ string tokenCookie = Request.Cookies[_generalSettings.JwtCookieName];
+ EventlogHelper.CreateAuthenticationEvent(_featureManager, _eventLog, tokenCookie, AuthenticationEventType.Logout);
return Ok();
}
diff --git a/src/Authentication/Helpers/EventlogHelper.cs b/src/Authentication/Helpers/EventlogHelper.cs
index e9c46bd5..3860b0b4 100644
--- a/src/Authentication/Helpers/EventlogHelper.cs
+++ b/src/Authentication/Helpers/EventlogHelper.cs
@@ -26,7 +26,7 @@ public static class EventlogHelper
/// token in the authentication request
/// authentication event type
public async static Task CreateAuthenticationEvent(IFeatureManager featureManager, IEventLog eventLog, string jwtToken, AuthenticationEventType eventType)
- {
+ {
if (await featureManager.IsEnabledAsync(FeatureFlags.AuditLog))
{
AuthenticationEvent authenticationEvent = MapAuthenticationEvent(jwtToken, eventType);
diff --git a/test/Altinn.Platform.Authentication.Tests/Controllers/LogoutControllerTests.cs b/test/Altinn.Platform.Authentication.Tests/Controllers/LogoutControllerTests.cs
index 9f7fd65a..063aa42d 100644
--- a/test/Altinn.Platform.Authentication.Tests/Controllers/LogoutControllerTests.cs
+++ b/test/Altinn.Platform.Authentication.Tests/Controllers/LogoutControllerTests.cs
@@ -25,6 +25,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using Microsoft.FeatureManagement;
using Moq;
using Xunit;
@@ -139,11 +140,15 @@ public async Task Logout_LogedIn_RedirectToSBL_ExternalAuthenticationMethod()
string issuer = "www.altinn.no";
claims.Add(new Claim("originaliss", "uidp", ClaimValueTypes.String, issuer));
claims.Add(new Claim("amr", AuthenticationMethod.BankID.ToString(), ClaimValueTypes.String, issuer));
- claims.Add(new Claim("acr", SecurityLevel.Sensitive.ToString(), ClaimValueTypes.String, issuer));
+ claims.Add(new Claim("acr", "Level4", ClaimValueTypes.String, issuer));
string token = PrincipalUtil.GetToken(1337, claims);
- HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object);
+ Mock eventQueue = new Mock();
+ eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny()));
+ AuthenticationEvent expectedAuthenticationEvent = GetAuthenticationEvent(AuthenticationMethod.BankID, SecurityLevel.VerySensitive, null, AuthenticationEventType.Logout, "1337");
+
+ HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object, eventQueue.Object);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "/authentication/api/v1/logout");
SetupUtil.AddAuthCookie(requestMessage, token);
@@ -159,6 +164,8 @@ public async Task Logout_LogedIn_RedirectToSBL_ExternalAuthenticationMethod()
{
Assert.Equal("https://idporten.azurewebsites.net/api/v1/logout", values.First());
}
+
+ AssertAuthenticationEvent(eventQueue, expectedAuthenticationEvent, Moq.Times.Once());
}
///
@@ -209,7 +216,16 @@ public async Task Logout_FrontChannelOK()
string token = PrincipalUtil.GetToken(1337, claims);
- HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object);
+ Mock eventQueue = new Mock();
+ eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny()));
+ AuthenticationEvent expectedAuthenticationEvent = GetAuthenticationEvent(AuthenticationMethod.AltinnPIN, SecurityLevel.QuiteSensitive, null, AuthenticationEventType.Logout, "1337");
+
+ Mock featureManageMock = new Mock();
+ featureManageMock
+ .Setup(m => m.IsEnabledAsync("AuditLog"))
+ .Returns(Task.FromResult(true));
+
+ HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object, eventQueue.Object, featureManageMock.Object);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "/authentication/api/v1/frontchannel_logout");
SetupUtil.AddAuthCookie(requestMessage, token);
@@ -227,9 +243,54 @@ public async Task Logout_FrontChannelOK()
Assert.Equal(".ASPXAUTH=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=localhost; path=/; secure; httponly", values.First());
Assert.Equal("AltinnStudioRuntime=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=localhost; path=/; secure; httponly", values.Last());
}
+
+ AssertAuthenticationEvent(eventQueue, expectedAuthenticationEvent, Moq.Times.Once());
}
- private HttpClient GetTestClient(ISblCookieDecryptionService cookieDecryptionService, IUserProfileService userProfileService, bool enableOidc = false, bool forceOidc = false, string defaultOidc = "altinn")
+ ///
+ /// Frontchannel logout with event log feature turned off
+ ///
+ [Fact]
+ public async Task Logout_FrontChannelOK_Auditlog_off()
+ {
+ List claims = new List();
+ string issuer = "www.altinn.no";
+ claims.Add(new Claim("originaliss", "uidp", ClaimValueTypes.String, issuer));
+
+ string token = PrincipalUtil.GetToken(1337, claims);
+
+ Mock eventQueue = new Mock();
+ eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny()));
+ AuthenticationEvent expectedAuthenticationEvent = GetAuthenticationEvent(AuthenticationMethod.AltinnPIN, SecurityLevel.QuiteSensitive, null, AuthenticationEventType.Logout, "1337");
+
+ Mock featureManageMock = new Mock();
+ featureManageMock
+ .Setup(m => m.IsEnabledAsync("AuditLog"))
+ .Returns(Task.FromResult(false));
+
+ HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object, eventQueue.Object, featureManageMock.Object);
+
+ HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "/authentication/api/v1/frontchannel_logout");
+ SetupUtil.AddAuthCookie(requestMessage, token);
+
+ // Act
+ HttpResponseMessage response = await client.SendAsync(requestMessage);
+
+ // Assert
+ Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
+
+ IEnumerable values;
+
+ if (response.Headers.TryGetValues("Set-Cookie", out values))
+ {
+ Assert.Equal(".ASPXAUTH=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=localhost; path=/; secure; httponly", values.First());
+ Assert.Equal("AltinnStudioRuntime=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=localhost; path=/; secure; httponly", values.Last());
+ }
+
+ AssertAuthenticationEvent(eventQueue, expectedAuthenticationEvent, Moq.Times.Never());
+ }
+
+ private HttpClient GetTestClient(ISblCookieDecryptionService cookieDecryptionService, IUserProfileService userProfileService, IEventLog eventLog = null, IFeatureManager featureManager = null, bool enableOidc = false, bool forceOidc = false, bool auditLog = true, string defaultOidc = "altinn")
{
HttpClient client = _factory.WithWebHostBuilder(builder =>
{
@@ -261,6 +322,15 @@ private HttpClient GetTestClient(ISblCookieDecryptionService cookieDecryptionSer
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ if (featureManager != null)
+ {
+ services.AddSingleton(featureManager);
+ }
+
+ if (eventLog != null)
+ {
+ services.AddSingleton(eventLog);
+ }
});
}).CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
@@ -272,5 +342,22 @@ private static string GetConfigPath()
string unitTestFolder = Path.GetDirectoryName(new Uri(typeof(AuthenticationControllerTests).Assembly.Location).LocalPath);
return Path.Combine(unitTestFolder, $"../../../appsettings.json");
}
+
+ private static AuthenticationEvent GetAuthenticationEvent(AuthenticationMethod authMethod, SecurityLevel authLevel, string orgNumber, AuthenticationEventType authEventType, string userId = null)
+ {
+ AuthenticationEvent authenticationEvent = new AuthenticationEvent();
+ authenticationEvent.AuthenticationMethod = authMethod.ToString();
+ authenticationEvent.AuthenticationLevel = authLevel.ToString();
+ authenticationEvent.OrgNumber = orgNumber;
+ authenticationEvent.EventType = authEventType.ToString();
+ authenticationEvent.UserId = userId;
+
+ return authenticationEvent;
+ }
+
+ private static void AssertAuthenticationEvent(Mock eventQueue, AuthenticationEvent expectedAuthenticationEvent, Moq.Times invocationsTime)
+ {
+ eventQueue.Verify(e => e.CreateAuthenticationEvent(It.Is(q => q.AuthenticationMethod == expectedAuthenticationEvent.AuthenticationMethod && q.AuthenticationLevel == expectedAuthenticationEvent.AuthenticationLevel && q.OrgNumber == expectedAuthenticationEvent.OrgNumber && q.UserId == expectedAuthenticationEvent.UserId && q.EventType == expectedAuthenticationEvent.EventType)), invocationsTime);
+ }
}
}
diff --git a/test/Altinn.Platform.Authentication.Tests/appsettings.json b/test/Altinn.Platform.Authentication.Tests/appsettings.json
index bb4bbf16..13e4e42b 100644
--- a/test/Altinn.Platform.Authentication.Tests/appsettings.json
+++ b/test/Altinn.Platform.Authentication.Tests/appsettings.json
@@ -36,7 +36,7 @@
"TokenEndpoint": "https://idporten.azurewebsites.net/api/token",
"WellKnownConfigEndpoint": "https://idporten.azurewebsites.net/api/v1/openid/.well-known/openid-configuration",
"ClientId": "345345s",
- "ProviderClaims": [ "sub", "locale", "role"]
+ "ProviderClaims": [ "sub", "locale", "role" ]
},
"uidp": {
"Issuer": "https://uidp-qa.udir.no",
@@ -51,5 +51,8 @@
"ProviderClaims": [ "locale", "urn:feide:role", "sub" ]
}
+ },
+ "FeatureManagement": {
+ "AuditLog": true
}
}