Skip to content

Commit a7a7ebb

Browse files
committed
Release v2.0.0 (requires docs and project cleanup)
1 parent 1dd4e15 commit a7a7ebb

126 files changed

Lines changed: 11306 additions & 1160 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
bin
12
target
23
.idea
34
*.iml
45
.classpath
56
.settings/
6-
.project
7+
.project

LICENSE

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
Copyright (c) 2010-2015 OneLogin, LLC
1+
Copyright (c) 2010-2016 OneLogin, Inc.
22

3-
Permission is hereby granted, free of charge, to any person obtaining a copy
4-
of this software and associated documentation files (the "Software"), to deal
5-
in the Software without restriction, including without limitation the rights
6-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7-
copies of the Software, and to permit persons to whom the Software is
8-
furnished to do so, subject to the following conditions:
3+
Permission is hereby granted, free of charge, to any person
4+
obtaining a copy of this software and associated documentation
5+
files (the "Software"), to deal in the Software without
6+
restriction, including without limitation the rights to use,
7+
copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the
9+
Software is furnished to do so, subject to the following
10+
conditions:
911

10-
The above copyright notice and this permission notice shall be included in
11-
all copies or substantial portions of the Software.
12+
The above copyright notice and this permission notice shall be
13+
included in all copies or substantial portions of the Software.
1214

