Skip to content

Commit 8c66a14

Browse files
authored
Merge pull request #321 from mauromol/add-message-xml-post-processing
Allow for extension classes to post-process generated XML
2 parents 0a90a87 + 423618a commit 8c66a14

File tree

8 files changed

+177
-7
lines changed

8 files changed

+177
-7
lines changed

core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import org.slf4j.Logger;
1212
import org.slf4j.LoggerFactory;
1313

14-
import com.onelogin.saml2.settings.Saml2Settings;
1514
import com.onelogin.saml2.model.Organization;
15+
import com.onelogin.saml2.settings.Saml2Settings;
1616
import com.onelogin.saml2.util.Constants;
1717
import com.onelogin.saml2.util.Util;
1818

@@ -101,7 +101,7 @@ public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassiv
101101
this.nameIdValueReq = nameIdValueReq;
102102

103103
StrSubstitutor substitutor = generateSubstitutor(settings);
104-
authnRequestString = substitutor.replace(getAuthnRequestTemplate());
104+
authnRequestString = postProcessXml(substitutor.replace(getAuthnRequestTemplate()), settings);
105105
LOGGER.debug("AuthNRequest --> " + authnRequestString);
106106
}
107107

@@ -121,6 +121,26 @@ public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassiv
121121
this(settings, forceAuthn, isPassive, setNameIdPolicy, null);
122122
}
123123

124+
/**
125+
* Allows for an extension class to post-process the AuthnRequest XML generated
126+
* for this request, in order to customize the result.
127+
* <p>
128+
* This method is invoked at construction time, after all the other fields of
129+
* this class have already been initialised. Its default implementation simply
130+
* returns the input XML as-is, with no change.
131+
*
132+
* @param authnRequestXml
133+
* the XML produced for this AuthnRequest by the standard
134+
* implementation provided by {@link AuthnRequest}
135+
* @param settings
136+
* the settings
137+
* @return the post-processed XML for this AuthnRequest, which will then be
138+
* returned by any call to {@link #getAuthnRequestXml()}
139+
*/
140+
protected String postProcessXml(final String authnRequestXml, final Saml2Settings settings) {
141+
return authnRequestXml;
142+
}
143+
124144
/**
125145
* @return the base64 encoded unsigned AuthnRequest (deflated or not)
126146
*

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public LogoutRequest(Saml2Settings settings, HttpRequest request, String nameId,
139139
this.sessionIndex = sessionIndex;
140140

141141
StrSubstitutor substitutor = generateSubstitutor(settings);
142-
logoutRequestString = substitutor.replace(getLogoutRequestTemplate());
142+
logoutRequestString = postProcessXml(substitutor.replace(getLogoutRequestTemplate()), settings);
143143
} else {
144144
logoutRequestString = Util.base64decodedInflated(samlLogoutRequest);
145145
Document doc = Util.loadXML(logoutRequestString);
@@ -224,6 +224,28 @@ public LogoutRequest(Saml2Settings settings, HttpRequest request) {
224224
this(settings, request, null, null);
225225
}
226226

227+
/**
228+
* Allows for an extension class to post-process the LogoutRequest XML generated
229+
* for this request, in order to customize the result.
230+
* <p>
231+
* This method is invoked at construction time when no existing LogoutRequest
232+
* message is found in the HTTP request (and hence in the logout request sending
233+
* scenario only), after all the other fields of this class have already been
234+
* initialised. Its default implementation simply returns the input XML as-is,
235+
* with no change.
236+
*
237+
* @param logoutRequestXml
238+
* the XML produced for this LogoutRequest by the standard
239+
* implementation provided by {@link LogoutRequest}
240+
* @param settings
241+
* the settings
242+
* @return the post-processed XML for this LogoutRequest, which will then be
243+
* returned by any call to {@link #getLogoutRequestXml()}
244+
*/
245+
protected String postProcessXml(final String logoutRequestXml, final Saml2Settings settings) {
246+
return logoutRequestXml;
247+
}
248+
227249
/**
228250
* @return the base64 encoded unsigned Logout Request (deflated or not)
229251
*

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ public void build(String inResponseTo, String statusCode) {
367367
this.inResponseTo = inResponseTo;
368368

369369
StrSubstitutor substitutor = generateSubstitutor(settings, statusCode);
370-
this.logoutResponseString = substitutor.replace(getLogoutResponseTemplate());
370+
this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), settings);
371371
}
372372

373373
/**
@@ -388,6 +388,26 @@ public void build() {
388388
build(null);
389389
}
390390

391+
/**
392+
* Allows for an extension class to post-process the LogoutResponse XML
393+
* generated for this response, in order to customize the result.
394+
* <p>
395+
* This method is invoked by {@link #build(String, String)} (and all of its
396+
* overloadings) and hence only in the logout response sending scenario. Its
397+
* default implementation simply returns the input XML as-is, with no change.
398+
*
399+
* @param logoutResponseXml
400+
* the XML produced for this LogoutResponse by the standard
401+
* implementation provided by {@link LogoutResponse}
402+
* @param settings
403+
* the settings
404+
* @return the post-processed XML for this LogoutResponse, which will then be
405+
* returned by any call to {@link #getLogoutResponseXml()}
406+
*/
407+
protected String postProcessXml(final String logoutResponseXml, final Saml2Settings settings) {
408+
return logoutResponseXml;
409+
}
410+
391411
/**
392412
* Substitutes LogoutResponse variables within a string by values.
393413
*

core/src/main/java/com/onelogin/saml2/settings/Metadata.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public Metadata(Saml2Settings settings, Calendar validUntilTime, Integer cacheDu
7777
this.cacheDuration = cacheDuration;
7878

7979
StrSubstitutor substitutor = generateSubstitutor(settings);
80-
String unsignedMetadataString = substitutor.replace(getMetadataTemplate());
80+
String unsignedMetadataString = postProcessXml(substitutor.replace(getMetadataTemplate()), settings);
8181

8282
LOGGER.debug("metadata --> " + unsignedMetadataString);
8383
metadataString = unsignedMetadataString;
@@ -109,11 +109,31 @@ public Metadata(Saml2Settings settings) throws CertificateEncodingException {
109109
this.cacheDuration = SECONDS_CACHED;
110110

111111
StrSubstitutor substitutor = generateSubstitutor(settings);
112-
String unsignedMetadataString = substitutor.replace(getMetadataTemplate());
112+
String unsignedMetadataString = postProcessXml(substitutor.replace(getMetadataTemplate()), settings);
113113

114114
LOGGER.debug("metadata --> " + unsignedMetadataString);
115115
metadataString = unsignedMetadataString;
116116
}
117+
118+
/**
119+
* Allows for an extension class to post-process the SAML metadata XML generated
120+
* for this metadata instance, in order to customize the result.
121+
* <p>
122+
* This method is invoked at construction time, after all the other fields of
123+
* this class have already been initialised. Its default implementation simply
124+
* returns the input XML as-is, with no change.
125+
*
126+
* @param metadataXml
127+
* the XML produced for this metadata instance by the standard
128+
* implementation provided by {@link Metadata}
129+
* @param settings
130+
* the settings
131+
* @return the post-processed XML for this metadata instance, which will then be
132+
* returned by any call to {@link #getMetadataString()}
133+
*/
134+
protected String postProcessXml(final String metadataXml, final Saml2Settings settings) {
135+
return metadataXml;
136+
}
117137

