Skip to content

Commit 72520f8

Browse files
authored
Merge branch 'master' into master
2 parents 7f0f070 + ca8d59b commit 72520f8

Some content is hidden

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

46 files changed

+1905
-754
lines changed

.java-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.7
1+
1.8

.nvd-suppressions.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.2.xsd">
3+
4+
</suppressions>

.travis.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
language: java
2-
jdk:
3-
- openjdk7
4-
- openjdk8
5-
# - oraclejdk7 #It seems oraclejdk7 temp fail on Travis
2+
3+
matrix:
4+
include:
5+
- os: linux
6+
dist: trusty
7+
jdk: openjdk8
8+
- os: linux
9+
dist: trusty
10+
jdk: oraclejdk8
11+
- os: linux
12+
dist: xenial
13+
jdk: openjdk9
14+
15+
616
install: true
717
after_success:
8-
- mvn clean test org.jacoco:jacoco-maven-plugin:report org.eluder.coveralls:coveralls-maven-plugin:report
18+
- mvn clean verify org.jacoco:jacoco-maven-plugin:report org.eluder.coveralls:coveralls-maven-plugin:report

README.md

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
Add SAML support to your Java applications using this library.
66
Forget those complicated libraries and use that open source library provided and supported by OneLogin Inc.
77

8-
Version 2.X.X, compatible with java7 / java8.
8+
Version >= 2.5.0 compatible with java8 / java9. Not compatible with java7
9+
2.5.0 sets the 'strict' setting parameter to true.
10+
2.5.0 uses xmlsec 2.1.4 which fixes [CVE-2019-12400](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-460281)
11+
12+
13+
Version 2.0.0 - 2.4.0, compatible with java7 / java8.
914

