Skip to content

Commit

Permalink
Merge pull request Sustainsys#636 from explunit/logout-status-notific…
Browse files Browse the repository at this point in the history
…ation

Notification for single logout response status
  • Loading branch information
explunit authored Jan 25, 2017
2 parents e47cbc9 + 80c83f0 commit 80a2b36
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
25 changes: 25 additions & 0 deletions Kentor.AuthServices.Tests/WebSSO/LogoutCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,31 @@ public void LogoutCommand_Run_ThrowsOnLogoutResponseStatusNonSuccess()
.And.Message.Should().Be("Idp returned status \"Requester\", indicating that the single logout failed. The local session has been successfully terminated.");
}

[TestMethod]
public void LogoutCommand_Run_LetsNotificationHandleStatus()
{
var response = new Saml2LogoutResponse(Saml2StatusCode.Requester)
{
DestinationUrl = new Uri("http://sp.example.com/path/AuthServices/logout"),
Issuer = new EntityId("https://idp.example.com"),
InResponseTo = new Saml2Id(),
SigningCertificate = SignedXmlHelper.TestCert
};

var bindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
.Bind(response);

var request = new HttpRequestData("GET", bindResult.Location,
"http://sp-internal.example.com/path/AuthServices", null, null, null);

var options = StubFactory.CreateOptions();
options.SPOptions.PublicOrigin = new Uri("https://sp.example.com/path/");
options.Notifications.ProcessSingleLogoutResponseStatus = (logoutResponse, requestState) => true;

var actual = CommandFactory.GetCommand(CommandFactory.LogoutCommandName).Run(request, options);
actual.Location.ShouldBeEquivalentTo(options.SPOptions.PublicOrigin);
}

[TestMethod]
public void LogoutCommand_Run_LocalLogoutIfNoUser()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public KentorAuthServicesNotifications()
SelectIdentityProvider = (ei, r) => null;
GetLogoutResponseState = ( httpRequestData ) => httpRequestData.StoredRequestState;
GetPublicOrigin = ( httpRequestData ) => null;
ProcessSingleLogoutResponseStatus = ( response, state ) => false;
GetBinding = Saml2Binding.Get;
MessageUnbound = ur => { };
AcsCommandResultCreated = (cr, r) => { };
Expand Down Expand Up @@ -82,6 +83,15 @@ public Func<HttpRequestData, StoredRequestState>
public Func<HttpRequestData, Uri>
GetPublicOrigin { get; set; }

/// <summary>
/// Notification called when single logout status is returned from IDP.
/// Return true to indicate that your notification has handled this status. Otherwise
/// it will fall back to the normal status processing logic.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout" )]
public Func<Saml2LogoutResponse, StoredRequestState, bool>
ProcessSingleLogoutResponseStatus { get; set; }

/// <summary>
/// Get a binding that can unbind data from the supplied request. The
/// default is to use <see cref="Saml2Binding.Get(HttpRequestData)"/>
Expand Down
16 changes: 10 additions & 6 deletions Kentor.AuthServices/WebSSO/LogOutCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,16 @@ private static CommandResult HandleRequest(UnbindResult unbindResult, IOptions o

private static CommandResult HandleResponse(UnbindResult unbindResult, StoredRequestState storedRequestState, IOptions options, Uri returnUrl)
{
var status = Saml2LogoutResponse.FromXml(unbindResult.Data).Status;
if(status != Saml2StatusCode.Success)
{
throw new UnsuccessfulSamlOperationException(string.Format(CultureInfo.InvariantCulture,
"Idp returned status \"{0}\", indicating that the single logout failed. The local session has been successfully terminated.",
status));
var logoutResponse = Saml2LogoutResponse.FromXml(unbindResult.Data);
var notificationHandledTheStatus = options.Notifications.ProcessSingleLogoutResponseStatus(logoutResponse, storedRequestState);
if (!notificationHandledTheStatus) {
var status = logoutResponse.Status;
if(status != Saml2StatusCode.Success)
{
throw new UnsuccessfulSamlOperationException(string.Format(CultureInfo.InvariantCulture,
"Idp returned status \"{0}\", indicating that the single logout failed. The local session has been successfully terminated.",
status));
}
}

var commandResult = new CommandResult
Expand Down

0 comments on commit 80a2b36

Please sign in to comment.