118138
/**
119139
* Substitutes metadata variables within a string by values.

core/src/test/java/com/onelogin/saml2/test/authn/AuthnRequestTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.junit.Assert.assertEquals;
66
import static org.junit.Assert.assertNotEquals;
77
import static org.junit.Assert.assertNotNull;
8+
import static org.junit.Assert.assertSame;
89
import static org.junit.Assert.assertThat;
910
import static org.junit.Assert.assertTrue;
1011

@@ -382,4 +383,25 @@ public void testAuthNDestination() throws Exception {
382383
assertThat(authnRequestStr, containsString("<samlp:AuthnRequest"));
383384
assertThat(authnRequestStr, not(containsString("Destination=\"http://idp.example.com/simplesaml/saml2/idp/SSOService.php\"")));
384385
}
386+
387+
/**
388+
* Tests the postProcessXml method of AuthnRequest
389+
*
390+
* @throws Exception
391+
*
392+
* @see com.onelogin.saml2.authn.AuthnRequest#postProcessXml
393+
*/
394+
@Test
395+
public void testPostProcessXml() throws Exception {
396+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
397+
AuthnRequest authnRequest = new AuthnRequest(settings) {
398+
@Override
399+
protected String postProcessXml(String authRequestXml, Saml2Settings sett) {
400+
assertEquals(authRequestXml, super.postProcessXml(authRequestXml, sett));
401+
assertSame(settings, sett);
402+
return "changed";
403+
}
404+
};
405+
assertEquals("changed", authnRequest.getAuthnRequestXml());
406+
}
385407
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.junit.Assert.assertEquals;
66
import static org.junit.Assert.assertThat;
77
import static org.junit.Assert.assertNull;
8+
import static org.junit.Assert.assertSame;
89
import static org.junit.Assert.assertFalse;
910
import static org.junit.Assert.assertNotEquals;
1011
import static org.junit.Assert.assertNotNull;
@@ -1008,4 +1009,25 @@ public void testGetError() throws Exception {
10081009
private static HttpRequest newHttpRequest(String requestURL, String samlRequestEncoded) {
10091010
return new HttpRequest(requestURL, (String)null).addParameter("SAMLRequest", samlRequestEncoded);
10101011
}
1012+
1013+
/**
1014+
* Tests the postProcessXml method of LogoutRequest
1015+
*
1016+
* @throws Exception
1017+
*
1018+
* @see com.onelogin.saml2.logout.LogoutRequest#postProcessXml
1019+
*/
1020+
@Test
1021+
public void testPostProcessXml() throws Exception {
1022+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
1023+
LogoutRequest logoutRequest = new LogoutRequest(settings) {
1024+
@Override
1025+
protected String postProcessXml(String authRequestXml, Saml2Settings sett) {
1026+
assertEquals(authRequestXml, super.postProcessXml(authRequestXml, sett));
1027+
assertSame(settings, sett);
1028+
return "changed";
1029+
}
1030+
};
1031+
assertEquals("changed", logoutRequest.getLogoutRequestXml());
1032+
}
10111033
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.junit.Assert.assertEquals;
66
import static org.junit.Assert.assertThat;
77
import static org.junit.Assert.assertNull;
8+
import static org.junit.Assert.assertSame;
89
import static org.junit.Assert.assertFalse;
910
import static org.junit.Assert.assertNotEquals;
1011
import static org.junit.Assert.assertNotNull;
@@ -717,4 +718,26 @@ public void testGetError() throws URISyntaxException, IOException, XMLEntityExce
717718
private static HttpRequest newHttpRequest(String requestURL, String samlResponseEncoded) {
718719
return new HttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded);
719720
}
721+
722+
/**
723+
* Tests the postProcessXml method of LogoutResponse
724+
*
725+
* @throws Exception
726+
*
727+
* @see com.onelogin.saml2.logout.LogoutResponse#postProcessXml
728+
*/
729+
@Test
730+
public void testPostProcessXml() throws Exception {
731+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
732+
LogoutResponse logoutResponse = new LogoutResponse(settings, null) {
733+
@Override
734+
protected String postProcessXml(String authRequestXml, Saml2Settings sett) {
735+
assertEquals(authRequestXml, super.postProcessXml(authRequestXml, sett));
736+
assertSame(settings, sett);
737+
return "changed";
738+
}
739+
};
740+
logoutResponse.build();
741+
assertEquals("changed", logoutResponse.getLogoutResponseXml());
742+
}
720743
}