1015
We [introduced some incompatibilities](https://github.com/onelogin/java-saml/issues/90), that could be fixed and make it compatible with java6.
1116

@@ -82,7 +87,7 @@ Install it as a maven dependency:
8287
<dependency>
8388
<groupId>com.onelogin</groupId>
8489
<artifactId>java-saml</artifactId>
85-
<version>2.4.0</version>
90+
<version>2.5.0</version>
8691
</dependency>
8792
```
8893

@@ -105,8 +110,8 @@ java-saml (com.onelogin:java-saml-toolkit) has the following dependencies:
105110
* For CI:
106111
* org.jacoco:jacoco-maven-plugin
107112

108-
also the [Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_Cryptography_Extension) is required. If you don't have it, download the version of [jce-6](http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html), [jce-7](http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html) or [jce-8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html), unzip it, and drop its content at
109-
*${java.home}/jre/lib/security/*
113+
also the [Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_Cryptography_Extension) is required. If you don't have it, download the version of [jce-8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html), unzip it, and drop its content at
114+
*${java.home}/jre/lib/security/*. JDK 9 and later offer the stronger cryptographic algorithms by default.
110115

111116
*toolkit:*
112117
* com.onelogin:java-saml-core
@@ -118,7 +123,7 @@ also the [Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_
118123
* org.apache.maven.plugins:maven-enforcer-plugin
119124

120125
For more info, open and read the different pom.xml files:
121-
[core/pom.xml](https://github.com/onelogin/java-saml/blob/v2.2.0/core/pom.xml), [toolkit/pom.xml](https://github.com/onelogin/java-saml/blob/v2.2.0/toolkit/pom.xml)
126+
[core/pom.xml](https://github.com/onelogin/java-saml/blob/v2.5.0/core/pom.xml), [toolkit/pom.xml](https://github.com/onelogin/java-saml/blob/v2.5.0/toolkit/pom.xml)
122127

123128
## Working with the github repository code and Eclipse.
124129
### Get the toolkit.
@@ -228,6 +233,9 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe
228233

229234
onelogin.saml2.sp.x509cert =
230235

236+
# Future SP certificate, to be used during SP Key roll over
237+
onelogin.saml2.sp.x509certNew =
238+
231239
# Requires Format PKCS#8 BEGIN PRIVATE KEY
232240
# If you have PKCS#1 BEGIN RSA PRIVATE KEY convert it by openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem
233241
onelogin.saml2.sp.privatekey =
@@ -321,6 +329,9 @@ onelogin.saml2.security.requested_authncontext = urn:oasis:names:tc:SAML:2.0:ac:
321329
# Allows the authn comparison parameter to be set, defaults to 'exact'
322330
onelogin.saml2.security.requested_authncontextcomparison = exact
323331

332+
# Allows duplicated names in the attribute statement
333+
onelogin.saml2.security.allow_duplicated_attribute_name = false
334+
324335
# Indicates if the SP will validate all received xmls.
325336
# (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).
326337
onelogin.saml2.security.want_xml_validation = true
@@ -351,6 +362,28 @@ onelogin.saml2.contacts.support.email_address = support@example.com
351362
# onelogin.saml2.unique_id_prefix = _
352363
```
353364

365+
##### KeyStores
366+
367+
The Auth constructor supports the ability to read SP public cert/private key from a KeyStore. A KeyStoreSettings object must be provided with the KeyStore, the Alias and the KeyEntry password.
368+
369+
```java
370+
import java.io.FileInputStream;
371+
import java.security.KeyStore;
372+
import com.onelogin.saml2.Auth
373+
import com.onelogin.saml2.model.KeyStoreSettings
374+
375+
String keyStoreFile = "oneloginTestKeystore.jks";
376+
String alias = "keywithpassword";
377+
String storePass = "changeit";
378+
String keyPassword = "keypassword";
379+
380+
KeyStore ks = KeyStore.getInstance("JKS");
381+
ks.load(new FileInputStream(keyStoreFile), storePass.toCharArray());
382+
383+
KeyStoreSettings keyStoreSettings = new keyStoreSettings(ks, alias, keyPassword);
384+
Auth auth = new Auth(KeyStoreSettings keyStoreSetting);
385+
```
386+
354387
##### Dynamic Settings
355388
It is possible to build settings programmatically. You can load your values from different sources such as files, databases, or generated values.
356389

@@ -393,11 +426,12 @@ We can set a 'returnTo' url parameter to the login function and that will be con
393426
String targetUrl = 'https://example.com';
394427
auth.login(returnTo=targetUrl)
395428
```
396-
The login method can receive 4 more optional parameters:
429+
The login method can receive 5 more optional parameters:
397430
- *forceAuthn* When true the AuthNRequest will have the 'ForceAuthn' attribute set to 'true'
398431
- *isPassive* When true the AuthNRequest will have the 'Ispassive' attribute set to 'true'
399432
- *setNameIdPolicy* When true the AuthNRequest will set a nameIdPolicy element.
400433
- *stay* Set to true to stay (returns the url string), otherwise set to false to execute a redirection to that url (IdP SSO URL)
434+
- *nameIdValueReq* Indicates to the IdP the subject that should be authenticated
401435

402436
By default, the login method initiates a redirect to the SAML Identity Provider. You can use the *stay* parameter, to prevent that, and execute the redirection manually. We need to use that if a match on the future SAMLResponse ID and the AuthNRequest ID to be sent is required. That AuthNRequest ID must be extracted and stored for future validation, so we can't execute the redirection on the login. Instead, set *stay* to true, then get that ID by
403437
```

core/pom.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>com.onelogin</groupId>
55
<artifactId>java-saml-toolkit</artifactId>
6-
<version>2.4.1-SNAPSHOT</version>
6+
<version>2.5.1-SNAPSHOT</version>
77
</parent>
88

99
<packaging>jar</packaging>
@@ -48,7 +48,7 @@
4848
<dependency>
4949
<groupId>joda-time</groupId>
5050
<artifactId>joda-time</artifactId>
51-
<version>2.9.4</version>
51+
<version>2.10.6</version>
5252
</dependency>
5353

5454
<!-- commons -->
@@ -60,12 +60,12 @@
6060
<dependency>
6161
<groupId>org.apache.santuario</groupId>
6262
<artifactId>xmlsec</artifactId>
63-
<version>2.0.7</version>
63+
<version>2.2.0</version>
6464
</dependency>
6565
<dependency>
6666
<groupId>commons-codec</groupId>
6767
<artifactId>commons-codec</artifactId>
68-
<version>1.10</version>
68+
<version>1.15</version>
6969
</dependency>
7070
</dependencies>
7171

@@ -74,7 +74,7 @@
7474
<plugin>
7575
<groupId>org.jacoco</groupId>
7676
<artifactId>jacoco-maven-plugin</artifactId>
77-
<version>0.8.2</version>
77+
<version>0.8.6</version>
7878
<configuration>
7979
<propertyName>jacoco.agent.argLine</propertyName>
8080
</configuration>
@@ -90,7 +90,7 @@
9090
<plugin>
9191
<groupId>org.apache.maven.plugins</groupId>
9292
<artifactId>maven-jar-plugin</artifactId>
93-
<version>2.4</version>
93+
<version>3.2.0</version>
9494
<executions>
9595
<execution>
9696
<goals>
@@ -102,22 +102,22 @@
102102
<plugin>
103103
<groupId>org.apache.maven.plugins</groupId>
104104
<artifactId>maven-surefire-plugin</artifactId>
105-
<version>2.12</version>
105+
<version>2.22.2</version>
106106
<configuration>
107107
<argLine>${jacoco.agent.argLine}</argLine>
108108
</configuration>
109109
</plugin>
110110
<plugin>
111111
<groupId>org.apache.maven.plugins</groupId>
112112
<artifactId>maven-enforcer-plugin</artifactId>
113-
<version>1.1.1</version>
113+
<version>1.4.1</version>
114114
<executions>
115115
<execution>
116116
<id>enforce</id>
117117
<configuration>
118118
<rules>
119119
<evaluateBeanshell>
120-
<condition>javax.crypto.Cipher.getMaxAllowedKeyLength("AES") &gt; 128</condition>
120+
<condition>javax.crypto.Cipher.getMaxAllowedKeyLength("AES") > 128</condition>
121121
</evaluateBeanshell>
122122
</rules>
123123
</configuration>

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public class AuthnRequest {
5757
*/
5858
private final boolean setNameIdPolicy;
5959

60+
/**
61+
* Indicates to the IdP the subject that should be authenticated
62+
*/
63+
private final String nameIdValueReq;
6064

6165
/**
6266
* Time stamp that indicates when the AuthNRequest was created
@@ -84,20 +88,39 @@ public AuthnRequest(Saml2Settings settings) {
8488
* When true the AuthNReuqest will set the IsPassive='true'
8589
* @param setNameIdPolicy
8690
* When true the AuthNReuqest will set a nameIdPolicy
91+
* @param nameIdValueReq
92+
* Indicates to the IdP the subject that should be authenticated
8793
*/
88-
public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy) {
94+
public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy, String nameIdValueReq) {
8995
this.id = Util.generateUniqueID(settings.getUniqueIDPrefix());
9096
issueInstant = Calendar.getInstance();
9197
this.isPassive = isPassive;
9298
this.settings = settings;
9399
this.forceAuthn = forceAuthn;
94100
this.setNameIdPolicy = setNameIdPolicy;
101+
this.nameIdValueReq = nameIdValueReq;
95102

96103
StrSubstitutor substitutor = generateSubstitutor(settings);
97104
authnRequestString = substitutor.replace(getAuthnRequestTemplate());
98105
LOGGER.debug("AuthNRequest --> " + authnRequestString);
99106
}
100107

108+
/**
109+
* Constructs the AuthnRequest object.
110+
*
111+
* @param settings
112+
* OneLogin_Saml2_Settings
113+
* @param forceAuthn
114+
* When true the AuthNReuqest will set the ForceAuthn='true'
115+
* @param isPassive
116+
* When true the AuthNReuqest will set the IsPassive='true'
117+
* @param setNameIdPolicy
118+
* When true the AuthNReuqest will set a nameIdPolicy
119+
*/
120+
public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy) {
121+
this(settings, forceAuthn, isPassive, setNameIdPolicy, null);
122+
}
123+
101124
/**
102125
* @return the base64 encoded unsigned AuthnRequest (deflated or not)
103126
*
@@ -167,6 +190,16 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
167190
}
168191
valueMap.put("destinationStr", destinationStr);
169192

193+
String subjectStr = "";
194+
if (nameIdValueReq != null && !nameIdValueReq.isEmpty()) {
195+
String nameIDFormat = settings.getSpNameIDFormat();
196+
subjectStr = "<saml:Subject>";
197+
subjectStr += "<saml:NameID Format=\"" + nameIDFormat + "\">" + nameIdValueReq + "</saml:NameID>";
198+
subjectStr += "<saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"></saml:SubjectConfirmation>";
199+
subjectStr += "</saml:Subject>";
200+
}
201+
valueMap.put("subjectStr", subjectStr);
202+
170203
String nameIDPolicyStr = "";
171204
if (setNameIdPolicy) {
172205
String nameIDPolicyFormat = settings.getSpNameIDFormat();
@@ -191,6 +224,7 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
191224
valueMap.put("issueInstant", issueInstantString);
192225
valueMap.put("id", String.valueOf(id));
193226
valueMap.put("assertionConsumerServiceURL", String.valueOf(settings.getSpAssertionConsumerServiceUrl()));
227+
valueMap.put("protocolBinding", settings.getSpAssertionConsumerServiceBinding());
194228
valueMap.put("spEntityid", settings.getSpEntityId());
195229

196230
String requestedAuthnContextStr = "";
@@ -214,9 +248,9 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings) {
214248
*/
215249
private static StringBuilder getAuthnRequestTemplate() {
216250
StringBuilder template = new StringBuilder();
217-
template.append("<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"${id}\" Version=\"2.0\" IssueInstant=\"${issueInstant}\"${providerStr}${forceAuthnStr}${isPassiveStr}${destinationStr} ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" AssertionConsumerServiceURL=\"${assertionConsumerServiceURL}\">");
251+
template.append("<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"${id}\" Version=\"2.0\" IssueInstant=\"${issueInstant}\"${providerStr}${forceAuthnStr}${isPassiveStr}${destinationStr} ProtocolBinding=\"${protocolBinding}\" AssertionConsumerServiceURL=\"${assertionConsumerServiceURL}\">");
218252
template.append("<saml:Issuer>${spEntityid}</saml:Issuer>");
219-
template.append("${nameIDPolicyStr}${requestedAuthnContextStr}</samlp:AuthnRequest>");
253+
template.append("${subjectStr}${nameIDPolicyStr}${requestedAuthnContextStr}</samlp:AuthnRequest>");
220254
return template;
221255
}
222256

0 commit comments

Comments
 (0)