Skip to content

Commit e43459b

Browse files
committed
Fix #244 Add StatusCode support for logout response
1 parent 58fc792 commit e43459b

3 files changed

Lines changed: 60 additions & 19 deletions

File tree

core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* LogoutResponse class of OneLogin's Java Toolkit.
3333
*
3434
* A class that implements SAML 2 Logout Response builder/parser/validator
35-
*/
35+
*/
3636
public class LogoutResponse {
3737
/**
3838
* Private property to construct a logger for this class.
@@ -42,7 +42,7 @@ public class LogoutResponse {
4242
/**
4343
* SAML LogoutResponse string
4444
*/
45-
private String logoutResponseString;
45+
private String logoutResponseString;
4646

4747
/**
4848
* A DOMDocument object loaded from the SAML Response.
@@ -81,7 +81,7 @@ public class LogoutResponse {
8181

8282
/**
8383
* After validation, if it fails this property has the cause of the problem
84-
*/
84+
*/
8585
private String error;
8686

8787
/**
@@ -96,7 +96,7 @@ public class LogoutResponse {
9696
public LogoutResponse(Saml2Settings settings, HttpRequest request) {
9797
this.settings = settings;
9898
this.request = request;
99-
99+
100100
String samlLogoutResponse = null;
101101
if (request != null) {
102102
currentUrl = request.getRequestURL();
@@ -112,10 +112,10 @@ public LogoutResponse(Saml2Settings settings, HttpRequest request) {
112112
/**
113113
* @return the base64 encoded unsigned Logout Response (deflated or not)
114114
*
115-
* @param deflated
115+
* @param deflated
116116
* If deflated or not the encoded Logout Response
117117
*
118-
* @throws IOException
118+
* @throws IOException
119119
*/
120120
public String getEncodedLogoutResponse(Boolean deflated) throws IOException {
121121
String encodedLogoutResponse;
@@ -133,7 +133,7 @@ public String getEncodedLogoutResponse(Boolean deflated) throws IOException {
133133
/**
134134
* @return the base64 encoded, unsigned Logout Response (deflated or not)
135135
*
136-
* @throws IOException
136+
* @throws IOException
137137
*/
138138
public String getEncodedLogoutResponse() throws IOException {
139139
return getEncodedLogoutResponse(null);
@@ -274,13 +274,13 @@ public Boolean isValid(String requestId) {
274274
}
275275
}
276276

277-
public Boolean isValid() {
277+
public Boolean isValid() {
278278
return isValid(null);
279279
}
280280

281281
/**
282282
* Gets the Issuer from Logout Response.
283-
*
283+
*
284284
* @return the issuer of the logout response
285285
*
286286
* @throws XPathExpressionException
@@ -290,7 +290,7 @@ public String getIssuer() throws XPathExpressionException {
290290
NodeList issuers = this.query("/samlp:LogoutResponse/saml:Issuer");
291291
if (issuers.getLength() == 1) {
292292
issuer = issuers.item(0).getTextContent();
293-
}
293+
}
294294
return issuer;
295295
}
296296

@@ -341,16 +341,28 @@ private NodeList query (String query) throws XPathExpressionException {
341341
*
342342
* @param inResponseTo
343343
* InResponseTo attribute value to bet set at the Logout Response.
344+
* @param statusCode
345+
* String StatusCode to be set on the LogoutResponse
344346
*/
345-
public void build(String inResponseTo) {
347+
public void build(String inResponseTo, String statusCode) {
346348
id = Util.generateUniqueID(settings.getUniqueIDPrefix());
347349
issueInstant = Calendar.getInstance();
348350
this.inResponseTo = inResponseTo;
349351

350-
StrSubstitutor substitutor = generateSubstitutor(settings);
352+
StrSubstitutor substitutor = generateSubstitutor(settings, statusCode);
351353
this.logoutResponseString = substitutor.replace(getLogoutResponseTemplate());
352354
}
353355

356+
/**
357+
* Generates a Logout Response XML string.
358+
*
359+
* @param inResponseTo
360+
* InResponseTo attribute value to bet set at the Logout Response.
361+
*/
362+
public void build(String inResponseTo) {
363+
build(inResponseTo, Constants.STATUS_SUCCESS);
364+
}
365+
354366
/**
355367
* Generates a Logout Response XML string.
356368
*
@@ -364,13 +376,15 @@ public void build() {
364376
*
365377
* @param settings
366378
* Saml2Settings object. Setting data
367-
*
368-
* @return the StrSubstitutor object of the LogoutResponse
379+
* @param statusCode
380+
* String StatusCode to be set on the LogoutResponse
381+
*
382+
* @return the StrSubstitutor object of the LogoutResponse
369383
*/
370-
private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
384+
private StrSubstitutor generateSubstitutor(Saml2Settings settings, String statusCode) {
371385
Map<String, String> valueMap = new HashMap<String, String>();
372386

373-
valueMap.put("id", id);
387+
valueMap.put("id", id);
374388

375389
String issueInstantString = Util.formatDateTime(issueInstant.getTimeInMillis());
376390
valueMap.put("issueInstant", issueInstantString);
@@ -388,11 +402,29 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
388402
}
389403
valueMap.put("inResponseStr", inResponseStr);
390404

405+
String statusStr = "";
406+
if (statusCode != null) {
407+
statusStr = "Value=\"" + statusCode + "\"";
408+
}
409+
valueMap.put("statusStr", statusStr);
410+
391411
valueMap.put("issuer", settings.getSpEntityId());
392412

393413
return new StrSubstitutor(valueMap);
394414
}
395415

416+
/**
417+
* Substitutes LogoutResponse variables within a string by values.
418+
*
419+
* @param settings
420+
* Saml2Settings object. Setting data
421+
*
422+
* @return the StrSubstitutor object of the LogoutResponse
423+
*/
424+
private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
425+
return generateSubstitutor(settings, Constants.STATUS_SUCCESS);
426+
}
427+
396428
/**
397429
* @return the LogoutResponse's template
398430
*/
@@ -404,7 +436,7 @@ private static StringBuilder getLogoutResponseTemplate() {
404436
template.append("IssueInstant=\"${issueInstant}\"${destinationStr}${inResponseStr} >");
405437
template.append("<saml:Issuer>${issuer}</saml:Issuer>");
406438
template.append("<samlp:Status>");
407-
template.append("<samlp:StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\" />");
439+
template.append("<samlp:StatusCode ${statusStr} />");
408440
template.append("</samlp:Status>");
409441
template.append("</samlp:LogoutResponse>");
410442
return template;
@@ -413,7 +445,7 @@ private static StringBuilder getLogoutResponseTemplate() {
413445
/**
414446
* After execute a validation process, if fails this method returns the cause
415447
*
416-
* @return the cause of the validation error
448+
* @return the cause of the validation error
417449
*/
418450
public String getError() {
419451
return error;

core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ public void testBuild() throws IOException, XMLEntityException, URISyntaxExcepti
155155
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
156156
assertThat(logoutRequestStr, containsString("<samlp:LogoutResponse"));
157157
assertThat(logoutRequestStr, containsString("InResponseTo=\"inResponseValue\""));
158+
assertThat(logoutRequestStr, containsString("StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\""));
159+
160+
LogoutResponse logoutResponse3 = new LogoutResponse(settings, httpRequest);
161+
logoutResponse3.build("inResponseValue", Constants.STATUS_REQUEST_DENIED);
162+
logoutRequestStringBase64 = logoutResponse3.getEncodedLogoutResponse();
163+
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
164+
assertThat(logoutRequestStr, containsString("<samlp:LogoutResponse"));
165+
assertThat(logoutRequestStr, containsString("InResponseTo=\"inResponseValue\""));
166+
assertThat(logoutRequestStr, containsString("StatusCode Value=\"" + Constants.STATUS_REQUEST_DENIED + "\""));
158167
}
159168

160169
/**

toolkit/src/main/java/com/onelogin/saml2/Auth.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
821821

822822
String inResponseTo = logoutRequest.id;
823823
LogoutResponse logoutResponseBuilder = new LogoutResponse(settings, httpRequest);
824-
logoutResponseBuilder.build(inResponseTo);
824+
logoutResponseBuilder.build(inResponseTo, Constants.STATUS_SUCCESS);
825825
lastResponse = logoutResponseBuilder.getLogoutResponseXml();
826826

827827
String samlLogoutResponse = logoutResponseBuilder.getEncodedLogoutResponse();

0 commit comments

Comments
 (0)