LogoutRequest logoutRequest = (LogoutRequest) message;
// Make sure request was authenticated if required, authentication is done as part of the binding processing
if (!context.isInboundSAMLMessageAuthenticated() && context.getLocalExtendedMetadata().isRequireLogoutRequestSigned()) {
throw new SAMLStatusException(StatusCode.REQUEST_DENIED_URI, "LogoutRequest is required to be signed by the entity policy");
}
// Verify destination
try {
verifyEndpoint(context.getLocalEntityEndpoint(), logoutRequest.getDestination());
} catch (SAMLException e) {
throw new SAMLStatusException(StatusCode.REQUEST_DENIED_URI, "Destination of the LogoutRequest does not match any of the single logout endpoints");
}
// Verify issuer
try {
if (logoutRequest.getIssuer() != null) {
Issuer issuer = logoutRequest.getIssuer();
verifyIssuer(issuer, context);
}
} catch (SAMLException e) {
throw new SAMLStatusException(StatusCode.REQUEST_DENIED_URI, "Issuer of the LogoutRequest is unknown");
}
// Verify issue time
DateTime time = logoutRequest.getIssueInstant();
if (!isDateTimeSkewValid(getResponseSkew(), time)) {
throw new SAMLStatusException(StatusCode.REQUESTER_URI, "LogoutRequest issue instant is either too old or with date in the future");
}
// Check whether any user is logged in
if (credential == null) {
throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "No user is logged in");
}
// Find index for which the logout is requested
boolean indexFound = false;
if (logoutRequest.getSessionIndexes() != null && logoutRequest.getSessionIndexes().size() > 0) {
for (AuthnStatement statement : credential.getAuthenticationAssertion().getAuthnStatements()) {
String statementIndex = statement.getSessionIndex();
if (statementIndex != null) {
for (SessionIndex index : logoutRequest.getSessionIndexes()) {
if (statementIndex.equals(index.getSessionIndex())) {
indexFound = true;
}
}
}
}
} else {
indexFound = true;
}
// Fail if sessionIndex is not found in any assertion
if (!indexFound) {
// Check logout request still valid and store request
//if (logoutRequest.getNotOnOrAfter() != null) {
// TODO store request for assertions possibly arriving later
//}
throw new SAMLStatusException(StatusCode.REQUESTER_URI, "The SessionIndex was not found");
}
try {
// Fail if NameId doesn't correspond to the currently logged user
NameID nameID = getNameID(context, logoutRequest);
if (nameID == null || !equalsNameID(credential.getNameID(), nameID)) {
throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "The requested NameID is invalid");
}
} catch (DecryptionException e) {
throw new SAMLStatusException(StatusCode.RESPONDER_URI, "The NameID can't be decrypted", e);
}
return true;
}