Skip to content

Commit

Permalink
Added logging assert på logout
Browse files Browse the repository at this point in the history
  • Loading branch information
acn-dgopa committed Sep 18, 2023
1 parent 606b4d5 commit 263df72
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/Authentication/Controllers/LogoutController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Check warning on line 100 in src/Authentication/Controllers/LogoutController.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 100 in src/Authentication/Controllers/LogoutController.cs

View workflow job for this annotation

GitHub Actions / Analyze

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 100 in src/Authentication/Controllers/LogoutController.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
return Ok();
}

Expand Down
2 changes: 1 addition & 1 deletion src/Authentication/Helpers/EventlogHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static class EventlogHelper
/// <param name="jwtToken">token in the authentication request</param>
/// <param name="eventType">authentication event type</param>
public async static Task CreateAuthenticationEvent(IFeatureManager featureManager, IEventLog eventLog, string jwtToken, AuthenticationEventType eventType)
{
{
if (await featureManager.IsEnabledAsync(FeatureFlags.AuditLog))
{
AuthenticationEvent authenticationEvent = MapAuthenticationEvent(jwtToken, eventType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
using Moq;
using Xunit;

Expand Down Expand Up @@ -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<IEventLog> eventQueue = new Mock<IEventLog>();
eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny<AuthenticationEvent>()));
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);
Expand All @@ -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());
}

/// <summary>
Expand Down Expand Up @@ -209,7 +216,16 @@ public async Task Logout_FrontChannelOK()

string token = PrincipalUtil.GetToken(1337, claims);

HttpClient client = GetTestClient(_cookieDecryptionService.Object, _userProfileService.Object);
Mock<IEventLog> eventQueue = new Mock<IEventLog>();
eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny<AuthenticationEvent>()));
AuthenticationEvent expectedAuthenticationEvent = GetAuthenticationEvent(AuthenticationMethod.AltinnPIN, SecurityLevel.QuiteSensitive, null, AuthenticationEventType.Logout, "1337");

Mock<IFeatureManager> featureManageMock = new Mock<IFeatureManager>();
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);
Expand All @@ -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")
/// <summary>
/// Frontchannel logout with event log feature turned off
/// </summary>
[Fact]
public async Task Logout_FrontChannelOK_Auditlog_off()
{
List<Claim> claims = new List<Claim>();
string issuer = "www.altinn.no";
claims.Add(new Claim("originaliss", "uidp", ClaimValueTypes.String, issuer));

string token = PrincipalUtil.GetToken(1337, claims);

Mock<IEventLog> eventQueue = new Mock<IEventLog>();
eventQueue.Setup(q => q.CreateAuthenticationEvent(It.IsAny<AuthenticationEvent>()));
AuthenticationEvent expectedAuthenticationEvent = GetAuthenticationEvent(AuthenticationMethod.AltinnPIN, SecurityLevel.QuiteSensitive, null, AuthenticationEventType.Logout, "1337");

Mock<IFeatureManager> featureManageMock = new Mock<IFeatureManager>();
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<string> 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 =>
{
Expand Down Expand Up @@ -261,6 +322,15 @@ private HttpClient GetTestClient(ISblCookieDecryptionService cookieDecryptionSer
services.AddSingleton<IPublicSigningKeyProvider, SigningKeyResolverStub>();
services.AddSingleton<IEnterpriseUserAuthenticationService, EnterpriseUserAuthenticationServiceMock>();
services.AddSingleton<IOidcProvider, OidcProviderServiceMock>();
if (featureManager != null)
{
services.AddSingleton(featureManager);
}

if (eventLog != null)
{
services.AddSingleton(eventLog);
}
});
}).CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });

Expand All @@ -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<IEventLog> eventQueue, AuthenticationEvent expectedAuthenticationEvent, Moq.Times invocationsTime)
{
eventQueue.Verify(e => e.CreateAuthenticationEvent(It.Is<AuthenticationEvent>(q => q.AuthenticationMethod == expectedAuthenticationEvent.AuthenticationMethod && q.AuthenticationLevel == expectedAuthenticationEvent.AuthenticationLevel && q.OrgNumber == expectedAuthenticationEvent.OrgNumber && q.UserId == expectedAuthenticationEvent.UserId && q.EventType == expectedAuthenticationEvent.EventType)), invocationsTime);
}
}
}
5 changes: 4 additions & 1 deletion test/Altinn.Platform.Authentication.Tests/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -51,5 +51,8 @@
"ProviderClaims": [ "locale", "urn:feide:role", "sub" ]
}

},
"FeatureManagement": {
"AuditLog": true
}
}

0 comments on commit 263df72

Please sign in to comment.