13-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19-
THE SOFTWARE.
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
1-
# OneLogin's SAML Java SAML
1+
# OneLogin's SAML Java Toolkit
2+
3+
Version 2.0.0-candidate
4+
5+
Under development (Don't use it at production environments)
6+
7+
8+
## Working with Eclipse.
9+
10+
### Adding the toolkit as a project
11+
12+
1. Open Eclipse and set a workspace
13+
2. File > Import > Maven : Existing Maven Projects > Select the path where the core folder of the Java Toolkit is <path>/java-saml/core, resolve the Wordkspace project and select the pom.xml
14+
15+
### Adding the jsp-samlple as a project
16+
17+
3. File > Import > Maven : Existing Maven Projects > Select the path where the core folder of the Java Toolkit is <path>/java-saml/samples/java-saml-jspsample, resolve the Wordkspace project and select the pom.xml
18+
19+
### Deploy the jsp-sample
20+
21+
At the Package Explorer, select the jsp-sample project, 2nd bottom of the mouse and Run As > Run Server
22+
Select a Tomcat Server in order to deploy the server.
223

3-
Candidate version 2.0.0
424

5-
Under development (Don't use it in production)

core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
<version>1.6.2</version>
3535
<scope>test</scope>
3636
</dependency>
37+
<dependency>
38+
<groupId>org.powermock</groupId>
39+
<artifactId>powermock-module-junit4-rule-agent</artifactId>
40+
<version>1.6.4</version>
41+
<scope>test</scope>
42+
</dependency>
3743

3844
<!-- for log -->
3945
<dependency>

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

Lines changed: 111 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.security.PrivateKey;
77
import java.security.SignatureException;
88
import java.util.ArrayList;
9-
import java.util.Calendar;
109
import java.util.Collection;
1110
import java.util.HashMap;
1211
import java.util.List;
@@ -16,6 +15,7 @@
1615
import javax.servlet.http.HttpServletRequest;
1716

1817
import org.apache.commons.lang3.StringUtils;
18+
import org.joda.time.DateTime;
1919
import org.slf4j.Logger;
2020
import org.slf4j.LoggerFactory;
2121

@@ -72,7 +72,7 @@ public class Auth {
7272
/**
7373
* SessionNotOnOrAfter. When the user is logged, this stored it from the AuthnStatement of the SAML Response
7474
*/
75-
private Calendar sessionExpiration;
75+
private DateTime sessionExpiration;
7676

7777
/**
7878
* User attributes data.
@@ -104,6 +104,19 @@ public Auth() throws IOException, SettingsException {
104104
this(new SettingsBuilder().fromFile("onelogin.saml.properties").build(), null, null);
105105
}
106106

107+
/**
108+
* Initializes the SP SAML instance.
109+
*
110+
* @param filename
111+
* String Filename with the settings
112+
*
113+
* @throws IOException
114+
* @throws SettingsException
115+
*/
116+
public Auth(String filename) throws IOException, SettingsException {
117+
this(new SettingsBuilder().fromFile(filename).build(), null, null);
118+
}
119+
107120
/**
108121
* Initializes the SP SAML instance.
109122
*
@@ -119,6 +132,23 @@ public Auth(HttpServletRequest request, HttpServletResponse response) throws IOE
119132
this(new SettingsBuilder().fromFile("onelogin.saml.properties").build(), request, response);
120133
}
121134

135+
/**
136+
* Initializes the SP SAML instance.
137+
*
138+
* @param filename
139+
* String Filename with the settings
140+
* @param request
141+
* HttpServletRequest object to be processed
142+
* @param response
143+
* HttpServletResponse object to be used
144+
*
145+
* @throws SettingsException
146+
* @throws IOException
147+
*/
148+
public Auth(String filename, HttpServletRequest request, HttpServletResponse response) throws SettingsException, IOException {
149+
this(new SettingsBuilder().fromFile(filename).build(), request, response);
150+
}
151+
122152
/**
123153
* Initializes the SP SAML instance.
124154
*
@@ -167,13 +197,14 @@ public void setStrict(Boolean value)
167197
* When true the AuthNReuqest will set the ForceAuthn='true'
168198
* @param isPassive
169199
* When true the AuthNReuqest will set the IsPassive='true'
170-
*
200+
* @param setNameIdPolicy
201+
* When true the AuthNReuqest will set a nameIdPolicy
171202
* @throws IOException
172203
*/
173-
public void login(String returnTo, Boolean forceAuthn, Boolean isPassive) throws IOException {
204+
public void login(String returnTo, Boolean forceAuthn, Boolean isPassive, Boolean setNameIdPolicy) throws IOException {
174205
Map<String, String> parameters = new HashMap<String, String>();
175206

176-
AuthnRequest authnRequest = new AuthnRequest(settings, forceAuthn, isPassive);
207+
AuthnRequest authnRequest = new AuthnRequest(settings, forceAuthn, isPassive, setNameIdPolicy);
177208

178209
String samlRequest = authnRequest.getEncodedAuthnRequest();
179210
parameters.put("SAMLRequest", samlRequest);
@@ -206,7 +237,19 @@ public void login(String returnTo, Boolean forceAuthn, Boolean isPassive) throws
206237
* @throws IOException
207238
*/
208239
public void login() throws IOException {
209-
login(null ,false, false);
240+
login(null ,false, false, true);
241+
}
242+
243+
/**
244+
* Initiates the SSO process.
245+
*
246+
* @param returnTo
247+
* The target URL the user should be returned to after login.
248+
*
249+
* @throws IOException
250+
*/
251+
public void login(String returnTo) throws IOException {
252+
login(returnTo ,false, false, true);
210253
}
211254

212255
/**
@@ -261,6 +304,20 @@ public void logout() throws IOException, XMLEntityException {
261304
logout(null, null, null);
262305
}
263306

307+
/**
308+
* Initiates the SLO process.
309+
*
310+
* @param returnTo
311+
* The target URL the user should be returned to after logout.
312+
*
313+
* @throws IOException
314+
* @throws XMLEntityException
315+
*/
316+
public void logout(String returnTo) throws IOException, XMLEntityException {
317+
logout(returnTo, null, null);
318+
}
319+
320+
264321
/**
265322
* @return The url of the Single Sign On Service
266323
*/
@@ -343,7 +400,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
343400
errorReason = logoutResponse.getError();
344401
} else {
345402
String status = logoutResponse.getStatus();
346-
if (!status.equals(Constants.STATUS_SUCCESS)) {
403+
if (status == null || !status.equals(Constants.STATUS_SUCCESS)) {
347404
errors.add("logout_not_success");
348405
LOGGER.error("processSLO error. logout_not_success");
349406
LOGGER.debug(" --> " + samlResponseParameter);
@@ -378,7 +435,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
378435
parameters.put("SAMLResponse", samlLogoutResponse);
379436

380437
String relayState = request.getParameter("RelayState");
381-
if (relayState != null && ! relayState.isEmpty()) {
438+
if (relayState != null) {
382439
parameters.put("RelayState", relayState);
383440
}
384441

@@ -419,10 +476,10 @@ public final boolean isAuthenticated() {
419476
}
420477

421478
/**
422-
* @return the set of the names of the SAML attributes.
479+
* @return the list of the names of the SAML attributes.
423480
*/
424-
public final Collection<String> getAttributesName() {
425-
return attributes.keySet();
481+
public final List<String> getAttributesName() {
482+
return new ArrayList<String>(attributes.keySet());
426483
}
427484

428485
/**
@@ -461,13 +518,13 @@ public final String getSessionIndex()
461518
/**
462519
* @return the SessionNotOnOrAfter of the assertion
463520
*/
464-
public final Calendar getSessionExpiration()
521+
public final DateTime getSessionExpiration()
465522
{
466523
return sessionExpiration;
467524
}
468525

469526
/**
470-
* @return an array with the errors, the array is empty when the settings is ok
527+
* @return an array with the errors, the array is empty when the validation was successful
471528
*/
472529
public List<String> getErrors()
473530
{
@@ -511,38 +568,7 @@ public Boolean isDebugActive() {
511568
*/
512569
public String buildRequestSignature(String samlRequest, String relayState, String signAlgorithm)
513570
{
514-
String signature = "";
515-
516-
if (!settings.checkSPCerts()) {
517-
String errorMsg = "Trying to sign the SAML Request but can't load the SP certs";
518-
LOGGER.error("buildRequestSignature error." + errorMsg);
519-
throw new IllegalArgumentException(errorMsg);
520-
}
521-
522-
PrivateKey key = settings.getSPkey();
523-
524-
String msg = "SAMLRequest=" + Util.urlEncoder(samlRequest);
525-
msg += "&RelayState=" + Util.urlEncoder(relayState);
526-
msg += "&SigAlg=" + Util.urlEncoder(signAlgorithm);
527-
528-
try {
529-
signature = Util.base64encoder(Util.sign(msg, key, signAlgorithm));
530-
} catch (InvalidKeyException e) {
531-
LOGGER.error("buildRequestSignature error." + e.getMessage());
532-
} catch (NoSuchAlgorithmException e) {
533-
LOGGER.error("buildRequestSignature error." + e.getMessage());
534-
} catch (SignatureException e) {
535-
LOGGER.error("buildRequestSignature error." + e.getMessage());
536-
}
537-
538-
if (signature.isEmpty()) {
539-
String errorMsg = "There was a problem when calculating the Signature of the SAMLRequest";
540-
LOGGER.error("buildRequestSignature error. " + errorMsg);
541-
throw new IllegalArgumentException(errorMsg);
542-
}
543-
544-
LOGGER.debug("buildRequestSignature success. --> " + signature);
545-
return signature;
571+
return buildSignature(samlRequest, relayState, signAlgorithm, "SAMLRequest");
546572
}
547573

548574
/**
@@ -559,37 +585,45 @@ public String buildRequestSignature(String samlRequest, String relayState, Strin
559585
*/
560586
public String buildResponseSignature(String samlResponse, String relayState, String signAlgorithm)
561587
{
562-
String signature = "";
563-
564-
if (!settings.checkSPCerts()) {
565-
String errorMsg = "Trying to sign the SAML Response but can't load the SP certs";
566-
LOGGER.error("buildResponseSignature error. " + errorMsg);
567-
throw new IllegalArgumentException(errorMsg);
568-
}
569-
570-
PrivateKey key = settings.getSPkey();
571-
572-
String msg = "SAMLResponse=" + Util.urlEncoder(samlResponse);
573-
msg += "&RelayState=" + Util.urlEncoder(relayState);
574-
msg += "&SigAlg=" + Util.urlEncoder(signAlgorithm);
575-
576-
try {
577-
signature = Util.base64encoder(Util.sign(msg, key, signAlgorithm));
578-
} catch (InvalidKeyException e) {
579-
LOGGER.error("buildResponseSignature error. " + e.getMessage());
580-
} catch (NoSuchAlgorithmException e) {
581-
LOGGER.error("buildResponseSignature error. " + e.getMessage());
582-
} catch (SignatureException e) {
583-
LOGGER.error("buildResponseSignature error." + e.getMessage());
584-
}
585-
586-
if (signature.isEmpty()) {
587-
String errorMsg = "There was a problem when calculating the Signature of the SAMLResponse";
588-
LOGGER.error("buildResponseSignature error. " + errorMsg);
589-
throw new IllegalArgumentException(errorMsg);
590-
}
591-
592-
LOGGER.debug("buildResponseSignature success. --> " + signature);
593-
return signature;
588+
return buildSignature(samlResponse, relayState, signAlgorithm, "SAMLResponse");
589+
}
590+
591+
private String buildSignature(String samlMessage, String relayState, String signAlgorithm, String type)
592+
{
593+
String signature = "";
594+
595+
if (!settings.checkSPCerts()) {
596+
String errorMsg = "Trying to sign the " + type + " but can't load the SP certs";
597+
LOGGER.error("buildSignature error. " + errorMsg);
598+
throw new IllegalArgumentException(errorMsg);
599+
}
600+
601+
PrivateKey key = settings.getSPkey();
602+
603+
String msg = type + "=" + Util.urlEncoder(samlMessage);
604+
if (relayState != null) {
605+
msg += "&RelayState=" + Util.urlEncoder(relayState);
606+
}
607+
608+
if (signAlgorithm == null || signAlgorithm.isEmpty()) {
609+
signAlgorithm = Constants.RSA_SHA1;
610+
}
611+
612+
msg += "&SigAlg=" + Util.urlEncoder(signAlgorithm);
613+
614+
try {
615+
signature = Util.base64encoder(Util.sign(msg, key, signAlgorithm));
616+
} catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException e) {
617+
LOGGER.error("buildSignature error." + e.getMessage());
618+
}
619+
620+
if (signature.isEmpty()) {
621+
String errorMsg = "There was a problem when calculating the Signature of the " + type;
622+
LOGGER.error("buildSignature error. " + errorMsg);
623+
throw new IllegalArgumentException(errorMsg);
624+
}
625+
626+
LOGGER.debug("buildResponseSignature success. --> " + signature);
627+
return signature;
594628
}
595629
}

0 commit comments

Comments
 (0)