Skip to content

Commit a183afd

Browse files
committed
Be able to get at the auth object the last processed ID
1 parent 84c1730 commit a183afd

8 files changed

Lines changed: 53 additions & 4 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,21 @@ auth.getLastRequestId()
515515
and later excuting the redirection manually.
516516

517517

518+
### Working behind load balancer
519+
520+
Is possible that asserting request URL and Destination attribute of SAML response fails when working behind load balancer with SSL offload.
521+
522+
You should be able to workaround this by configuring your server so that it is aware of the proxy and returns the original url when requested.
523+
524+
For Apache Tomcat this is done by setting the proxyName, proxyPort, scheme and secure attributes for the Connector. See [here](http://serverfault.com/questions/774300/ssl-offloading-from-apache-to-tomcat-get-overwritten-somewhere) for an example.
525+
526+
527+
### Reply attacks
528+
529+
In order to avoid reply attacks, you can store the ID of the SAML messages already processed, to avoid processing them twice. Since the Messages expires and will be invalidated due that fact, you don't need to store those IDs longer than the time frame that you currently accepting.
530+
531+
Get the ID of the last processed message with the getLastMessageId method of the Auth object.
532+
518533
## Demo included in the toolkit
519534
The Onelogin's Java Toolkit allows you to provide the settings in a unique file as described at the [Settings section](https://github.com/onelogin/java-saml/#Settings).
520535

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,13 @@ public String getSessionIndex() throws XPathExpressionException {
705705
return sessionIndex;
706706
}
707707

708+
/**
709+
* @return the ID of the Response
710+
*/
711+
public String getId() {
712+
return samlResponseDocument.getDocumentElement().getAttributes().getNamedItem("ID").getNodeValue();
713+
}
714+
708715
/**
709716
* @return the ID of the assertion in the Response
710717
* @throws XPathExpressionException

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ public String getError() {
619619
}
620620

621621
/**
622-
* @return the generated id of the LogoutRequest message
622+
* @return the ID of the Logout Request
623623
*/
624624
public String getId()
625625
{

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,19 @@ public String getLogoutResponseXml() {
143143
return logoutResponseString;
144144
}
145145

146+
/**
147+
* @return the ID of the Response
148+
*/
149+
public String getId() {
150+
String idvalue = null;
151+
if (id != null) {
152+
idvalue = id;
153+
} else if (logoutResponseDocument != null) {
154+
idvalue = logoutResponseDocument.getDocumentElement().getAttributes().getNamedItem("ID").getNodeValue();
155+
}
156+
return idvalue;
157+
}
158+
146159
/**
147160
* Determines if the SAML LogoutResponse is valid
148161
*

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1667,7 +1667,6 @@ public void testIsInValidSessionIndex() throws IOException, Error, XPathExpressi
16671667
public void testIsValidSubjectConfirmation_noSubjectConfirmationMethod() throws Exception {
16681668
final Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
16691669
final String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/no_subjectconfirmation_method.xml.base64");
1670-
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
16711670

16721671
assertResponseValid(settings, samlResponseEncoded, false, false, "No Signature found. SAML Response rejected");
16731672
assertResponseValid(settings, samlResponseEncoded, true, false, "A valid SubjectConfirmation was not found on this Response");

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public void testConstructorWithEncryptedNameID() throws Exception {
192192
*
193193
* @throws Exception
194194
*
195-
* @see com.onelogin.saml2.logout.getLogoutRequestXml
195+
* @see com.onelogin.saml2.logout.LogoutRequest#getLogoutRequestXml
196196
*/
197197
@Test
198198
public void testGetLogoutRequestXml() throws Exception {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public void testBuild() throws IOException, XMLEntityException, URISyntaxExcepti
161161
*
162162
* @throws Exception
163163
*
164-
* @see com.onelogin.saml2.logout.getLogoutResponseXml
164+
* @see com.onelogin.saml2.logout.LogoutResponse#getLogoutResponseXml
165165
*/
166166
@Test
167167
public void testGetLogoutRequestXml() throws Exception {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public class Auth {
8181
*/
8282
private DateTime sessionExpiration;
8383

84+
/**
85+
* The ID of the last message processed
86+
*/
87+
private String lastMessageId;
88+
8489
/**
8590
* The ID of the last assertion processed
8691
*/
@@ -474,6 +479,7 @@ public void processResponse(String requestId) throws Exception {
474479
attributes = samlResponse.getAttributes();
475480
sessionIndex = samlResponse.getSessionIndex();
476481
sessionExpiration = samlResponse.getSessionNotOnOrAfter();
482+
lastMessageId = samlResponse.getId();
477483
lastAssertionId = samlResponse.getAssertionId();
478484
lastAssertionNotOnOrAfter = samlResponse.getAssertionNotOnOrAfter();
479485
LOGGER.debug("processResponse success --> " + samlResponseParameter);
@@ -531,6 +537,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
531537
LOGGER.error("processSLO error. logout_not_success");
532538
LOGGER.debug(" --> " + samlResponseParameter);
533539
} else {
540+
lastMessageId = logoutResponse.getId();
534541
LOGGER.debug("processSLO success --> " + samlResponseParameter);
535542
if (!keepLocalSession) {
536543
request.getSession().invalidate();
@@ -546,6 +553,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
546553
LOGGER.debug(" --> " + samlRequestParameter);
547554
errorReason = logoutRequest.getError();
548555
} else {
556+
lastMessageId = logoutRequest.getId();
549557
LOGGER.debug("processSLO success --> " + samlRequestParameter);
550558
if (!keepLocalSession) {
551559
request.getSession().invalidate();
@@ -651,6 +659,13 @@ public final DateTime getSessionExpiration()
651659
return sessionExpiration;
652660
}
653661

662+
/**
663+
* @return The ID of the last message processed
664+
*/
665+
public String getLastMessageId() {
666+
return lastMessageId;
667+
}
668+
654669
/**
655670
* @return The ID of the last assertion processed
656671
*/

0 commit comments

Comments
 (0)