core/src/test/java/com/onelogin/saml2/test/settings/MetadataTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import static org.junit.Assert.assertThat;
88
import static org.junit.Assert.assertTrue;
99
import static org.junit.Assert.assertNull;
10-
10+
import static org.junit.Assert.assertSame;
1111

1212
import java.io.IOException;
1313
import java.security.GeneralSecurityException;
@@ -520,4 +520,25 @@ public void shouldIgnoreCacheDuration() throws CertificateEncodingException, Err
520520
assertNull("should not set cache duration attribute", cacheDurationNode);
521521

522522
}
523+
524+
/**
525+
* Tests the postProcessXml method of Metadata
526+
*
527+
* @throws Exception
528+
*
529+
* @see com.onelogin.saml2.settings.Metadata#postProcessXml
530+
*/
531+
@Test
532+
public void testPostProcessXml() throws Exception {
533+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
534+
Metadata metadata = new Metadata(settings) {
535+
@Override
536+
protected String postProcessXml(String authRequestXml, Saml2Settings sett) {
537+
assertEquals(authRequestXml, super.postProcessXml(authRequestXml, sett));
538+
assertSame(settings, sett);
539+
return "changed";
540+
}
541+
};
542+
assertEquals("changed", metadata.getMetadataString());
543+
}
523544
}

0 commit comments

Comments
 (0)