diff --git a/.classpath b/.classpath
index 92adcf1..8124950 100644
--- a/.classpath
+++ b/.classpath
@@ -19,10 +19,15 @@
+
+
+
+
+
+
-
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..839d647
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..cac0df4
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..88579cf
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..6bdc57d
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs
new file mode 100644
index 0000000..04cad8c
--- /dev/null
+++ b/.settings/org.eclipse.wst.validation.prefs
@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1
diff --git a/pom.xml b/pom.xml
index 79463b2..56b16c0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,8 +12,8 @@
UTF-8
- 1.6
- 1.6
+ 1.8
+ 1.8
diff --git a/src/main/java/com/lastpass/saml/IdPConfig.java b/src/main/java/com/lastpass/saml/IdPConfig.java
index e96ef5c..e08207d 100644
--- a/src/main/java/com/lastpass/saml/IdPConfig.java
+++ b/src/main/java/com/lastpass/saml/IdPConfig.java
@@ -209,6 +209,9 @@ private Certificate certFromString(String b64data)
/** Certificate used to validate assertions */
private Certificate cert;
+ /** Host to replace in login URL and logout URL*/
+ private String host;
+
/**
* Set the Idp Entity Id.
*/
@@ -240,6 +243,9 @@ public void setLoginUrl(String loginUrl)
*/
public String getLoginUrl()
{
+ if(host != null && host.length() > 0) {
+ return SAMLUtils.replaceHost(loginUrl, host);
+ }
return this.loginUrl;
}
@@ -277,6 +283,25 @@ public void setLogoutUrl(String logoutUrl)
*/
public String getLogoutUrl()
{
+ if(host != null && host.length() > 0) {
+ return SAMLUtils.replaceHost(loginUrl, host);
+ }
return this.logoutUrl;
}
+
+ /**
+ * Set the replace host of login URL and logout URL.
+ */
+ public void setHost(String host)
+ {
+ this.host = host;
+ }
+
+ /**
+ * Get the replace host of login URL and logout URL.
+ */
+ public String getHost()
+ {
+ return this.host;
+ }
}
diff --git a/src/main/java/com/lastpass/saml/SAMLClient.java b/src/main/java/com/lastpass/saml/SAMLClient.java
index 5627d94..283b42e 100644
--- a/src/main/java/com/lastpass/saml/SAMLClient.java
+++ b/src/main/java/com/lastpass/saml/SAMLClient.java
@@ -168,6 +168,20 @@ public static SAMLClient getInstance()
return _instance;
}
+ // [dew]
+ public static SAMLClient getInstance(String host)
+ throws Exception
+ {
+ if(_instance != null) return _instance;
+ SAMLInit.initialize();
+ IdPConfig _idpConfig = new IdPConfig(Thread.currentThread().getContextClassLoader().getResourceAsStream("idp-metadata.xml"));
+ SPConfig _spConfig = new SPConfig(Thread.currentThread().getContextClassLoader().getResourceAsStream("sp-metadata.xml"));
+ _idpConfig.setHost(host);
+ _spConfig.setHost(host);
+ _instance = new SAMLClient(_spConfig, _idpConfig);
+ return _instance;
+ }
+
/**
* Get the configured IdpConfig.
*
@@ -224,10 +238,8 @@ private Assertion decrypt(EncryptedAssertion encrypted)
throw new DecryptionException("Encrypted assertion found but no SP key available");
BasicCredential cred = new BasicCredential();
cred.setPrivateKey(spConfig.getPrivateKey());
- StaticKeyInfoCredentialResolver resolver =
- new StaticKeyInfoCredentialResolver(cred);
- Decrypter decrypter =
- new Decrypter(null, resolver, new InlineEncryptedKeyResolver());
+ StaticKeyInfoCredentialResolver resolver = new StaticKeyInfoCredentialResolver(cred);
+ Decrypter decrypter = new Decrypter(null, resolver, new InlineEncryptedKeyResolver());
decrypter.setRootInNewDocument(true);
return decrypter.decrypt(encrypted);
@@ -261,8 +273,7 @@ private void validate(Response response)
// response must be successful
if (response.getStatus() == null ||
response.getStatus().getStatusCode() == null ||
- !(StatusCode.SUCCESS_URI
- .equals(response.getStatus().getStatusCode().getValue()))) {
+ !(StatusCode.SUCCESS_URI.equals(response.getStatus().getStatusCode().getValue()))) {
throw new ValidationException(
"Response has an unsuccessful status code");
}
diff --git a/src/main/java/com/lastpass/saml/SAMLUtils.java b/src/main/java/com/lastpass/saml/SAMLUtils.java
index 9de2494..02da468 100644
--- a/src/main/java/com/lastpass/saml/SAMLUtils.java
+++ b/src/main/java/com/lastpass/saml/SAMLUtils.java
@@ -141,4 +141,24 @@ else if(iMill < 100) {
}
return sYear + "-" + sMonth + "-" + sDay + "T" + sHour + ":" + sMin + ":" + sSec + "Z";
}
+
+ public static
+ String replaceHost(String url, String host) {
+ if(host == null || host.length() == 0) {
+ return url;
+ }
+ int sepCtx = url.indexOf('/', 8);
+ if(sepCtx < 0) return url;
+ int sepCtxHost = host.indexOf('/', 8);
+ if(sepCtxHost > 0) {
+ host = host.substring(0, sepCtxHost);
+ }
+ if(host.startsWith("http://") || host.startsWith("https://")) {
+ return host + url.substring(sepCtx);
+ }
+ if(url.startsWith("https://")) {
+ return "https://" + host + url.substring(sepCtx);
+ }
+ return "http://" + host + url.substring(sepCtx);
+ }
}
diff --git a/src/main/java/com/lastpass/saml/SPConfig.java b/src/main/java/com/lastpass/saml/SPConfig.java
index 91783f5..67acac7 100644
--- a/src/main/java/com/lastpass/saml/SPConfig.java
+++ b/src/main/java/com/lastpass/saml/SPConfig.java
@@ -50,6 +50,9 @@ class SPConfig
/** Private key used for decrypting assertions */
private PrivateKey privateKey;
+ /** Host to replace in ACS URL*/
+ private String host;
+
/**
* Construct a new, empty SPConfig.
*/
@@ -62,8 +65,7 @@ public SPConfig()
*
* @param metadataFile File where the metadata lives
*
- * @throws SAMLException if an error condition occurs while trying to parse and process
- * the metadata
+ * @throws SAMLException if an error condition occurs while trying to parse and process the metadata
*/
public SPConfig(File metadataFile)
throws SAMLException
@@ -93,8 +95,7 @@ public SPConfig(File metadataFile)
*
* @param inputStream An input stream containing a metadata XML document
*
- * @throws SAMLException if an error condition occurs while trying to parse and process
- * the metadata
+ * @throws SAMLException if an error condition occurs while trying to parse and process the metadata
*/
public SPConfig(InputStream inputStream)
throws SAMLException
@@ -114,8 +115,7 @@ private void init(InputStream inputStream)
Document doc = parsers.parse(inputStream);
Element root = doc.getDocumentElement();
- UnmarshallerFactory unmarshallerFactory =
- Configuration.getUnmarshallerFactory();
+ UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
edesc = (EntityDescriptor) unmarshallerFactory
.getUnmarshaller(root)
@@ -129,8 +129,7 @@ private void init(InputStream inputStream)
}
// fetch sp information
- SPSSODescriptor spDesc = edesc.getSPSSODescriptor(
- "urn:oasis:names:tc:SAML:2.0:protocol");
+ SPSSODescriptor spDesc = edesc.getSPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol");
if (spDesc == null)
throw new SAMLException("No SP SSO descriptor found");
@@ -165,12 +164,16 @@ public void setEntityId(String entityId)
*/
public String getEntityId()
{
+ if(host != null && host.length() > 0) {
+ if(entityId != null && entityId.startsWith("http")) {
+ return SAMLUtils.replaceHost(entityId, host);
+ }
+ }
return this.entityId;
}
/**
- * Set the SP ACS URL. Auth responses are posted
- * here.
+ * Set the SP ACS URL. Auth responses are posted here.
*/
public void setAcs(String acs)
{
@@ -182,6 +185,9 @@ public void setAcs(String acs)
*/
public String getAcs()
{
+ if(host != null && host.length() > 0) {
+ return SAMLUtils.replaceHost(acs, host);
+ }
return this.acs;
}
@@ -200,4 +206,21 @@ public PrivateKey getPrivateKey()
{
return this.privateKey;
}
+
+
+ /**
+ * Set the replace host of ACS URL.
+ */
+ public void setHost(String host)
+ {
+ this.host = host;
+ }
+
+ /**
+ * Get the replace host of ACS URL.
+ */
+ public String getHost()
+ {
+ return this.host;
+ }
}
diff --git a/src/main/java/org/dew/saml/web/WebLogin.java b/src/main/java/org/dew/saml/web/WebLogin.java
index e0cccdc..87f0743 100644
--- a/src/main/java/org/dew/saml/web/WebLogin.java
+++ b/src/main/java/org/dew/saml/web/WebLogin.java
@@ -1,15 +1,20 @@
package org.dew.saml.web;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
-import javax.servlet.http.*;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import org.opensaml.saml2.core.AuthnRequest;
import com.lastpass.saml.SAMLIdP;
-import javax.servlet.*;
-
public
class WebLogin extends HttpServlet
{
diff --git a/src/main/java/org/dew/saml/web/WebSLO.java b/src/main/java/org/dew/saml/web/WebSLO.java
index 9e21190..429eb62 100644
--- a/src/main/java/org/dew/saml/web/WebSLO.java
+++ b/src/main/java/org/dew/saml/web/WebSLO.java
@@ -1,15 +1,20 @@
package org.dew.saml.web;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
-import javax.servlet.http.*;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import org.opensaml.saml2.core.LogoutRequest;
import com.lastpass.saml.SAMLIdP;
-import javax.servlet.*;
-
public
class WebSLO extends HttpServlet
{
diff --git a/src/main/java/org/dew/saml/web/WebSSO.java b/src/main/java/org/dew/saml/web/WebSSO.java
index 61fe295..3c44ed1 100644
--- a/src/main/java/org/dew/saml/web/WebSSO.java
+++ b/src/main/java/org/dew/saml/web/WebSSO.java
@@ -1,15 +1,20 @@
package org.dew.saml.web;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
-import javax.servlet.http.*;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import org.opensaml.saml2.core.AuthnRequest;
import com.lastpass.saml.SAMLIdP;
-import javax.servlet.*;
-
public
class WebSSO extends HttpServlet
{