Skip to content

Commit

Permalink
Notifications when sending LogoutResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
AndersAbel committed Mar 26, 2020
1 parent 1a2b976 commit b97a40d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
8 changes: 8 additions & 0 deletions Sustainsys.Saml2/Configuration/Saml2Notifications.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@ public Func<Saml2LogoutResponse, StoredRequestState, bool>
/// </summary>
public Action<Saml2LogoutRequest, XDocument> LogoutRequestXmlCreated { get; set; } = (lr, xd) => { };

/// <summary>
/// Notification called when a logout request has been received and processed and a Logout Response has been created.
/// </summary>
public Action<Saml2LogoutResponse, Saml2LogoutRequest, ClaimsPrincipal, IdentityProvider> LogoutResponseCreated { get; set; }
= (resp, req, u, idp) => { };

public Action<Saml2LogoutResponse, XDocument> LogoutResponseXmlCreated { get; set; } = (lr, xd) => { };

/// <summary>
/// Notification called when metadata has been created, but before
/// signing. At this point the contents of the metadata can be
Expand Down
9 changes: 6 additions & 3 deletions Sustainsys.Saml2/WebSSO/LogOutCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static CommandResult Run(
switch (unbindResult.Data.LocalName)
{
case "LogoutRequest":
commandResult = HandleRequest(unbindResult, options);
commandResult = HandleRequest(unbindResult, request, options);
break;
case "LogoutResponse":
var storedRequestState = options.Notifications.GetLogoutResponseState(request);
Expand Down Expand Up @@ -241,7 +241,7 @@ private static Uri GetReturnUrl(HttpRequestData request, string returnPath, IOpt
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "SingleLogoutServiceUrl")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "SingleLogoutService")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "LogoutRequest")]
private static CommandResult HandleRequest(UnbindResult unbindResult, IOptions options)
private static CommandResult HandleRequest(UnbindResult unbindResult, HttpRequestData httpRequest, IOptions options)
{
var request = Saml2LogoutRequest.FromXml(unbindResult.Data);

Expand Down Expand Up @@ -275,10 +275,13 @@ private static CommandResult HandleRequest(UnbindResult unbindResult, IOptions o
RelayState = unbindResult.RelayState
};

options.Notifications.LogoutResponseCreated(response, request, httpRequest.User, idp);

options.SPOptions.Logger.WriteInformation("Got a logout request " + request.Id
+ ", responding with logout response " + response.Id);

var result = Saml2Binding.Get(idp.SingleLogoutServiceBinding).Bind(response);
var result = Saml2Binding.Get(idp.SingleLogoutServiceBinding).Bind(
response, options.SPOptions.Logger, options.Notifications.LogoutResponseXmlCreated);
result.TerminateLocalSession = true;
return result;
}
Expand Down
28 changes: 27 additions & 1 deletion Tests/Tests.Shared/WebSSO/LogoutCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,35 @@ public void LogoutCommand_Run_HandlesLogoutRequest_ReceivedThroughRedirectBindin
var bindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
.Bind(request);

var httpRequest = new HttpRequestData("GET", bindResult.Location);
var httpRequest = new HttpRequestData(
"GET",
bindResult.Location,
"/",
null,
cookieName => null,
null,
new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim(Saml2ClaimTypes.SessionIndex, "SessionID") })));

var options = StubFactory.CreateOptions();
options.SPOptions.ServiceCertificates.Add(SignedXmlHelper.TestCert);

Saml2LogoutResponse logoutResponse = null;
options.Notifications.LogoutResponseCreated = (resp, req, u, idp) =>
{
logoutResponse = resp;
req.Id.Value.Should().Be(request.Id.Value);
u.Identities.First().FindFirst(Saml2ClaimTypes.SessionIndex).Value.Should().Be("SessionID");
idp.EntityId.Id.Should().Be(request.Issuer.Id);
};

bool xmlCreatedCalled = false;
options.Notifications.LogoutResponseXmlCreated = (resp, xml) =>
{
xmlCreatedCalled = true;
resp.Should().BeSameAs(logoutResponse);
xml.Root.Attribute("ID").Value.Should().BeSameAs(resp.Id.Value);
};

CommandResult notifiedCommandResult = null;
options.Notifications.LogoutCommandResultCreated = cr =>
{
Expand Down Expand Up @@ -491,6 +515,8 @@ public void LogoutCommand_Run_HandlesLogoutRequest_ReceivedThroughRedirectBindin

actual.Should().BeEquivalentTo(expected, opt => opt.Excluding(cr => cr.Location));
actual.Should().BeSameAs(notifiedCommandResult);
logoutResponse.InResponseTo.Value.Should().Be(request.Id.Value);
xmlCreatedCalled.Should().BeTrue();

var actualUnbindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
.Unbind(new HttpRequestData("GET", actual.Location), options);
Expand Down

0 comments on commit b97a40d

Please sign in to comment.