Skip to content

Commit 2c6b79c

Browse files
authored
Merge pull request #61 from miszobi/issue/60-allow-retrieving-request-ids
#60: allow retrieving the generated request ids
2 parents 525ba97 + 66d4a05 commit 2c6b79c

8 files changed

Lines changed: 65 additions & 82 deletions

File tree

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

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
* Defines the methods that you can invoke in your application in
3838
* order to add SAML support (initiates sso, initiates slo, processes a
3939
* SAML Response, a Logout Request or a Logout Response).
40+
*
41+
* This is stateful and not thread-safe, you should create a new instance for each request/response.
4042
*/
4143
public class Auth {
4244
/**
@@ -94,6 +96,11 @@ public class Auth {
9496
*/
9597
private String errorReason;
9698

99+
/**
100+
* The id of the last request (Authn or Logout) generated
101+
*/
102+
private String lastRequestId;
103+
97104
/**
98105
* Initializes the SP SAML instance.
99106
*
@@ -191,14 +198,15 @@ public void setStrict(Boolean value)
191198
/**
192199
* Initiates the SSO process.
193200
*
194-
* @param returnTo
195-
* The target URL the user should be returned to after login.
196-
* @param forceAuthn
197-
* When true the AuthNReuqest will set the ForceAuthn='true'
198-
* @param isPassive
199-
* When true the AuthNReuqest will set the IsPassive='true'
201+
* @param returnTo
202+
* The target URL the user should be returned to after login.
203+
* @param forceAuthn
204+
* When true the AuthNRequest will set the ForceAuthn='true'
205+
* @param isPassive
206+
* When true the AuthNRequest will set the IsPassive='true'
200207
* @param setNameIdPolicy
201-
* When true the AuthNReuqest will set a nameIdPolicy
208+
* When true the AuthNRequest will set a nameIdPolicy
209+
* @return the representation of the AuthNRequest generated
202210
* @throws IOException
203211
*/
204212
public void login(String returnTo, Boolean forceAuthn, Boolean isPassive, Boolean setNameIdPolicy) throws IOException {
@@ -229,6 +237,7 @@ public void login(String returnTo, Boolean forceAuthn, Boolean isPassive, Boolea
229237

230238
LOGGER.debug("AuthNRequest sent to " + ssoUrl + " --> " + samlRequest);
231239
Util.sendRedirect(response, ssoUrl, parameters);
240+
lastRequestId = authnRequest.getId();
232241
}
233242

234243
/**
@@ -292,6 +301,7 @@ public void logout(String returnTo, String nameId, String sessionIndex) throws I
292301
String sloUrl = getSLOurl();
293302
LOGGER.debug("Logout request sent to " + sloUrl + " --> " + samlLogoutRequest);
294303
Util.sendRedirect(response, sloUrl, parameters);
304+
lastRequestId = logoutRequest.getId();
295305
}
296306

297307
/**
@@ -538,7 +548,15 @@ public String getLastErrorReason()
538548
{
539549
return errorReason;
540550
}
541-
551+
552+
/**
553+
* @return the id of the last request generated (AuthnRequest or LogoutRequest), null if none
554+
*/
555+
public String getLastRequestId()
556+
{
557+
return lastRequestId;
558+
}
559+
542560
/**
543561
* @return the Saml2Settings object. The Settings data.
544562
*/

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,12 @@ private static StringBuilder getAuthnRequestTemplate() {
186186
template.append("${nameIDPolicyStr}${requestedAuthnContextStr}</samlp:AuthnRequest>");
187187
return template;
188188
}
189+
190+
/**
191+
* @return the generated id of the AuthnRequest message
192+
*/
193+
public String getId()
194+
{
195+
return id;
196+
}
189197
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,4 +599,12 @@ public static List<String> getSessionIndexes(String samlLogoutRequestString) thr
599599
public String getError() {
600600
return error;
601601
}
602+
603+
/**
604+
* @return the generated id of the LogoutRequest message
605+
*/
606+
public String getId()
607+
{
608+
return id;
609+
}
602610
}

core/src/main/java/com/onelogin/saml2/util/Util.java

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public final class Util {
103103

104104
private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(DateTimeZone.UTC);
105105
private static final DateTimeFormatter DATE_TIME_FORMAT_MILLS = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(DateTimeZone.UTC);
106+
public static final String UNIQUE_ID_PREFIX = "ONELOGIN_";
106107

107108
/**
108109
* This function load an XML string in a save way. Prevent XEE/XXE Attacks
@@ -1344,50 +1345,9 @@ private static SecretKey generateSymmetricKey() throws Exception {
13441345
* @return A unique string
13451346
*/
13461347
public static String generateUniqueID() {
1347-
String uniqueIdSha1 = StringUtils.EMPTY;
1348-
String uniqueId = StringUtils.EMPTY;
1349-
1350-
try {
1351-
Random r = new Random();
1352-
Integer n = r.nextInt();
1353-
1354-
String id = uniqid(n.toString(), true);
1355-
1356-
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
1357-
crypt.reset();
1358-
crypt.update(id.getBytes());
1359-
uniqueIdSha1 = new BigInteger(1, crypt.digest()).toString(16);
1360-
1361-
uniqueId = "ONELOGIN_" + uniqueIdSha1;
1362-
} catch (Exception e) {
1363-
LOGGER.error("Error executing generateUniqueID: " + e.getMessage(), e);
1364-
}
1365-
return uniqueId;
1366-
}
1367-
1368-
/**
1369-
* Generates random UUID
1370-
*
1371-
* @param prefix
1372-
*
1373-
* @param more_entropy
1374-
*
1375-
* @return the random UUID
1376-
*/
1377-
public static String uniqid(String prefix, Boolean more_entropy) {
1378-
if (prefix != null && StringUtils.isEmpty(prefix)) {
1379-
prefix = StringUtils.EMPTY;
1380-
}
1381-
1382-
if (!more_entropy) {
1383-
return (String) (prefix + UUID.randomUUID().toString()).substring(
1384-
0, 13);
1385-
} else {
1386-
return (String) (prefix + UUID.randomUUID().toString() + UUID
1387-
.randomUUID().toString()).substring(0, 23);
1388-
}
1348+
return UNIQUE_ID_PREFIX + UUID.randomUUID();
13891349
}
1390-
1350+
13911351
/**
13921352
* Interprets a ISO8601 duration value relative to a current time timestamp.
13931353
*

core/src/test/java/com/onelogin/saml2/test/AuthTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.onelogin.saml2.test;
22

33

4+
import static com.onelogin.saml2.util.Util.UNIQUE_ID_PREFIX;
45
import static org.hamcrest.CoreMatchers.is;
56
import static org.hamcrest.CoreMatchers.containsString;
67
import static org.hamcrest.CoreMatchers.not;
8+
import static org.hamcrest.CoreMatchers.startsWith;
79
import static org.junit.Assert.assertEquals;
810
import static org.junit.Assert.assertFalse;
911
import static org.junit.Assert.assertNotEquals;
@@ -91,6 +93,7 @@ public void testConstructor() throws IOException, SettingsException {
9193
Saml2Settings settings = new SettingsBuilder().fromFile("onelogin.saml.properties").build();
9294
assertEquals(settings.getIdpEntityId(), auth.getSettings().getIdpEntityId());
9395
assertEquals(settings.getSpEntityId(), auth.getSettings().getSpEntityId());
96+
assertNull(auth.getLastRequestId());
9497
}
9598

9699
/**
@@ -896,6 +899,7 @@ public void testLogin() throws IOException, SettingsException, URISyntaxExceptio
896899
Auth auth = new Auth(settings, request, response);
897900
auth.login();
898901
verify(response).sendRedirect(matches("https:\\/\\/pitbulk.no-ip.org\\/simplesaml\\/saml2\\/idp\\/SSOService.php\\?SAMLRequest=(.)*&RelayState=http%3A%2F%2Flocalhost%3A8080%2Finitial.jsp"));
902+
assertThat(auth.getLastRequestId(), startsWith(Util.UNIQUE_ID_PREFIX));
899903
}
900904

901905
/**
@@ -1011,6 +1015,7 @@ public void testLogout() throws IOException, SettingsException, XMLEntityExcepti
10111015
auth.logout();
10121016

10131017
verify(response).sendRedirect(matches("https:\\/\\/pitbulk.no-ip.org\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLRequest=(.)*&RelayState=http%3A%2F%2Flocalhost%3A8080%2Finitial.jsp"));
1018+
assertThat(auth.getLastRequestId(), startsWith(Util.UNIQUE_ID_PREFIX));
10141019
}
10151020

10161021
/**

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ public void testAuthNContext() throws Exception {
241241
assertThat(authnRequestStr, containsString("<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:X509</saml:AuthnContextClassRef>"));
242242
}
243243

244+
@Test
245+
public void testAuthNId() throws Exception
246+
{
247+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
248+
249+
AuthnRequest authnRequest = new AuthnRequest(settings);
250+
final String authnRequestStr = Util.base64decodedInflated(authnRequest.getEncodedAuthnRequest());
251+
252+
assertThat(authnRequestStr, containsString("<samlp:AuthnRequest"));
253+
assertThat(authnRequestStr, containsString("ID=\"" + authnRequest.getId() + "\""));
254+
}
255+
244256
/**
245257
* Tests the AuthnRequest Constructor
246258
* The creation of a deflated SAML Request with and without Destination

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public void testConstructor() throws Exception {
8181
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
8282

8383
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
84+
assertThat(logoutRequestStr, containsString("ID=\"" + logoutRequest.getId() + "\""));
8485
assertThat(logoutRequestStr, not(containsString("<samlp:SessionIndex>")));
8586
}
8687

core/src/test/java/com/onelogin/saml2/test/util/UtilsTest.java

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static org.hamcrest.CoreMatchers.containsString;
55
import static org.hamcrest.CoreMatchers.not;
66
import static org.hamcrest.CoreMatchers.equalTo;
7+
import static org.hamcrest.CoreMatchers.startsWith;
78
import static org.junit.Assert.assertEquals;
89
import static org.junit.Assert.assertFalse;
910
import static org.junit.Assert.assertNotEquals;
@@ -1893,7 +1894,7 @@ public void testGenerateNameId() throws URISyntaxException, IOException, Certifi
18931894
public void testGenerateUniqueID() {
18941895
String s1 = Util.generateUniqueID();
18951896

1896-
assertThat(s1, containsString("ONELOGIN_"));
1897+
assertThat(s1, startsWith(Util.UNIQUE_ID_PREFIX));
18971898
assertTrue(s1.length() > 40);
18981899

18991900
String s2 = Util.generateUniqueID();
@@ -1903,36 +1904,6 @@ public void testGenerateUniqueID() {
19031904
assertNotEquals(s2, s3);
19041905
}
19051906

1906-
/**
1907-
* Tests the uniqid method
1908-
*
1909-
* @see com.onelogin.saml2.util.Util#uniqid
1910-
*/
1911-
@Test
1912-
public void testUniqid() {
1913-
String id_1 = Util.uniqid(null, false);
1914-
String id_2 = Util.uniqid(null, false);
1915-
assertNotEquals(id_1, id_2);
1916-
1917-
String id_3 = Util.uniqid(null, true);
1918-
String id_4 = Util.uniqid(null, true);
1919-
assertNotEquals(id_3, id_4);
1920-
1921-
assertNotEquals(id_1, id_3);
1922-
assertNotEquals(id_1, id_4);
1923-
assertNotEquals(id_2, id_3);
1924-
assertNotEquals(id_2, id_4);
1925-
1926-
String id_5 = Util.uniqid("ONELOGIN_", false);
1927-
String id_6 = Util.uniqid("ONELOGIN_", true);
1928-
assertThat(id_5, containsString("ONELOGIN_"));
1929-
assertThat(id_6, containsString("ONELOGIN_"));
1930-
assertNotEquals(id_5, id_6);
1931-
1932-
String id_7 = Util.uniqid("", false);
1933-
assertNotEquals(id_6, id_7);
1934-
}
1935-
19361907
/**
19371908
* Tests the parseDuration method
19381909
*

0 commit comments

Comments
 (0)