From 89c2df0ecc50efe6bd96358fe4dbc33b5602f46e Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Thu, 19 Aug 2021 09:59:37 +0200 Subject: [PATCH 01/34] Allow to control NameIDPolicy.AllowCreate attribute on AuthnRequest Closes #329. --- .../onelogin/saml2/authn/AuthnRequest.java | 6 +- .../saml2/authn/AuthnRequestParams.java | 77 +++++++++++++++++-- .../saml2/test/authn/AuthnRequestTest.java | 69 +++++++++++++++++ 3 files changed, 143 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java index da64ce46..b5f3811f 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java +++ b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java @@ -229,7 +229,11 @@ private StrSubstitutor generateSubstitutor(AuthnRequestParams params, Saml2Setti if (settings.getWantNameIdEncrypted()) { nameIDPolicyFormat = Constants.NAMEID_ENCRYPTED; } - nameIDPolicyStr = ""; + String allowCreateStr = ""; + if (params.isAllowCreate()) { + allowCreateStr = " AllowCreate=\"true\""; + } + nameIDPolicyStr = ""; } valueMap.put("nameIDPolicyStr", nameIDPolicyStr); diff --git a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java index 6aec5a54..0a7efa48 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java +++ b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java @@ -14,9 +14,14 @@ public class AuthnRequestParams { */ private final boolean isPassive; /** - * When true the AuthNReuqest will set a nameIdPolicy + * When true the AuthNRequest will set a nameIdPolicy */ private final boolean setNameIdPolicy; + /** + * When true and {@link #setNameIdPolicy} is also true, then the + * AllowCreate='true' will be set on the NameIDPolicy element + */ + private final boolean allowCreate; /** * Indicates to the IdP the subject that should be authenticated */ @@ -29,13 +34,34 @@ public class AuthnRequestParams { * whether the ForceAuthn attribute should be set to * true * @param isPassive - * whether the isPassive attribute should be set to + * whether the IsPassive attribute should be set to * true * @param setNameIdPolicy * whether a NameIDPolicy should be set */ public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy) { - this(forceAuthn, isPassive, setNameIdPolicy, null); + this(forceAuthn, isPassive, setNameIdPolicy, true); + } + + /** + * Create a set of authentication request input parameters. + * + * @param forceAuthn + * whether the ForceAuthn attribute should be set to + * true + * @param isPassive + * whether the IsPassive attribute should be set to + * true + * @param setNameIdPolicy + * whether a NameIDPolicy should be set + * @param allowCreate + * whether the AllowCreate attribute should be set to + * true on the NameIDPolicy element; only + * meaningful if setNameIdPolicy is also + * true + */ + public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy, boolean allowCreate) { + this(forceAuthn, isPassive, setNameIdPolicy, allowCreate, null); } /** @@ -45,7 +71,7 @@ public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setName * whether the ForceAuthn attribute should be set to * true * @param isPassive - * whether the isPassive attribute should be set to + * whether the IsPassive attribute should be set to * true * @param setNameIdPolicy * whether a NameIDPolicy should be set @@ -53,9 +79,34 @@ public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setName * the subject that should be authenticated */ public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy, String nameIdValueReq) { + this(forceAuthn, isPassive, setNameIdPolicy, true, nameIdValueReq); + } + + /** + * Create a set of authentication request input parameters. + * + * @param forceAuthn + * whether the ForceAuthn attribute should be set to + * true + * @param isPassive + * whether the IsPassive attribute should be set to + * true + * @param setNameIdPolicy + * whether a NameIDPolicy should be set + * @param allowCreate + * the value to set for the allowCreate attribute of + * NameIDPolicy element; null means it's + * not set at all; only meaningful when + * setNameIdPolicy is true + * @param nameIdValueReq + * the subject that should be authenticated + */ + public AuthnRequestParams(boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy, boolean allowCreate, + String nameIdValueReq) { this.forceAuthn = forceAuthn; this.isPassive = isPassive; this.setNameIdPolicy = setNameIdPolicy; + this.allowCreate = allowCreate; this.nameIdValueReq = nameIdValueReq; } @@ -70,6 +121,7 @@ protected AuthnRequestParams(AuthnRequestParams source) { this.forceAuthn = source.isForceAuthn(); this.isPassive = source.isPassive(); this.setNameIdPolicy = source.isSetNameIdPolicy(); + this.allowCreate = source.isAllowCreate(); this.nameIdValueReq = source.getNameIdValueReq(); } @@ -77,25 +129,34 @@ protected AuthnRequestParams(AuthnRequestParams source) { * @return whether the ForceAuthn attribute should be set to * true */ - protected boolean isForceAuthn() { + public boolean isForceAuthn() { return forceAuthn; } /** - * @return whether the isPassive attribute should be set to + * @return whether the IsPassive attribute should be set to * true */ - protected boolean isPassive() { + public boolean isPassive() { return isPassive; } /** * @return whether a NameIDPolicy should be set */ - protected boolean isSetNameIdPolicy() { + public boolean isSetNameIdPolicy() { return setNameIdPolicy; } + /** + * @return whether the AllowCreate attribute should be set to + * true on the NameIDPolicy element (only + * meaningful if {@link #isSetNameIdPolicy()} is also true) + */ + public boolean isAllowCreate() { + return allowCreate; + } + /** * @return the subject that should be authenticated */ diff --git a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnRequestTest.java b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnRequestTest.java index 3212fb4c..20886fb8 100644 --- a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnRequestTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnRequestTest.java @@ -242,6 +242,75 @@ public void testNameIDPolicy() throws Exception { assertThat(authnRequestStr, containsString("Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\"")); } + /** + * Tests the AuthnRequest Constructor + * The creation of a deflated SAML Request with NameIDPolicy with and without AllowCreate + * + * @throws Exception + * + * @see com.onelogin.saml2.authn.AuthnRequest + */ + @Test + public void testAllowCreate() throws Exception { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + + // by default setNameIdPolicy=true, allowCreate=true + AuthnRequest authnRequest = new AuthnRequest(settings); + String authnRequestStringBase64 = authnRequest.getEncodedAuthnRequest(); + String authnRequestStr = Util.base64decodedInflated(authnRequestStringBase64); + assertThat(authnRequestStr, containsString(" Date: Fri, 2 Apr 2021 19:22:12 +0200 Subject: [PATCH 02/34] Add factories as an extension mechanism for Auth This allows library consumers to extend the standard java-saml message classes with custom implementations while still using the built-in Auth class to orchestrate the message flow, by providing a mechanism to plug-in custom object creation logic. --- .../onelogin/saml2/logout/LogoutResponse.java | 6 +- .../main/java/com/onelogin/saml2/Auth.java | 133 ++++++++++- .../saml2/SamlOutgoingMessageFactory.java | 27 +++ .../saml2/SamlReceivedMessageFactory.java | 28 +++ .../com/onelogin/saml2/test/AuthTest.java | 207 ++++++++++++++++++ 5 files changed, 392 insertions(+), 9 deletions(-) create mode 100644 toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java create mode 100644 toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java index 6deb9ee2..fcc0354d 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java @@ -95,8 +95,10 @@ public class LogoutResponse { * @param settings * OneLogin_Saml2_Settings * @param request - * the HttpRequest object to be processed (Contains GET and POST parameters, request URL, ...). - * + * the HttpRequest object to be processed (Contains GET and POST + * parameters, request URL, ...); may be null when + * building an outgoing logout response + * */ public LogoutResponse(Saml2Settings settings, HttpRequest request) { this.settings = settings; diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index dac4e4e3..e5bd0bc3 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -167,6 +167,20 @@ public class Auth { * encrypted, by default tries to return the decrypted XML */ private String lastResponse; + + private static final SamlOutgoingMessageFactory DEFAULT_AUTHN_REQUEST_FACTORY = AuthnRequest::new; + private static final SamlReceivedMessageFactory DEFAULT_SAML_RESPONSE_FACTORY = SamlResponse::new; + private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; + private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; + private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY = (settings, nothing) -> new LogoutResponse(settings, null); + private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY = LogoutResponse::new; + + private SamlOutgoingMessageFactory authnRequestFactory = DEFAULT_AUTHN_REQUEST_FACTORY; + private SamlReceivedMessageFactory samlResponseFactory = DEFAULT_SAML_RESPONSE_FACTORY; + private SamlOutgoingMessageFactory outgoingLogoutRequestFactory = DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY; + private SamlReceivedMessageFactory receivedLogoutRequestFactory = DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY; + private SamlOutgoingMessageFactory outgoingLogoutResponseFactory = DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; + private SamlReceivedMessageFactory receivedLogoutResponseFactory = DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY; /** * Initializes the SP SAML instance. @@ -609,7 +623,7 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo * @throws SettingsException */ public String login(String relayState, AuthnRequestParams authnRequestParams, Boolean stay, Map parameters) throws IOException, SettingsException { - AuthnRequest authnRequest = new AuthnRequest(settings, authnRequestParams); + AuthnRequest authnRequest = authnRequestFactory.create(settings, authnRequestParams); if (parameters == null) { parameters = new HashMap(); @@ -785,7 +799,7 @@ public String logout(String relayState, LogoutRequestParams logoutRequestParams, parameters = new HashMap(); } - LogoutRequest logoutRequest = new LogoutRequest(settings, logoutRequestParams); + LogoutRequest logoutRequest = outgoingLogoutRequestFactory.create(settings, logoutRequestParams); String samlLogoutRequest = logoutRequest.getEncodedLogoutRequest(); parameters.put("SAMLRequest", samlLogoutRequest); @@ -1196,7 +1210,7 @@ public void processResponse(String requestId) throws Exception { final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - SamlResponse samlResponse = new SamlResponse(settings, httpRequest); + SamlResponse samlResponse = samlResponseFactory.create(settings, httpRequest); lastResponse = samlResponse.getSAMLResponseXml(); if (samlResponse.isValid(requestId)) { @@ -1229,7 +1243,7 @@ public void processResponse(String requestId) throws Exception { errors.add("invalid_response"); LOGGER.error("processResponse error. invalid_response"); LOGGER.debug(" --> " + samlResponseParameter); - } + } } } else { errors.add("invalid_binding"); @@ -1269,7 +1283,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - LogoutResponse logoutResponse = new LogoutResponse(settings, httpRequest); + LogoutResponse logoutResponse = receivedLogoutResponseFactory.create(settings, httpRequest); lastResponse = logoutResponse.getLogoutResponseXml(); if (!logoutResponse.isValid(requestId)) { errors.add("invalid_logout_response"); @@ -1299,7 +1313,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } return null; } else if (samlRequestParameter != null) { - LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest); + LogoutRequest logoutRequest = receivedLogoutRequestFactory.create(settings, httpRequest); lastRequest = logoutRequest.getLogoutRequestXml(); if (!logoutRequest.isValid()) { errors.add("invalid_logout_request"); @@ -1317,7 +1331,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } String inResponseTo = logoutRequest.id; - LogoutResponse logoutResponseBuilder = new LogoutResponse(settings, httpRequest); + LogoutResponse logoutResponseBuilder = outgoingLogoutResponseFactory.create(settings, null); logoutResponseBuilder.build(inResponseTo, Constants.STATUS_SUCCESS); lastResponse = logoutResponseBuilder.getLogoutResponseXml(); @@ -1644,4 +1658,109 @@ public String getLastRequestXML() { public String getLastResponseXML() { return lastResponse; } + + /** + * Sets the factory this {@link Auth} will use to create {@link AuthnRequest} + * objects. + *

+ * This allows consumers to provide their own extension of {@link AuthnRequest} + * possibly implementing custom features and/or XML post-processing. + * + * @param authnRequestFactory + * the factory to use to create {@link AuthnRequest} objects; if + * null, a default provider will be used which creates + * plain {@link AuthnRequest} instances + */ + public void setAuthnRequestFactory( + final SamlOutgoingMessageFactory authnRequestFactory) { + this.authnRequestFactory = authnRequestFactory != null ? authnRequestFactory + : DEFAULT_AUTHN_REQUEST_FACTORY; + } + + /** + * Sets the factory this {@link Auth} will use to create {@link SamlResponse} + * objects. + *

+ * This allows consumers to provide their own extension of {@link SamlResponse} + * possibly implementing custom features and/or XML validation. + * + * @param samlResponseFactory + * the factory to use to create {@link SamlResponse} objects; if + * null, a default factory will be used which creates + * plain {@link SamlResponse} instances + */ + public void setSamlResponseFactory(final SamlReceivedMessageFactory samlResponseFactory) { + this.samlResponseFactory = samlResponseFactory != null? samlResponseFactory: DEFAULT_SAML_RESPONSE_FACTORY; + } + + /** + * Sets the factory this {@link Auth} will use to create outgoing + * {@link LogoutRequest} objects. + *

+ * This allows consumers to provide their own extension of {@link LogoutRequest} + * possibly implementing custom features and/or XML post-processing. + * + * @param outgoingLogoutRequestFactory + * the factory to use to create outgoing {@link LogoutRequest} + * objects; if null, a default provider will be used + * which creates plain {@link LogoutRequest} instances + */ + public void setOutgoingLogoutRequestFactory(final + SamlOutgoingMessageFactory outgoingLogoutRequestFactory) { + this.outgoingLogoutRequestFactory = outgoingLogoutRequestFactory != null? outgoingLogoutRequestFactory: DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY; + } + + /** + * Sets the factory this {@link Auth} will use to create received + * {@link LogoutRequest} objects. + *

+ * This allows consumers to provide their own extension of {@link LogoutRequest} + * possibly implementing custom features and/or XML validation. + * + * @param receivedLogoutRequestFactory + * the factory to use to create received {@link LogoutRequest} + * objects; if null, a default provider will be used + * which creates plain {@link LogoutRequest} instances + */ + public void setReceivedLogoutRequestFactory( + final SamlReceivedMessageFactory receivedLogoutRequestFactory) { + this.receivedLogoutRequestFactory = receivedLogoutRequestFactory != null ? receivedLogoutRequestFactory + : DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY; + } + + /** + * Sets the factory this {@link Auth} will use to create outgoing + * {@link LogoutResponse} objects. + *

+ * This allows consumers to provide their own extension of + * {@link LogoutResponse} possibly implementing custom features and/or XML + * post-processing. + * + * @param outgoingLogoutResponseFactory + * the factory to use to create outgoing {@link LogoutResponse} + * objects; if null, a default provider will be used + * which creates plain {@link LogoutResponse} instances + */ + public void setOutgoingLogoutResponseFactory(final + SamlOutgoingMessageFactory outgoingLogoutResponseFactory) { + this.outgoingLogoutResponseFactory = outgoingLogoutResponseFactory != null? outgoingLogoutResponseFactory: DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; + } + + /** + * Sets the factory this {@link Auth} will use to create received + * {@link LogoutResponse} objects. + *

+ * This allows consumers to provide their own extension of + * {@link LogoutResponse} possibly implementing custom features and/or XML + * validation. + * + * @param receivedLogoutResponseFactory + * the factory to use to create received {@link LogoutResponse} + * objects; if null, a default provider will be used + * which creates plain {@link LogoutResponse} instances + */ + public void setReceivedLogoutResponseFactory(final + SamlReceivedMessageFactory receivedLogoutResponseFactory) { + this.receivedLogoutResponseFactory = receivedLogoutResponseFactory != null? receivedLogoutResponseFactory: DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY; + } } diff --git a/toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java new file mode 100644 index 00000000..8c83b10f --- /dev/null +++ b/toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java @@ -0,0 +1,27 @@ +package com.onelogin.saml2; + +import com.onelogin.saml2.settings.Saml2Settings; + +/** + * Factory which can create an outgoing SAML message object from a + * {@link Saml2Settings} instance and other input parameters. + * + * @param + * the type of input parameters required + * @param + * the type of SAML outgoing message object created + */ +@FunctionalInterface +public interface SamlOutgoingMessageFactory { + + /** + * Creates an outgoing SAML message object. + * + * @param settings + * the settings + * @param params + * the input parameters + * @return the created received SAML message object + */ + R create(Saml2Settings settings, U params); +} \ No newline at end of file diff --git a/toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java new file mode 100644 index 00000000..c086c558 --- /dev/null +++ b/toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java @@ -0,0 +1,28 @@ +package com.onelogin.saml2; + +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.settings.Saml2Settings; + +/** + * Factory which can create a received SAML message object from a + * {@link Saml2Settings} instance and other input parameters. + * + * @param + * the type of received SAML message object created + */ +@FunctionalInterface +public interface SamlReceivedMessageFactory { + + /** + * Creates a received SAML message object. + * + * @param settings + * the settings + * @param httpRequest + * the HTTP request + * @return the created received SAML message object + * @throws Exception + * if the message creation fails + */ + R create(Saml2Settings settings, HttpRequest httpRequest) throws Exception; +} \ No newline at end of file diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index ff8f1e54..8679033e 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -10,6 +10,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.matches; @@ -47,13 +48,19 @@ import org.w3c.dom.Document; import com.onelogin.saml2.Auth; +import com.onelogin.saml2.authn.AuthnRequest; import com.onelogin.saml2.authn.AuthnRequestParams; +import com.onelogin.saml2.authn.SamlResponse; import com.onelogin.saml2.exception.Error; import com.onelogin.saml2.exception.SettingsException; import com.onelogin.saml2.exception.ValidationError; import com.onelogin.saml2.exception.XMLEntityException; +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; +import com.onelogin.saml2.logout.LogoutResponse; import com.onelogin.saml2.model.KeyStoreSettings; +import com.onelogin.saml2.servlet.ServletUtils; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; import com.onelogin.saml2.util.Constants; @@ -2221,4 +2228,204 @@ public void testGetLastLogoutResponseReceived() throws Exception { String logoutResponseXML = auth.getLastResponseXML(); assertThat(logoutResponseXML, containsString(" new LogoutResponseEx(settings, null)); + auth.processSLO(false, null); + } + + /** + * Tests that the received LogoutResponse factory gets invoked by Auth and the right parameters are passed to it. + * + * @throws Exception + * + * @see com.onelogin.saml2.Auth#setReceivedLogoutResponseFactory(com.onelogin.saml2.SamlReceivedMessageFactory) + */ + @Test(expected = FactoryInvokedException.class) + public void testReceivedLogoutResponseFactory() throws Exception { + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + HttpSession session = mock(HttpSession.class); + when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php")); + when(request.getSession()).thenReturn(session); + + String samlResponseEncoded = Util.getFileAsString("data/logout_responses/logout_response_deflated.xml.base64"); + when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded})); + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + + class LogoutResponseEx extends LogoutResponse { + + public LogoutResponseEx(Saml2Settings sett, HttpRequest req) { + super(sett, req); + assertSame(settings, sett); + assertEquals(ServletUtils.makeHttpRequest(request), req); + throw new FactoryInvokedException(); + } + + } + + Auth auth = new Auth(settings, request, response); + auth.setReceivedLogoutResponseFactory(LogoutResponseEx::new); + auth.processSLO(); + } } From 1246cd5e359fb193c9edaa4e05a33103eaf61ca5 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Tue, 27 Jul 2021 14:35:21 +0200 Subject: [PATCH 03/34] Change syntax to avoid javac 8 compilation errors It seems like neither Eclipse ecj nor javac in Java 11 complains when using constructor references in these very special cases used for unit testing. But javac in Java 8 does. So, we're now using lambda expressions in place of constructor references: this seems to make all compilers happy. --- .../test/java/com/onelogin/saml2/test/AuthTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index 8679033e..a77e5583 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -2257,7 +2257,7 @@ public AuthnRequestEx(Saml2Settings sett, AuthnRequestParams par) { } Auth auth = new Auth(settings, request, response); - auth.setAuthnRequestFactory(AuthnRequestEx::new); + auth.setAuthnRequestFactory((sett, param) -> new AuthnRequestEx(sett, param)); auth.login(params); } @@ -2289,7 +2289,7 @@ public SamlResponseEx(Saml2Settings sett, HttpRequest req) throws Exception { } Auth auth = new Auth(settings, request, response); - auth.setSamlResponseFactory(SamlResponseEx::new); + auth.setSamlResponseFactory((sett, req) -> new SamlResponseEx(sett, req)); auth.processResponse(); } @@ -2320,7 +2320,7 @@ public LogoutRequestEx(Saml2Settings sett, LogoutRequestParams par) { } Auth auth = new Auth(settings, request, response); - auth.setOutgoingLogoutRequestFactory(LogoutRequestEx::new); + auth.setOutgoingLogoutRequestFactory((sett, param) -> new LogoutRequestEx(sett, param)); auth.logout(null, params); } @@ -2355,7 +2355,7 @@ public LogoutRequestEx(Saml2Settings sett, HttpRequest req) { } Auth auth = new Auth(settings, request, response); - auth.setReceivedLogoutRequestFactory(LogoutRequestEx::new); + auth.setReceivedLogoutRequestFactory((sett, req) -> new LogoutRequestEx(sett, req)); auth.processSLO(); } @@ -2425,7 +2425,7 @@ public LogoutResponseEx(Saml2Settings sett, HttpRequest req) { } Auth auth = new Auth(settings, request, response); - auth.setReceivedLogoutResponseFactory(LogoutResponseEx::new); + auth.setReceivedLogoutResponseFactory((sett, req) -> new LogoutResponseEx(sett, req)); auth.processSLO(); } } From abd632656b151bd8b984e2a5f055fccc314d63f5 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Fri, 13 Aug 2021 19:13:04 +0200 Subject: [PATCH 04/34] Move message factories to their own package --- toolkit/src/main/java/com/onelogin/saml2/Auth.java | 2 ++ .../{ => factory}/SamlOutgoingMessageFactory.java | 2 +- .../{ => factory}/SamlReceivedMessageFactory.java | 2 +- .../test/java/com/onelogin/saml2/test/AuthTest.java | 12 ++++++------ 4 files changed, 10 insertions(+), 8 deletions(-) rename toolkit/src/main/java/com/onelogin/saml2/{ => factory}/SamlOutgoingMessageFactory.java (94%) rename toolkit/src/main/java/com/onelogin/saml2/{ => factory}/SamlReceivedMessageFactory.java (95%) diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index e5bd0bc3..d3c579bb 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -26,6 +26,8 @@ import com.onelogin.saml2.authn.AuthnRequestParams; import com.onelogin.saml2.authn.SamlResponse; import com.onelogin.saml2.exception.SettingsException; +import com.onelogin.saml2.factory.SamlOutgoingMessageFactory; +import com.onelogin.saml2.factory.SamlReceivedMessageFactory; import com.onelogin.saml2.exception.Error; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutRequest; diff --git a/toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java similarity index 94% rename from toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java rename to toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java index 8c83b10f..7cbdd32c 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/SamlOutgoingMessageFactory.java +++ b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java @@ -1,4 +1,4 @@ -package com.onelogin.saml2; +package com.onelogin.saml2.factory; import com.onelogin.saml2.settings.Saml2Settings; diff --git a/toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java similarity index 95% rename from toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java rename to toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java index c086c558..0a78a800 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/SamlReceivedMessageFactory.java +++ b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java @@ -1,4 +1,4 @@ -package com.onelogin.saml2; +package com.onelogin.saml2.factory; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.settings.Saml2Settings; diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index a77e5583..6bf588f1 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -2237,7 +2237,7 @@ private static class FactoryInvokedException extends RuntimeException { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setAuthnRequestFactory(com.onelogin.saml2.SamlOutgoingMessageFactory) + * @see com.onelogin.saml2.Auth#setAuthnRequestFactory(com.onelogin.saml2.factory.SamlOutgoingMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testAuthnRequestFactory() throws Exception { @@ -2266,7 +2266,7 @@ public AuthnRequestEx(Saml2Settings sett, AuthnRequestParams par) { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setSamlResponseFactory(com.onelogin.saml2.SamlReceivedMessageFactory) + * @see com.onelogin.saml2.Auth#setSamlResponseFactory(com.onelogin.saml2.factory.SamlReceivedMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testSamlResponseFactory() throws Exception { @@ -2298,7 +2298,7 @@ public SamlResponseEx(Saml2Settings sett, HttpRequest req) throws Exception { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setOutgoingLogoutRequestFactory(com.onelogin.saml2.SamlOutgoingMessageFactory) + * @see com.onelogin.saml2.Auth#setOutgoingLogoutRequestFactory(com.onelogin.saml2.factory.SamlOutgoingMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testOutgoingLogoutRequestFactory() throws Exception { @@ -2329,7 +2329,7 @@ public LogoutRequestEx(Saml2Settings sett, LogoutRequestParams par) { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setReceivedLogoutRequestFactory(com.onelogin.saml2.SamlReceivedMessageFactory) + * @see com.onelogin.saml2.Auth#setReceivedLogoutRequestFactory(com.onelogin.saml2.factory.SamlReceivedMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testReceivedLogoutRequestFactory() throws Exception { @@ -2364,7 +2364,7 @@ public LogoutRequestEx(Saml2Settings sett, HttpRequest req) { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setOutgoingLogoutResponseFactory(com.onelogin.saml2.SamlOutgoingMessageFactory) + * @see com.onelogin.saml2.Auth#setOutgoingLogoutResponseFactory(com.onelogin.saml2.factory.SamlOutgoingMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testOutgoingLogoutResponseFactory() throws Exception { @@ -2399,7 +2399,7 @@ public LogoutResponseEx(Saml2Settings sett, HttpRequest req) { * * @throws Exception * - * @see com.onelogin.saml2.Auth#setReceivedLogoutResponseFactory(com.onelogin.saml2.SamlReceivedMessageFactory) + * @see com.onelogin.saml2.Auth#setReceivedLogoutResponseFactory(com.onelogin.saml2.factory.SamlReceivedMessageFactory) */ @Test(expected = FactoryInvokedException.class) public void testReceivedLogoutResponseFactory() throws Exception { From 11bb45d30145430c653b7d0a46ab8e586852a810 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Fri, 13 Aug 2021 21:54:51 +0200 Subject: [PATCH 05/34] Improve LogoutResponse API to match LogoutRequest/AuthnRequest ones This introduces LogoutResponseParams and allows to make the whole API coherent when building outgoing SAML messages. The Auth factories benefit from this as well, because they now share a common construction and usage pattern. --- .../onelogin/saml2/logout/LogoutResponse.java | 136 +++++++--- .../saml2/logout/LogoutResponseParams.java | 105 ++++++++ .../saml2/test/logout/LogoutResponseTest.java | 243 +++++++++++++++--- .../main/java/com/onelogin/saml2/Auth.java | 11 +- .../com/onelogin/saml2/test/AuthTest.java | 14 +- 5 files changed, 425 insertions(+), 84 deletions(-) create mode 100644 core/src/main/java/com/onelogin/saml2/logout/LogoutResponseParams.java diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java index fcc0354d..7199fae9 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java @@ -69,11 +69,6 @@ public class LogoutResponse { */ private String currentUrl; - /** - * The inResponseTo attribute of the Logout Request - */ - private String inResponseTo; - /** * Time when the Logout Request was created */ @@ -85,12 +80,8 @@ public class LogoutResponse { private Exception validationException; /** - * The respone status code and messages - */ - private SamlResponseStatus responseStatus; - - /** - * Constructs the LogoutResponse object. + * Constructs the LogoutResponse object when a received response should be + * extracted from the HTTP request and parsed. * * @param settings * OneLogin_Saml2_Settings @@ -115,6 +106,25 @@ public LogoutResponse(Saml2Settings settings, HttpRequest request) { logoutResponseDocument = Util.loadXML(logoutResponseString); } } + + /** + * Constructs the LogoutResponse object when a new response should be generated + * and sent. + * + * @param settings + * OneLogin_Saml2_Settings + * @param params + * a set of logout response input parameters that shape the + * request to create + */ + public LogoutResponse(Saml2Settings settings, LogoutResponseParams params) { + this.settings = settings; + this.request = null; + id = Util.generateUniqueID(settings.getUniqueIDPrefix()); + issueInstant = Calendar.getInstance(); + StrSubstitutor substitutor = generateSubstitutor(params, settings); + this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), params, settings); + } /** * @return the base64 encoded unsigned Logout Response (deflated or not) @@ -355,21 +365,33 @@ protected NodeList query (String query) throws XPathExpressionException { return Util.query(this.logoutResponseDocument, query, null); } - /** - * Generates a Logout Response XML string. - * - * @param inResponseTo - * InResponseTo attribute value to bet set at the Logout Response. + /** + * Generates a Logout Response XML string. + * + * @param inResponseTo + * InResponseTo attribute value to bet set at the Logout Response. * @param responseStatus - * SamlResponseStatus response status to be set on the LogoutResponse - */ + * SamlResponseStatus response status to be set on the + * LogoutResponse + * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} + * instead, in which case this method becomes completely useless; + * indeed, invoking this method in an outgoing logout response + * scenario will cause the response parameters specified at + * construction time (inResponseTo and + * responseStatus) to be overwritten, as well as its + * generated id and issue instant; on the other hand invoking this + * method in a received logout response scenario does not make sense + * at all (and in that case + * {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be + * used instead) + */ + @Deprecated public void build(String inResponseTo, SamlResponseStatus responseStatus) { id = Util.generateUniqueID(settings.getUniqueIDPrefix()); issueInstant = Calendar.getInstance(); - this.inResponseTo = inResponseTo; - - StrSubstitutor substitutor = generateSubstitutor(settings, responseStatus); - this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), settings); + final LogoutResponseParams params = new LogoutResponseParams(inResponseTo, responseStatus); + StrSubstitutor substitutor = generateSubstitutor(params, settings); + this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), params, settings); } /** @@ -379,24 +401,61 @@ public void build(String inResponseTo, SamlResponseStatus responseStatus) { * InResponseTo attribute value to bet set at the Logout Response. * @param statusCode * String StatusCode to be set on the LogoutResponse + * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} + * instead, in which case this method becomes completely useless; + * indeed, invoking this method in an outgoing logout response + * scenario will cause the response parameters specified at + * construction time (inResponseTo and + * responseStatus) to be overwritten, as well as its + * generated id and issue instant; on the other hand invoking this + * method in a received logout response scenario does not make sense + * at all (and in that case + * {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be + * used instead) */ + @Deprecated public void build(String inResponseTo, String statusCode) { build(inResponseTo, new SamlResponseStatus(statusCode)); } - /** - * Generates a Logout Response XML string. - * - * @param inResponseTo - * InResponseTo attribute value to bet set at the Logout Response. - */ + /** + * Generates a Logout Response XML string. + * + * @param inResponseTo + * InResponseTo attribute value to bet set at the Logout Response. + * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} + * instead, in which case this method becomes completely useless; + * indeed, invoking this method in an outgoing logout response + * scenario will cause the response parameters specified at + * construction time (inResponseTo and + * responseStatus) to be overwritten, as well as its + * generated id and issue instant; on the other hand invoking this + * method in a received logout response scenario does not make sense + * at all (and in that case + * {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be + * used instead) + */ + @Deprecated public void build(String inResponseTo) { build(inResponseTo, Constants.STATUS_SUCCESS); } - /** - * Generates a Logout Response XML string. - */ + /** + * Generates a Logout Response XML string. + * + * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} + * instead, in which case this method becomes completely useless; + * indeed, invoking this method in an outgoing logout response + * scenario will cause the response parameters specified at + * construction time (inResponseTo and + * responseStatus) to be overwritten, as well as its + * generated id and issue instant; on the other hand invoking this + * method in a received logout response scenario does not make sense + * at all (and in that case + * {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be + * used instead) + */ + @Deprecated public void build() { build(null); } @@ -412,26 +471,29 @@ public void build() { * @param logoutResponseXml * the XML produced for this LogoutResponse by the standard * implementation provided by {@link LogoutResponse} + * @param params + * the logout request input parameters * @param settings * the settings * @return the post-processed XML for this LogoutResponse, which will then be * returned by any call to {@link #getLogoutResponseXml()} */ - protected String postProcessXml(final String logoutResponseXml, final Saml2Settings settings) { + protected String postProcessXml(final String logoutResponseXml, final LogoutResponseParams params, + final Saml2Settings settings) { return logoutResponseXml; } /** * Substitutes LogoutResponse variables within a string by values. * + * @param params + * the logout response input parameters * @param settings - * Saml2Settings object. Setting data - * @param responseStatus - * SamlResponseStatus response status to be set on the LogoutResponse + * Saml2Settings object. Setting data * * @return the StrSubstitutor object of the LogoutResponse */ - private StrSubstitutor generateSubstitutor(Saml2Settings settings, SamlResponseStatus responseStatus) { + private StrSubstitutor generateSubstitutor(LogoutResponseParams params, Saml2Settings settings) { Map valueMap = new HashMap(); valueMap.put("id", Util.toXml(id)); @@ -447,12 +509,14 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings, SamlResponseS valueMap.put("destinationStr", destinationStr); String inResponseStr = ""; + final String inResponseTo = params.getInResponseTo(); if (inResponseTo != null) { inResponseStr = " InResponseTo=\"" + Util.toXml(inResponseTo) + "\""; } valueMap.put("inResponseStr", inResponseStr); StringBuilder statusStr = new StringBuilder("inResponseTo attribute and a + * response status with a top-level {@link Constants#STATUS_SUCCESS} status + * code. + */ + public LogoutResponseParams() { + this((String) null); + } + + /** + * Creates a logout response with a response status with a top-level + * {@link Constants#STATUS_SUCCESS} status code. + * + * @param inResponseTo + * the id of the logout request the response refers to; may be + * null if such id cannot be determined (possibly + * because the request is malformed) + */ + public LogoutResponseParams(String inResponseTo) { + this(inResponseTo, Constants.STATUS_SUCCESS); + } + + /** + * Creates a logout response. + * + * @param inResponseTo + * the id of the logout request the response refers to; may be + * null if such id cannot be determined (possibly + * because the request is malformed) + * @param statusCode + * the top-level status code code to set on the response + */ + public LogoutResponseParams(String inResponseTo, String statusCode) { + this(inResponseTo, new SamlResponseStatus(statusCode)); + } + + /** + * Creates a logout response. + * + * @param inResponseTo + * the id of the logout request the response refers to; may be + * null if such id cannot be determined (possibly + * because the request is malformed) + * @param responseStatus + * the response status; should not be null + * @throws NullPointerException + * if the specified response status is null + */ + public LogoutResponseParams(String inResponseTo, SamlResponseStatus responseStatus) throws NullPointerException { + this.inResponseTo = inResponseTo; + this.responseStatus = responseStatus; + if (responseStatus == null) + throw new NullPointerException("response status must not be null"); + } + + /** + * Create a set of logout request input parameters, by copying them from another + * set. + * + * @param source + * the source set of logout request input parameters + */ + protected LogoutResponseParams(LogoutResponseParams source) { + this.inResponseTo = source.getInResponseTo(); + this.responseStatus = source.getResponseStatus(); + } + + /** + * Returns the response status. + * + * @return the response status + */ + public SamlResponseStatus getResponseStatus() { + return responseStatus; + } + + /** + * Returns the id of the logout request this response refers to. + * + * @return the inResponseTo + */ + public String getInResponseTo() { + return inResponseTo; + } +} \ No newline at end of file diff --git a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java index c561aec3..dbc68c51 100644 --- a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java @@ -24,6 +24,7 @@ import com.onelogin.saml2.exception.XMLEntityException; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutResponse; +import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; @@ -114,7 +115,7 @@ public String getLogoutResponseXml() { * @see com.onelogin.saml2.logout.LogoutResponse */ @Test - public void testConstructor() throws IOException, XMLEntityException, URISyntaxException, Error { + public void testReceivedMessageConstructor() throws IOException, XMLEntityException, URISyntaxException, Error { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); String samlResponseEncoded = Util.getFileAsString("data/logout_responses/logout_response_deflated.xml.base64"); final String requestURL = "/"; @@ -125,7 +126,7 @@ public void testConstructor() throws IOException, XMLEntityException, URISyntaxE String logoutResponseStringBase64 = logoutResponse.getEncodedLogoutResponse(); assertEquals(logoutResponseStringBase64, expectedLogoutResponseStringBase64); } - + /** * Tests the build method of LogoutResponse * @@ -137,6 +138,66 @@ public void testConstructor() throws IOException, XMLEntityException, URISyntaxE * @see com.onelogin.saml2.logout.LogoutResponse#build */ @Test + public void testOutgoingMessageConstructor() throws IOException, XMLEntityException, URISyntaxException, Error { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + + LogoutResponse logoutResponse = new LogoutResponse(settings, new LogoutResponseParams()); + assertFalse(logoutResponse.isValid()); + assertEquals("SAML Logout Response is not loaded", logoutResponse.getError()); + String logoutResponseStringBase64 = logoutResponse.getEncodedLogoutResponse(); + assertFalse(logoutResponseStringBase64.isEmpty()); + + String logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, not(containsString(""))); + assertThat(logoutResponseStr, not(containsString(""))); + + SamlResponseStatus responseStatus = new SamlResponseStatus(Constants.STATUS_RESPONDER); + responseStatus.setSubStatusCode(Constants.STATUS_PARTIAL_LOGOUT); + LogoutResponse logoutResponse4 = new LogoutResponse(settings, new LogoutResponseParams("inResponseValue", responseStatus)); + logoutResponseStringBase64 = logoutResponse4.getEncodedLogoutResponse(); + logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, not(containsString(""))); + + responseStatus.setStatusMessage("status message"); + LogoutResponse logoutResponse5 = new LogoutResponse(settings, new LogoutResponseParams("inResponseValue", responseStatus)); + logoutResponseStringBase64 = logoutResponse5.getEncodedLogoutResponse(); + logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, containsString("status message")); + } + + /** + * Tests the legacy build method of LogoutResponse + * + * @throws IOException + * @throws XMLEntityException + * @throws URISyntaxException + * @throws Error + * + * @see com.onelogin.saml2.logout.LogoutResponse#build + */ + @Test public void testBuild() throws IOException, XMLEntityException, URISyntaxException, Error { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); @@ -147,50 +208,50 @@ public void testBuild() throws IOException, XMLEntityException, URISyntaxExcepti assertFalse(logoutResponse.isValid()); assertEquals("SAML Logout Response is not loaded", logoutResponse.getError()); logoutResponse.build(); - String logoutRequestStringBase64 = logoutResponse.getEncodedLogoutResponse(); - assertFalse(logoutRequestStringBase64.isEmpty()); + String logoutResponseStringBase64 = logoutResponse.getEncodedLogoutResponse(); + assertFalse(logoutResponseStringBase64.isEmpty()); - String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64); - assertThat(logoutRequestStr, containsString("")); - assertThat(logoutRequestStr, not(containsString(""))); - assertThat(logoutRequestStr, not(containsString(""))); + logoutResponseStringBase64 = logoutResponse3.getEncodedLogoutResponse(); + logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, not(containsString(""))); + assertThat(logoutResponseStr, not(containsString(""))); LogoutResponse logoutResponse4 = new LogoutResponse(settings, httpRequest); SamlResponseStatus responseStatus = new SamlResponseStatus(Constants.STATUS_RESPONDER); responseStatus.setSubStatusCode(Constants.STATUS_PARTIAL_LOGOUT); logoutResponse4.build("inResponseValue", responseStatus); - logoutRequestStringBase64 = logoutResponse4.getEncodedLogoutResponse(); - logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64); - assertThat(logoutRequestStr, containsString("")); - assertThat(logoutRequestStr, not(containsString(""))); + logoutResponseStringBase64 = logoutResponse4.getEncodedLogoutResponse(); + logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, not(containsString(""))); responseStatus.setStatusMessage("status message"); logoutResponse4.build("inResponseValue", responseStatus); - logoutRequestStringBase64 = logoutResponse4.getEncodedLogoutResponse(); - logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64); - assertThat(logoutRequestStr, containsString("")); - assertThat(logoutRequestStr, containsString("status message")); + logoutResponseStringBase64 = logoutResponse4.getEncodedLogoutResponse(); + logoutResponseStr = Util.base64decodedInflated(logoutResponseStringBase64); + assertThat(logoutResponseStr, containsString("")); + assertThat(logoutResponseStr, containsString("status message")); } /** @@ -203,7 +264,32 @@ public void testBuild() throws IOException, XMLEntityException, URISyntaxExcepti @Test public void testGetLogoutResponseXml() throws Exception { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); - LogoutResponse logoutResponse = new LogoutResponse(settings, null); + LogoutResponse logoutResponse = new LogoutResponse(settings, new LogoutResponseParams()); + String logoutResponseXML = logoutResponse.getLogoutResponseXml(); + assertThat(logoutResponseXML, containsString(" + * Case: logout destination contains special chars and the legacy build method is used to build the outgoing response. + * + * @throws Exception + * + * @see com.onelogin.saml2.logout.LogoutResponse#getLogoutResponseXml + */ + @Test + public void testGetLogoutResponseXmlSpecialCharsLegacy() throws Exception { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min_specialchars.properties").build(); + LogoutResponse logoutResponse = new LogoutResponse(settings, (HttpRequest) null); logoutResponse.build(); String logoutResponseXML = logoutResponse.getLogoutResponseXml(); assertThat(logoutResponseXML, containsString(" - * Case: LogoutResponse message built by the caller. + * Case: outgoing LogoutResponse message created by the caller. + * + * @throws IOException + * @throws Error + * @throws ValidationError + * + * @see com.onelogin.saml2.logout.LogoutResponse#getIssueInstant() + */ + @Test + public void testGetIssueInstantOutgoingMessage() throws IOException, Error, ValidationError { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + long start = System.currentTimeMillis(); + LogoutResponse logoutResponse = new LogoutResponse(settings, new LogoutResponseParams()); + long end = System.currentTimeMillis(); + Calendar issueInstant = logoutResponse.getIssueInstant(); + assertNotNull(issueInstant); + long millis = issueInstant.getTimeInMillis(); + assertTrue(millis >= start && millis <= end); + } + + /** + * Tests the getIssueInstant method of LogoutResponse + *

+ * Case: outgoing LogoutResponse message created by the caller and legacy build() method invoked * * @throws IOException * @throws Error @@ -330,10 +465,10 @@ public void testGetIssueInstant() throws IOException, Error, ValidationError { * @see com.onelogin.saml2.logout.LogoutResponse#getIssueInstant() */ @Test - public void testGetIssueInstantBuiltMessage() throws IOException, Error, ValidationError { + public void testGetIssueInstantOutgoingMessageLegacy() throws IOException, Error, ValidationError { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + LogoutResponse logoutResponse = new LogoutResponse(settings, new LogoutResponseParams()); long start = System.currentTimeMillis(); - LogoutResponse logoutResponse = new LogoutResponse(settings, null); logoutResponse.build(); long end = System.currentTimeMillis(); Calendar issueInstant = logoutResponse.getIssueInstant(); @@ -779,11 +914,41 @@ private static HttpRequest newHttpRequest(String requestURL, String samlResponse @Test public void testPostProcessXml() throws Exception { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); - LogoutResponse logoutResponse = new LogoutResponse(settings, null) { + final LogoutResponseParams params = new LogoutResponseParams(); + LogoutResponse logoutResponse = new LogoutResponse(settings, params) { + @Override + protected String postProcessXml(String logoutResponseXml, LogoutResponseParams par, Saml2Settings sett) { + assertEquals(logoutResponseXml, super.postProcessXml(logoutResponseXml, par, sett)); + assertSame(settings, sett); + assertSame(params, par); + return "changed"; + } + }; + assertEquals("changed", logoutResponse.getLogoutResponseXml()); + } + + /** + * Tests the postProcessXml method of LogoutResponse + * + * Case: the legacy build method is used to build the outgoing response. + * + * @throws Exception + * + * @see com.onelogin.saml2.logout.LogoutResponse#postProcessXml + */ + @Test + public void testPostProcessXmlLegacy() throws Exception { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); + LogoutResponse logoutResponse = new LogoutResponse(settings, (HttpRequest) null) { @Override - protected String postProcessXml(String logoutResponseXml, Saml2Settings sett) { - assertEquals(logoutResponseXml, super.postProcessXml(logoutResponseXml, sett)); + protected String postProcessXml(String logoutResponseXml, LogoutResponseParams params, Saml2Settings sett) { + assertEquals(logoutResponseXml, super.postProcessXml(logoutResponseXml, params, sett)); assertSame(settings, sett); + assertNull(params.getInResponseTo()); + SamlResponseStatus responseStatus = params.getResponseStatus(); + assertEquals(Constants.STATUS_SUCCESS, responseStatus.getStatusCode()); + assertNull(responseStatus.getSubStatusCode()); + assertNull(responseStatus.getStatusMessage()); return "changed"; } }; diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index d3c579bb..e0bb66c3 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -33,6 +33,7 @@ import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; import com.onelogin.saml2.logout.LogoutResponse; +import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.model.KeyStoreSettings; import com.onelogin.saml2.servlet.ServletUtils; @@ -174,14 +175,14 @@ public class Auth { private static final SamlReceivedMessageFactory DEFAULT_SAML_RESPONSE_FACTORY = SamlResponse::new; private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; - private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY = (settings, nothing) -> new LogoutResponse(settings, null); + private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY = LogoutResponse::new; private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY = LogoutResponse::new; private SamlOutgoingMessageFactory authnRequestFactory = DEFAULT_AUTHN_REQUEST_FACTORY; private SamlReceivedMessageFactory samlResponseFactory = DEFAULT_SAML_RESPONSE_FACTORY; private SamlOutgoingMessageFactory outgoingLogoutRequestFactory = DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY; private SamlReceivedMessageFactory receivedLogoutRequestFactory = DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY; - private SamlOutgoingMessageFactory outgoingLogoutResponseFactory = DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; + private SamlOutgoingMessageFactory outgoingLogoutResponseFactory = DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; private SamlReceivedMessageFactory receivedLogoutResponseFactory = DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY; /** @@ -1333,8 +1334,8 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } String inResponseTo = logoutRequest.id; - LogoutResponse logoutResponseBuilder = outgoingLogoutResponseFactory.create(settings, null); - logoutResponseBuilder.build(inResponseTo, Constants.STATUS_SUCCESS); + LogoutResponse logoutResponseBuilder = outgoingLogoutResponseFactory.create(settings, + new LogoutResponseParams(inResponseTo, Constants.STATUS_SUCCESS)); lastResponse = logoutResponseBuilder.getLogoutResponseXml(); String samlLogoutResponse = logoutResponseBuilder.getEncodedLogoutResponse(); @@ -1744,7 +1745,7 @@ public void setReceivedLogoutRequestFactory( * which creates plain {@link LogoutResponse} instances */ public void setOutgoingLogoutResponseFactory(final - SamlOutgoingMessageFactory outgoingLogoutResponseFactory) { + SamlOutgoingMessageFactory outgoingLogoutResponseFactory) { this.outgoingLogoutResponseFactory = outgoingLogoutResponseFactory != null? outgoingLogoutResponseFactory: DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; } diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index 6bf588f1..6846bfa7 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -59,7 +59,9 @@ import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; import com.onelogin.saml2.logout.LogoutResponse; +import com.onelogin.saml2.logout.LogoutResponseParams; import com.onelogin.saml2.model.KeyStoreSettings; +import com.onelogin.saml2.model.SamlResponseStatus; import com.onelogin.saml2.servlet.ServletUtils; import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; @@ -2380,17 +2382,21 @@ public void testOutgoingLogoutResponseFactory() throws Exception { class LogoutResponseEx extends LogoutResponse { - public LogoutResponseEx(Saml2Settings sett, HttpRequest req) { - super(sett, req); + public LogoutResponseEx(Saml2Settings sett, LogoutResponseParams par) { + super(sett, par); assertSame(settings, sett); - assertNull(req); + assertEquals("ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e", par.getInResponseTo()); + SamlResponseStatus responseStatus = par.getResponseStatus(); + assertEquals(Constants.STATUS_SUCCESS, responseStatus.getStatusCode()); + assertNull(responseStatus.getSubStatusCode()); + assertNull(responseStatus.getStatusMessage()); throw new FactoryInvokedException(); } } Auth auth = new Auth(settings, request, response); - auth.setOutgoingLogoutResponseFactory((sett, nothing) -> new LogoutResponseEx(settings, null)); + auth.setOutgoingLogoutResponseFactory((sett, param) -> new LogoutResponseEx(settings, param)); auth.processSLO(false, null); } From 41d95ac8c310a1a05c1f666446f55f20ff763b82 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Fri, 13 Aug 2021 21:58:29 +0200 Subject: [PATCH 06/34] Apply minor adjustments to AuthnRequest/LogoutRequest APIs and tests These details were overlooked in the first place: getters of the input params should better be public and fields can be declared as final. The useless NameId setter in LogoutRequestParams was temporarily introduced during development but should have been reverted from the beginning, so it's gone now. Some tests were improved to provide more accurate assertions. --- .../saml2/authn/AuthnRequestParams.java | 2 +- .../onelogin/saml2/logout/LogoutRequest.java | 2 +- .../saml2/logout/LogoutRequestParams.java | 31 +++++++------------ .../saml2/test/logout/LogoutRequestTest.java | 8 +++-- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java index 0a7efa48..69954254 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java +++ b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java @@ -160,7 +160,7 @@ public boolean isAllowCreate() { /** * @return the subject that should be authenticated */ - protected String getNameIdValueReq() { + public String getNameIdValueReq() { return nameIdValueReq; } } \ No newline at end of file diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java index 234b89ac..cacd7bf8 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java @@ -242,7 +242,7 @@ public LogoutRequest(Saml2Settings settings, HttpRequest request) { * @param settings * OneLogin_Saml2_Settings * @param params - * a set of authentication request input parameters that shape the + * a set of logout request input parameters that shape the * request to create */ public LogoutRequest(Saml2Settings settings, LogoutRequestParams params) { diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequestParams.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequestParams.java index ce95626f..79cd2ee8 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequestParams.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequestParams.java @@ -9,30 +9,31 @@ public class LogoutRequestParams { * SessionIndex. When the user is logged, this stored it from the AuthnStatement * of the SAML Response */ - private String sessionIndex; + private final String sessionIndex; /** * NameID. */ - private String nameId; + private final String nameId; /** * NameID Format. */ - private String nameIdFormat; + private final String nameIdFormat; /** * nameId NameQualifier */ - private String nameIdNameQualifier; + private final String nameIdNameQualifier; /** * nameId SP NameQualifier */ - private String nameIdSPNameQualifier; + private final String nameIdSPNameQualifier; /** Create an empty set of logout request input parameters. */ public LogoutRequestParams() { + this(null, null); } /** @@ -118,45 +119,35 @@ protected LogoutRequestParams(LogoutRequestParams source) { /** * @return the name ID */ - protected String getNameId() { + public String getNameId() { return nameId; } - /** - * Sets the name ID - * - * @param nameId - * the name ID to set - */ - protected void setNameId(String nameId) { - this.nameId = nameId; - } - /** * @return the name ID format */ - protected String getNameIdFormat() { + public String getNameIdFormat() { return nameIdFormat; } /** * @return the name ID name qualifier */ - protected String getNameIdNameQualifier() { + public String getNameIdNameQualifier() { return nameIdNameQualifier; } /** * @return the name ID SP name qualifier */ - protected String getNameIdSPNameQualifier() { + public String getNameIdSPNameQualifier() { return nameIdSPNameQualifier; } /** * @return the session index */ - protected String getSessionIndex() { + public String getSessionIndex() { return sessionIndex; } } \ No newline at end of file diff --git a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java index b3ae9c59..c81f172e 100644 --- a/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java @@ -1095,11 +1095,13 @@ private static HttpRequest newHttpRequest(String requestURL, String samlRequestE @Test public void testPostProcessXml() throws Exception { Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build(); - LogoutRequest logoutRequest = new LogoutRequest(settings) { + final LogoutRequestParams params = new LogoutRequestParams(); + LogoutRequest logoutRequest = new LogoutRequest(settings, params) { @Override - protected String postProcessXml(String logoutRequestXml, LogoutRequestParams params, Saml2Settings sett) { - assertEquals(logoutRequestXml, super.postProcessXml(logoutRequestXml, params, sett)); + protected String postProcessXml(String logoutRequestXml, LogoutRequestParams par, Saml2Settings sett) { + assertEquals(logoutRequestXml, super.postProcessXml(logoutRequestXml, par, sett)); assertSame(settings, sett); + assertSame(params, par); return "changed"; } }; From b54bff013678e03b6b4a7a4f0adf28e63c788be6 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Fri, 13 Aug 2021 22:41:57 +0200 Subject: [PATCH 07/34] Document the new API and extensibility features in README --- README.md | 76 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index d1bf4d3b..321cfb64 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ The toolkit is hosted on github. You can download it from: The toolkit is hosted at [Sonatype OSSRH (OSS Repository Hosting)](http://central.sonatype.org/pages/ossrh-guide.html) that is synced to the Central Repository. Install it as a maven dependency: -``` +```xml com.onelogin java-saml @@ -441,7 +441,7 @@ If you want to use anything different than javax.servlet.http, you will need to #### Initiate SSO In order to send an AuthNRequest to the IdP: -``` +```java Auth auth = new Auth(request, response); auth.login(); ``` @@ -450,16 +450,18 @@ The AuthNRequest will be sent signed or unsigned based on the security settings The IdP will then return the SAML Response to the user's client. The client is then forwarded to the Attribute Consumer Service of the SP with this information. We can set a 'RelayState' parameter containing a return url to the login function: -``` +```java String returnUrl = 'https://example.com'; auth.login(relayState=returnUrl) ``` -The login method can receive 6 more optional parameters: -- *forceAuthn* When true the AuthNRequest will have the 'ForceAuthn' attribute set to 'true' -- *isPassive* When true the AuthNRequest will have the 'Ispassive' attribute set to 'true' -- *setNameIdPolicy* When true the AuthNRequest will set a nameIdPolicy element. +The login method can receive 3 more optional parameters: +- *authnRequestParams* which in turn allows to shape the AuthNRequest with the following properties: + - *forceAuthn* When true the AuthNRequest will have the `ForceAuthn` attribute set to `true` + - *isPassive* When true the AuthNRequest will have the `IsPassive` attribute set to `true` + - *setNameIdPolicy* When true the AuthNRequest will set a `NameIdPolicy` element + - *allowCreate* When true, and *setNameIdPolicy* is also true, the AuthNRequest will have the `AllowCreate` attribute set to `true` on the `NameIdPolicy` element + - *nameIdValueReq* Indicates to the IdP the subject that should be authenticated - *stay* Set to true to stay (returns the url string), otherwise set to false to execute a redirection to that url (IdP SSO URL) -- *nameIdValueReq* Indicates to the IdP the subject that should be authenticated - *parameters* Use it to send extra parameters in addition to the AuthNRequest 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 @@ -474,7 +476,7 @@ Related to the SP there are 3 important endpoints: The metadata view, the ACS vi ##### SP Metadata This code will provide the XML metadata file of our SP, based on the info that we provided in the settings files. -``` +```java Auth auth = new Auth(); Saml2Settings settings = auth.getSettings(); String metadata = settings.getSPMetadata(); @@ -494,7 +496,7 @@ Before the XML metadata is exposed, a check takes place to ensure that the info ##### Attribute Consumer Service(ACS) This code handles the SAML response that the IdP forwards to the SP through the user's client. -``` +```java Auth auth = new Auth(request, response); auth.processResponse(); if (!auth.isAuthenticated()) { @@ -572,7 +574,7 @@ Before trying to get an attribute, check that the user is authenticated. If the ##### Single Logout Service (SLS) This code handles the Logout Request and the Logout Responses. -``` +```java Auth auth = new Auth(request, response); auth.processSLO(); List errors = auth.getErrors(); @@ -592,7 +594,7 @@ If we don't want that processSLO to destroy the session, pass the keepLocalSessi #### Initiate SLO In order to send a Logout Request to the IdP: -``` +```java Auth auth = new Auth(request, response); String nameId = null; @@ -615,36 +617,56 @@ String sessionIndex = null; if (session.getAttribute("sessionIndex") != null) { sessionIndex = session.getAttribute("sessionIndex").toString(); } -auth.logout(null, nameId, sessionIndex, nameIdFormat); -``` +auth.logout(null, new LogoutRequestParams(sessionIndex, nameId, nameIdFormat)); +```java The Logout Request will be sent signed or unsigned based on the security settings 'onelogin.saml2.security.logoutrequest_signed' The IdP will return the Logout Response through the user's client to the Single Logout Service of the SP. We can set a 'RelayState' parameter containing a return url to the login function: -``` +```java String returnUrl = 'https://example.com'; auth.logout(relayState=returnUrl) ``` -Also there are 7 optional parameters that can be set: -- nameId. That will be used to build the LogoutRequest. If not name_id parameter is set and the auth object processed a SAML Response with a NameId, then this NameId will be used. -- sessionIndex. Identifies the session of the user. -If a match on the LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must to be extracted and stored for future validation, we can get that ID by -- stay. True if we want to stay (returns the url string) False to execute a redirection to that url (IdP SLS URL) -- nameidFormat. The NameID Format that will be set in the LogoutRequest -- nameIdNameQualifier. The NameID NameQualifier that will be set in the LogoutRequest -- nameIdSPNameQualifier. The NameID SP Name Qualifier that will be set in the LogoutRequest -- parameters. Use it to send extra parameters in addition to the LogoutRequest - -By default the logout 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 +Also there are other 3 optional parameters that can be set: +- *logoutRequestParams* which in turn allows to shape the LogoutRequest with the following properties: + - *sessionIndex* Identifies the session of the user + - *nameId* That will be used to build the LogoutRequest. If no *nameId* parameter is set and the auth object processed a SAML Response with a `NameID`, then this `NameID` will be used + - *nameidFormat* The `NameID` `Format` that will be set on the LogoutRequest + - *nameIdNameQualifier* The `NameID` `NameQualifier` that will be set on the LogoutRequest + - *nameIdSPNameQualifier* The `NameID` `SPNameQualifier` that will be set on the LogoutRequest +- *stay* True if we want to stay (returns the url string) False to execute a redirection to that url (IdP SLS URL) +- *parameters* Use it to send extra parameters in addition to the LogoutRequest + +By default the logout 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 LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must be extracted and stored for future validation so we can't execute the redirection on the logout, instead set stay to true, then get that ID by -``` +```java auth.getLastRequestId() ``` and later executing the redirection manually. +### Extending the provided implementation + +All the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRequest`, `LogoutResponse`) can be extended to add or change the processing behavior. + +In particular, the classes used to produce outgoing messages (`AuthnRequest`, `LogoutRequest`, and `LogoutResponse`) also provide a `postProcessXml` method that can be overridden to customise the generation of the corresponding SAML message XML, along with the ability to pass in proper extensions of the input parameter classes (`AuthnRequestParams`, `LogoutRequestParams`, and `LogoutResponseParams` respectively). + +Once you have prepared your extension classes, in order to make the `Auth` class use them, appropriate factories can then be +specified: + +```java +// let AuthnRequestEx, SamlResponseEx, LogoutRequestEx, LogoutResponseEx be your extension classes +Auth auth = new Auth(request, response); +auth.setAuthnRequestFactory(AuthnRequestEx::new); // to make it build custom AuthnRequests +auth.setSamlResponseFactory(SamlResponseEx::new); // to make it build custom SamlResponses +auth.setOutgoingLogoutRequestFactory(LogoutRequestEx::new); // to make it build custom outgoing LogoutRequests +auth.setReceivedLogoutRequestFactory(LogoutRequestEx::new); // to make it build custom incoming LogoutRequests +auth.setOutgoingLogoutResponseFactory(LogoutResponseEx::new); // to make it build custom outgoing LogoutResponses +auth.setReceivedLogoutResponseFactory(LogoutResponseEx::new); // to make it build custom incoming LogoutResponses +// then proceed with login/processResponse/logout/processSLO... +``` ### Working behind load balancer From 2917a41f6242554e412d446a092bdc0a59ba1f42 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Wed, 18 Aug 2021 18:02:37 +0200 Subject: [PATCH 08/34] Change factory approach to use just a single multi-message factory In this way the API of Auth gets simplified. --- README.md | 26 ++-- .../main/java/com/onelogin/saml2/Auth.java | 137 +++--------------- .../saml2/factory/SamlMessageFactory.java | 119 +++++++++++++++ .../factory/SamlOutgoingMessageFactory.java | 27 ---- .../factory/SamlReceivedMessageFactory.java | 28 ---- .../com/onelogin/saml2/test/AuthTest.java | 61 ++++++-- 6 files changed, 201 insertions(+), 197 deletions(-) create mode 100644 toolkit/src/main/java/com/onelogin/saml2/factory/SamlMessageFactory.java delete mode 100644 toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java delete mode 100644 toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java diff --git a/README.md b/README.md index 321cfb64..ac1fd237 100644 --- a/README.md +++ b/README.md @@ -653,19 +653,25 @@ All the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRe In particular, the classes used to produce outgoing messages (`AuthnRequest`, `LogoutRequest`, and `LogoutResponse`) also provide a `postProcessXml` method that can be overridden to customise the generation of the corresponding SAML message XML, along with the ability to pass in proper extensions of the input parameter classes (`AuthnRequestParams`, `LogoutRequestParams`, and `LogoutResponseParams` respectively). -Once you have prepared your extension classes, in order to make the `Auth` class use them, appropriate factories can then be -specified: +Once you have prepared your extension classes, in order to make the `Auth` class use them, an appropriate `SamlMessageFactory` implementation can be specified. As an example, assuming you've created two extension classes `AuthnRequestEx` and `SamlResponseEx` to customise the creation of AuthnRequest SAML messages and the validation of SAML responses respectively, as well as an extended `AuthnRequestParamsEx` input parameter class to drive the AuthnRequest generation post-processing, you can do the following: ```java -// let AuthnRequestEx, SamlResponseEx, LogoutRequestEx, LogoutResponseEx be your extension classes Auth auth = new Auth(request, response); -auth.setAuthnRequestFactory(AuthnRequestEx::new); // to make it build custom AuthnRequests -auth.setSamlResponseFactory(SamlResponseEx::new); // to make it build custom SamlResponses -auth.setOutgoingLogoutRequestFactory(LogoutRequestEx::new); // to make it build custom outgoing LogoutRequests -auth.setReceivedLogoutRequestFactory(LogoutRequestEx::new); // to make it build custom incoming LogoutRequests -auth.setOutgoingLogoutResponseFactory(LogoutResponseEx::new); // to make it build custom outgoing LogoutResponses -auth.setReceivedLogoutResponseFactory(LogoutResponseEx::new); // to make it build custom incoming LogoutResponses -// then proceed with login/processResponse/logout/processSLO... +auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public AuthnRequest createAuthnRequest(Saml2Settings settings, AuthnRequestParams params) { + return new AuthnRequestEx(settings, (AuthnRequestParamsEx) params); + } + + @Override + public SamlResponse createSamlResponse(Saml2Settings settings, HttpRequest request) throws Exception { + return new SamlResponseEx(settings, request); + } +}); +// then proceed with login... +auth.login(relayState, new AuthnRequestParamsEx()); // the custom generation of AuthnReqeustEx will be executed +// ... or process the response as usual +auth.processResponse(); // the custom validation of SamlResponseEx will be executed ``` ### Working behind load balancer diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index e0bb66c3..511914b8 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -26,8 +26,7 @@ import com.onelogin.saml2.authn.AuthnRequestParams; import com.onelogin.saml2.authn.SamlResponse; import com.onelogin.saml2.exception.SettingsException; -import com.onelogin.saml2.factory.SamlOutgoingMessageFactory; -import com.onelogin.saml2.factory.SamlReceivedMessageFactory; +import com.onelogin.saml2.factory.SamlMessageFactory; import com.onelogin.saml2.exception.Error; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutRequest; @@ -171,19 +170,9 @@ public class Auth { */ private String lastResponse; - private static final SamlOutgoingMessageFactory DEFAULT_AUTHN_REQUEST_FACTORY = AuthnRequest::new; - private static final SamlReceivedMessageFactory DEFAULT_SAML_RESPONSE_FACTORY = SamlResponse::new; - private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; - private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY = LogoutRequest::new; - private static final SamlOutgoingMessageFactory DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY = LogoutResponse::new; - private static final SamlReceivedMessageFactory DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY = LogoutResponse::new; + private static final SamlMessageFactory DEFAULT_SAML_MESSAGE_FACTORY = new SamlMessageFactory() {}; - private SamlOutgoingMessageFactory authnRequestFactory = DEFAULT_AUTHN_REQUEST_FACTORY; - private SamlReceivedMessageFactory samlResponseFactory = DEFAULT_SAML_RESPONSE_FACTORY; - private SamlOutgoingMessageFactory outgoingLogoutRequestFactory = DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY; - private SamlReceivedMessageFactory receivedLogoutRequestFactory = DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY; - private SamlOutgoingMessageFactory outgoingLogoutResponseFactory = DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; - private SamlReceivedMessageFactory receivedLogoutResponseFactory = DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY; + private SamlMessageFactory samlMessageFactory = DEFAULT_SAML_MESSAGE_FACTORY; /** * Initializes the SP SAML instance. @@ -626,7 +615,7 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo * @throws SettingsException */ public String login(String relayState, AuthnRequestParams authnRequestParams, Boolean stay, Map parameters) throws IOException, SettingsException { - AuthnRequest authnRequest = authnRequestFactory.create(settings, authnRequestParams); + AuthnRequest authnRequest = samlMessageFactory.createAuthnRequest(settings, authnRequestParams); if (parameters == null) { parameters = new HashMap(); @@ -802,7 +791,7 @@ public String logout(String relayState, LogoutRequestParams logoutRequestParams, parameters = new HashMap(); } - LogoutRequest logoutRequest = outgoingLogoutRequestFactory.create(settings, logoutRequestParams); + LogoutRequest logoutRequest = samlMessageFactory.createOutgoingLogoutRequest(settings, logoutRequestParams); String samlLogoutRequest = logoutRequest.getEncodedLogoutRequest(); parameters.put("SAMLRequest", samlLogoutRequest); @@ -1213,7 +1202,7 @@ public void processResponse(String requestId) throws Exception { final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - SamlResponse samlResponse = samlResponseFactory.create(settings, httpRequest); + SamlResponse samlResponse = samlMessageFactory.createSamlResponse(settings, httpRequest); lastResponse = samlResponse.getSAMLResponseXml(); if (samlResponse.isValid(requestId)) { @@ -1286,7 +1275,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta final String samlResponseParameter = httpRequest.getParameter("SAMLResponse"); if (samlResponseParameter != null) { - LogoutResponse logoutResponse = receivedLogoutResponseFactory.create(settings, httpRequest); + LogoutResponse logoutResponse = samlMessageFactory.createIncomingLogoutResponse(settings, httpRequest); lastResponse = logoutResponse.getLogoutResponseXml(); if (!logoutResponse.isValid(requestId)) { errors.add("invalid_logout_response"); @@ -1316,7 +1305,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } return null; } else if (samlRequestParameter != null) { - LogoutRequest logoutRequest = receivedLogoutRequestFactory.create(settings, httpRequest); + LogoutRequest logoutRequest = samlMessageFactory.createIncomingLogoutRequest(settings, httpRequest); lastRequest = logoutRequest.getLogoutRequestXml(); if (!logoutRequest.isValid()) { errors.add("invalid_logout_request"); @@ -1334,7 +1323,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } String inResponseTo = logoutRequest.id; - LogoutResponse logoutResponseBuilder = outgoingLogoutResponseFactory.create(settings, + LogoutResponse logoutResponseBuilder = samlMessageFactory.createOutgoingLogoutResponse(settings, new LogoutResponseParams(inResponseTo, Constants.STATUS_SUCCESS)); lastResponse = logoutResponseBuilder.getLogoutResponseXml(); @@ -1663,107 +1652,19 @@ public String getLastResponseXML() { } /** - * Sets the factory this {@link Auth} will use to create {@link AuthnRequest} - * objects. + * Sets the factory this {@link Auth} will use to create SAML messages. *

- * This allows consumers to provide their own extension of {@link AuthnRequest} - * possibly implementing custom features and/or XML post-processing. + * This allows consumers to provide their own extension classes for SAML message + * XML generation and/or processing. * - * @param authnRequestFactory - * the factory to use to create {@link AuthnRequest} objects; if + * @param samlMessageFactory + * the factory to use to create SAML message objects; if * null, a default provider will be used which creates - * plain {@link AuthnRequest} instances + * the standard message implementation provided by this library + * (i.e.: {@link AuthnRequest}, {@link SamlResponse}, + * {@link LogoutRequest} and {@link LogoutResponse}) */ - public void setAuthnRequestFactory( - final SamlOutgoingMessageFactory authnRequestFactory) { - this.authnRequestFactory = authnRequestFactory != null ? authnRequestFactory - : DEFAULT_AUTHN_REQUEST_FACTORY; - } - - /** - * Sets the factory this {@link Auth} will use to create {@link SamlResponse} - * objects. - *

- * This allows consumers to provide their own extension of {@link SamlResponse} - * possibly implementing custom features and/or XML validation. - * - * @param samlResponseFactory - * the factory to use to create {@link SamlResponse} objects; if - * null, a default factory will be used which creates - * plain {@link SamlResponse} instances - */ - public void setSamlResponseFactory(final SamlReceivedMessageFactory samlResponseFactory) { - this.samlResponseFactory = samlResponseFactory != null? samlResponseFactory: DEFAULT_SAML_RESPONSE_FACTORY; - } - - /** - * Sets the factory this {@link Auth} will use to create outgoing - * {@link LogoutRequest} objects. - *

- * This allows consumers to provide their own extension of {@link LogoutRequest} - * possibly implementing custom features and/or XML post-processing. - * - * @param outgoingLogoutRequestFactory - * the factory to use to create outgoing {@link LogoutRequest} - * objects; if null, a default provider will be used - * which creates plain {@link LogoutRequest} instances - */ - public void setOutgoingLogoutRequestFactory(final - SamlOutgoingMessageFactory outgoingLogoutRequestFactory) { - this.outgoingLogoutRequestFactory = outgoingLogoutRequestFactory != null? outgoingLogoutRequestFactory: DEFAULT_OUTGOING_LOGOUT_REQUEST_FACTORY; - } - - /** - * Sets the factory this {@link Auth} will use to create received - * {@link LogoutRequest} objects. - *

- * This allows consumers to provide their own extension of {@link LogoutRequest} - * possibly implementing custom features and/or XML validation. - * - * @param receivedLogoutRequestFactory - * the factory to use to create received {@link LogoutRequest} - * objects; if null, a default provider will be used - * which creates plain {@link LogoutRequest} instances - */ - public void setReceivedLogoutRequestFactory( - final SamlReceivedMessageFactory receivedLogoutRequestFactory) { - this.receivedLogoutRequestFactory = receivedLogoutRequestFactory != null ? receivedLogoutRequestFactory - : DEFAULT_RECEIVED_LOGOUT_REQUEST_FACTORY; - } - - /** - * Sets the factory this {@link Auth} will use to create outgoing - * {@link LogoutResponse} objects. - *

- * This allows consumers to provide their own extension of - * {@link LogoutResponse} possibly implementing custom features and/or XML - * post-processing. - * - * @param outgoingLogoutResponseFactory - * the factory to use to create outgoing {@link LogoutResponse} - * objects; if null, a default provider will be used - * which creates plain {@link LogoutResponse} instances - */ - public void setOutgoingLogoutResponseFactory(final - SamlOutgoingMessageFactory outgoingLogoutResponseFactory) { - this.outgoingLogoutResponseFactory = outgoingLogoutResponseFactory != null? outgoingLogoutResponseFactory: DEFAULT_OUTGOING_LOGOUT_RESPONSE_FACTORY; - } - - /** - * Sets the factory this {@link Auth} will use to create received - * {@link LogoutResponse} objects. - *

- * This allows consumers to provide their own extension of - * {@link LogoutResponse} possibly implementing custom features and/or XML - * validation. - * - * @param receivedLogoutResponseFactory - * the factory to use to create received {@link LogoutResponse} - * objects; if null, a default provider will be used - * which creates plain {@link LogoutResponse} instances - */ - public void setReceivedLogoutResponseFactory(final - SamlReceivedMessageFactory receivedLogoutResponseFactory) { - this.receivedLogoutResponseFactory = receivedLogoutResponseFactory != null? receivedLogoutResponseFactory: DEFAULT_RECEIVED_LOGOUT_RESPONSE_FACTORY; + public void setSamlMessageFactory(final SamlMessageFactory samlMessageFactory) { + this.samlMessageFactory = samlMessageFactory != null ? samlMessageFactory : DEFAULT_SAML_MESSAGE_FACTORY; } } diff --git a/toolkit/src/main/java/com/onelogin/saml2/factory/SamlMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlMessageFactory.java new file mode 100644 index 00000000..08c71e91 --- /dev/null +++ b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlMessageFactory.java @@ -0,0 +1,119 @@ +package com.onelogin.saml2.factory; + +import com.onelogin.saml2.Auth; +import com.onelogin.saml2.authn.AuthnRequest; +import com.onelogin.saml2.authn.AuthnRequestParams; +import com.onelogin.saml2.authn.SamlResponse; +import com.onelogin.saml2.http.HttpRequest; +import com.onelogin.saml2.logout.LogoutRequest; +import com.onelogin.saml2.logout.LogoutRequestParams; +import com.onelogin.saml2.logout.LogoutResponse; +import com.onelogin.saml2.logout.LogoutResponseParams; +import com.onelogin.saml2.settings.Saml2Settings; + +/** + * Factory which can create all kind of SAML message objects. + *

+ * One such factory is used by the {@link Auth} class to orchestrate login and + * logout operations. + *

+ * Default implementations for all creation methods are provided: they create + * instances of the standard classes provided by the library. Any extension + * class may simply override the desired creation methods in order to return + * instances of custom extensions of those standard classes. + */ +public interface SamlMessageFactory { + + /** + * Creates an {@link AuthnRequest} instance. + * + * @param settings + * the settings + * @param params + * the authentication request input parameters + * @return the created {@link AuthnRequest} instance + */ + default AuthnRequest createAuthnRequest(final Saml2Settings settings, final AuthnRequestParams params) { + return new AuthnRequest(settings, params); + } + + /** + * Creates a {@link SamlResponse} instance. + * + * @param settings + * the settings + * @param request + * the HTTP request from which the response is to be extracted and + * parsed + * @return the created {@link SamlResponse} instance + * @throws Exception + * in case some error occurred while trying to create the + * {@link SamlResponse} instance + */ + default SamlResponse createSamlResponse(final Saml2Settings settings, final HttpRequest request) + throws Exception { + return new SamlResponse(settings, request); + } + + /** + * Creates a {@link LogoutRequest} instance for an outgoing request. + * + * @param settings + * the settings + * @param params + * the logout request input parameters + * @return the created {@link LogoutRequest} instance + */ + default LogoutRequest createOutgoingLogoutRequest(final Saml2Settings settings, final LogoutRequestParams params) { + return new LogoutRequest(settings, params); + } + + /** + * Creates a {@link LogoutRequest} instance for an incoming request. + * + * @param settings + * the settings + * @param request + * the HTTP request from which the logout request is to be + * extracted and parsed + * @return the created {@link LogoutRequest} instance + * @throws Exception + * in case some error occurred while trying to create the + * {@link LogoutRequest} instance + */ + default LogoutRequest createIncomingLogoutRequest(final Saml2Settings settings, final HttpRequest request) + throws Exception { + return new LogoutRequest(settings, request); + } + + /** + * Creates a {@link LogoutResponse} instance for an outgoing response. + * + * @param settings + * the settings + * @param params + * the logout response input parameters + * @return the created {@link LogoutResponse} instance + */ + default LogoutResponse createOutgoingLogoutResponse(final Saml2Settings settings, final LogoutResponseParams params) { + return new LogoutResponse(settings, params); + } + + /** + * Creates a {@link LogoutRequest} instance for an incoming response. + * + * @param settings + * the settings + * @param request + * the HTTP request from which the logout response is to be + * extracted and parsed + * @return the created {@link LogoutResponse} instance + * @throws Exception + * in case some error occurred while trying to create the + * {@link LogoutResponse} instance + */ + default LogoutResponse createIncomingLogoutResponse(final Saml2Settings settings, final HttpRequest request) + throws Exception { + return new LogoutResponse(settings, request); + } +} \ No newline at end of file diff --git a/toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java deleted file mode 100644 index 7cbdd32c..00000000 --- a/toolkit/src/main/java/com/onelogin/saml2/factory/SamlOutgoingMessageFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.onelogin.saml2.factory; - -import com.onelogin.saml2.settings.Saml2Settings; - -/** - * Factory which can create an outgoing SAML message object from a - * {@link Saml2Settings} instance and other input parameters. - * - * @param - * the type of input parameters required - * @param - * the type of SAML outgoing message object created - */ -@FunctionalInterface -public interface SamlOutgoingMessageFactory { - - /** - * Creates an outgoing SAML message object. - * - * @param settings - * the settings - * @param params - * the input parameters - * @return the created received SAML message object - */ - R create(Saml2Settings settings, U params); -} \ No newline at end of file diff --git a/toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java b/toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java deleted file mode 100644 index 0a78a800..00000000 --- a/toolkit/src/main/java/com/onelogin/saml2/factory/SamlReceivedMessageFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.onelogin.saml2.factory; - -import com.onelogin.saml2.http.HttpRequest; -import com.onelogin.saml2.settings.Saml2Settings; - -/** - * Factory which can create a received SAML message object from a - * {@link Saml2Settings} instance and other input parameters. - * - * @param - * the type of received SAML message object created - */ -@FunctionalInterface -public interface SamlReceivedMessageFactory { - - /** - * Creates a received SAML message object. - * - * @param settings - * the settings - * @param httpRequest - * the HTTP request - * @return the created received SAML message object - * @throws Exception - * if the message creation fails - */ - R create(Saml2Settings settings, HttpRequest httpRequest) throws Exception; -} \ No newline at end of file diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index 6846bfa7..6c376839 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -55,6 +55,7 @@ import com.onelogin.saml2.exception.SettingsException; import com.onelogin.saml2.exception.ValidationError; import com.onelogin.saml2.exception.XMLEntityException; +import com.onelogin.saml2.factory.SamlMessageFactory; import com.onelogin.saml2.http.HttpRequest; import com.onelogin.saml2.logout.LogoutRequest; import com.onelogin.saml2.logout.LogoutRequestParams; @@ -2235,7 +2236,7 @@ private static class FactoryInvokedException extends RuntimeException { } /** - * Tests that the AuthnRequest factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for AuthnRequests and the right parameters are passed to it. * * @throws Exception * @@ -2259,12 +2260,17 @@ public AuthnRequestEx(Saml2Settings sett, AuthnRequestParams par) { } Auth auth = new Auth(settings, request, response); - auth.setAuthnRequestFactory((sett, param) -> new AuthnRequestEx(sett, param)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public AuthnRequest createAuthnRequest(Saml2Settings settings, AuthnRequestParams params) { + return new AuthnRequestEx(settings, params); + } + }); auth.login(params); } /** - * Tests that the SamlResponse factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for SamlResponses and the right parameters are passed to it. * * @throws Exception * @@ -2291,12 +2297,17 @@ public SamlResponseEx(Saml2Settings sett, HttpRequest req) throws Exception { } Auth auth = new Auth(settings, request, response); - auth.setSamlResponseFactory((sett, req) -> new SamlResponseEx(sett, req)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public SamlResponse createSamlResponse(Saml2Settings settings, HttpRequest request) throws Exception { + return new SamlResponseEx(settings, request); + } + }); auth.processResponse(); } /** - * Tests that the outgoing LogoutRequest factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for outgoing LogoutRequests and the right parameters are passed to it. * * @throws Exception * @@ -2322,19 +2333,24 @@ public LogoutRequestEx(Saml2Settings sett, LogoutRequestParams par) { } Auth auth = new Auth(settings, request, response); - auth.setOutgoingLogoutRequestFactory((sett, param) -> new LogoutRequestEx(sett, param)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public LogoutRequest createOutgoingLogoutRequest(Saml2Settings settings, LogoutRequestParams params) { + return new LogoutRequestEx(settings, params); + } + }); auth.logout(null, params); } /** - * Tests that the received LogoutRequest factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for incoming LogoutRequests and the right parameters are passed to it. * * @throws Exception * * @see com.onelogin.saml2.Auth#setReceivedLogoutRequestFactory(com.onelogin.saml2.factory.SamlReceivedMessageFactory) */ @Test(expected = FactoryInvokedException.class) - public void testReceivedLogoutRequestFactory() throws Exception { + public void testIncomingLogoutRequestFactory() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); HttpSession session = mock(HttpSession.class); @@ -2357,12 +2373,18 @@ public LogoutRequestEx(Saml2Settings sett, HttpRequest req) { } Auth auth = new Auth(settings, request, response); - auth.setReceivedLogoutRequestFactory((sett, req) -> new LogoutRequestEx(sett, req)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public LogoutRequest createIncomingLogoutRequest(Saml2Settings settings, HttpRequest request) + throws Exception { + return new LogoutRequestEx(settings, request); + } + }); auth.processSLO(); } /** - * Tests that the outgoing LogoutResponse factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for outgoing LogoutResponses and the right parameters are passed to it. * * @throws Exception * @@ -2396,19 +2418,25 @@ public LogoutResponseEx(Saml2Settings sett, LogoutResponseParams par) { } Auth auth = new Auth(settings, request, response); - auth.setOutgoingLogoutResponseFactory((sett, param) -> new LogoutResponseEx(settings, param)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public LogoutResponse createOutgoingLogoutResponse(Saml2Settings settings, + LogoutResponseParams params) { + return new LogoutResponseEx(settings, params); + } + }); auth.processSLO(false, null); } /** - * Tests that the received LogoutResponse factory gets invoked by Auth and the right parameters are passed to it. + * Tests that the SAML message factory gets invoked by Auth for incoming LogoutResponses and the right parameters are passed to it. * * @throws Exception * * @see com.onelogin.saml2.Auth#setReceivedLogoutResponseFactory(com.onelogin.saml2.factory.SamlReceivedMessageFactory) */ @Test(expected = FactoryInvokedException.class) - public void testReceivedLogoutResponseFactory() throws Exception { + public void testIncomingLogoutResponseFactory() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); HttpSession session = mock(HttpSession.class); @@ -2431,7 +2459,12 @@ public LogoutResponseEx(Saml2Settings sett, HttpRequest req) { } Auth auth = new Auth(settings, request, response); - auth.setReceivedLogoutResponseFactory((sett, req) -> new LogoutResponseEx(sett, req)); + auth.setSamlMessageFactory(new SamlMessageFactory() { + @Override + public LogoutResponse createIncomingLogoutResponse(Saml2Settings settings, HttpRequest request) { + return new LogoutResponseEx(settings, request); + } + }); auth.processSLO(); } } From c939096310049fc3c37d696fa11591ad6b3919cc Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 21 Sep 2021 19:18:08 +0200 Subject: [PATCH 09/34] Update xmlsec dependency --- README.md | 5 ++++- core/pom.xml | 2 +- toolkit/pom.xml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d1bf4d3b..25c06020 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,13 @@ Add SAML support to your Java applications using this library. Forget those complicated libraries and use that open source library provided and supported by OneLogin Inc. +2.8.0 uses xmlsec 2.2.3 which fixes [CVE-2021-40690](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-1655558) + Version >= 2.5.0 compatible with java8 / java9. Not compatible with java7 + 2.5.0 sets the 'strict' setting parameter to true. -2.5.0 uses xmlsec 2.1.4 which fixes [CVE-2019-12400](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-460281) +2.5.0 uses xmlsec 2.1.4 which fixes [CVE-2019-12400](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-460281) Version 2.0.0 - 2.4.0, compatible with java7 / java8. diff --git a/core/pom.xml b/core/pom.xml index 405ea7f1..e2ce82af 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -60,7 +60,7 @@ org.apache.santuario xmlsec - 2.2.2 + 2.2.3 commons-codec diff --git a/toolkit/pom.xml b/toolkit/pom.xml index 841ee89c..f2323afb 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -81,7 +81,7 @@ org.apache.santuario xmlsec - 2.2.2 + 2.2.3 commons-codec From 95dd5dd1253d23452a3ecc389077b86692e19da0 Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 21 Sep 2021 21:28:27 +0200 Subject: [PATCH 10/34] Update rest of dependencies --- core/pom.xml | 6 +++--- pom.xml | 17 ++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e2ce82af..11aed629 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,13 +72,13 @@ com.azure azure-security-keyvault-keys - 4.3.0 + 4.3.3 true com.azure azure-identity - 1.3.3 + 1.3.6 true @@ -88,7 +88,7 @@ org.jacoco jacoco-maven-plugin - 0.8.6 + 0.8.7 jacoco.agent.argLine diff --git a/pom.xml b/pom.xml index b4bee9bb..456a455f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ 4.0.0 - com.onelogin java-saml-toolkit 2.7.1-SNAPSHOT @@ -13,10 +12,10 @@ UTF-8 UTF-8 - 1.7.30 - 4.13.1 - 1.2.3 - 3.11 + 1.7.32 + 4.13.2 + 1.2.6 + 3.12.0 @@ -72,7 +71,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.4.1 + 3.0.0 enforce-versions @@ -97,7 +96,7 @@ org.owasp dependency-check-maven - 6.1.6 + 6.3.1 7 @@ -198,7 +197,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.3.1 attach-javadocs @@ -214,7 +213,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts From c71f75bd9ad4552f02cb5345e6ae26dbce0fdab4 Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 21 Sep 2021 21:33:16 +0200 Subject: [PATCH 11/34] [maven-release-plugin] prepare release v2.8.0 --- core/pom.xml | 2 +- pom.xml | 4 ++-- samples/java-saml-tookit-jspsample/pom.xml | 2 +- samples/pom.xml | 2 +- toolkit/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 11aed629..0855e38b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.7.1-SNAPSHOT + 2.8.0 jar diff --git a/pom.xml b/pom.xml index 456a455f..5e2896c1 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.onelogin java-saml-toolkit - 2.7.1-SNAPSHOT + 2.8.0 pom OneLogin java-saml Toolkit Project @@ -157,7 +157,7 @@ scm:git:git@github.com:onelogin/java-saml.git scm:git:git@github.com:onelogin/java-saml.git https://github.com/onelogin/java-saml - HEAD + v2.8.0 diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index 6ca21609..73866caa 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-tookit-samples - 2.7.1-SNAPSHOT + 2.8.0 java-saml-tookit-jspsample diff --git a/samples/pom.xml b/samples/pom.xml index 4f532de0..3dc9212d 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.7.1-SNAPSHOT + 2.8.0 java-saml-tookit-samples diff --git a/toolkit/pom.xml b/toolkit/pom.xml index f2323afb..d6d5b4be 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.7.1-SNAPSHOT + 2.8.0 jar From 265c5267f09f9c207972c2771a7f5dff4a66d27c Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 21 Sep 2021 21:33:21 +0200 Subject: [PATCH 12/34] [maven-release-plugin] prepare for next development iteration --- core/pom.xml | 2 +- pom.xml | 4 ++-- samples/java-saml-tookit-jspsample/pom.xml | 2 +- samples/pom.xml | 2 +- toolkit/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 0855e38b..a00edff3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.0 + 2.8.1-SNAPSHOT jar diff --git a/pom.xml b/pom.xml index 5e2896c1..f18ede37 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.onelogin java-saml-toolkit - 2.8.0 + 2.8.1-SNAPSHOT pom OneLogin java-saml Toolkit Project @@ -157,7 +157,7 @@ scm:git:git@github.com:onelogin/java-saml.git scm:git:git@github.com:onelogin/java-saml.git https://github.com/onelogin/java-saml - v2.8.0 + HEAD diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index 73866caa..9c6185e3 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-tookit-samples - 2.8.0 + 2.8.1-SNAPSHOT java-saml-tookit-jspsample diff --git a/samples/pom.xml b/samples/pom.xml index 3dc9212d..470d0048 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.0 + 2.8.1-SNAPSHOT java-saml-tookit-samples diff --git a/toolkit/pom.xml b/toolkit/pom.xml index d6d5b4be..e517b4de 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.0 + 2.8.1-SNAPSHOT jar From f7364f7d7c98a4d6da800d4659ca5f2783d4d216 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Tue, 6 Apr 2021 19:33:50 +0200 Subject: [PATCH 13/34] Add support for multiple fully-fledged contacts for SP It's now possible to specify an arbitrary number of contacts, with all the information supported by the SAML 2.0 specification, including multiple e-mail addresses and multiple phone numbers per contact. Since this is indeed information related to the Service Provider (which appears in the SP metadata), the new (indexed) properties used to declare contacts have been put in the "onelogin.saml2.sp" namespace and their parsing uses the same technique used to support multiple Attribute Consuming Services. The legacy way to specify just a technical and a support contacts is still supported (these "legacy" contacts are appended as the last two ones). The Contact class has been enhanced to support all ContactType attributes supported by the SAML 2.0 specification but still exposes the old constructor and single e-mail address getter (although being deprecated) to provide a 100% backward compatible API. Fixes #326. --- README.md | 37 ++- .../com/onelogin/saml2/model/Contact.java | 108 ++++++-- .../com/onelogin/saml2/settings/Metadata.java | 17 +- .../saml2/settings/Saml2Settings.java | 7 +- .../saml2/settings/SettingsBuilder.java | 232 +++++++++++++++++- .../com/onelogin/saml2/util/Constants.java | 9 +- .../test/settings/IdPMetadataParserTest.java | 18 +- .../saml2/test/settings/MetadataTest.java | 73 +++++- .../test/settings/SettingBuilderTest.java | 166 +++++++++++-- .../resources/config/config.all.properties | 13 + .../config/config.all_specialchars.properties | 13 + 11 files changed, 620 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index a94c8ffe..df0c3bf0 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,31 @@ onelogin.saml2.sp.x509certNew = # 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 onelogin.saml2.sp.privatekey = +# Organization +onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.displayname = SP Java Example +onelogin.saml2.organization.url = http://sp.example.com +onelogin.saml2.organization.lang = en + +# Contacts (use indexes to specify multiple contacts, multiple e-mail addresses per contact, multiple phone numbers per contact) +onelogin.saml2.sp.contact[0].contactType=administrative +onelogin.saml2.sp.contact[0].company=ACME +onelogin.saml2.sp.contact[0].given_name=Guy +onelogin.saml2.sp.contact[0].sur_name=Administrative +onelogin.saml2.sp.contact[0].email_address[0]=administrative@example.com +onelogin.saml2.sp.contact[0].email_address[1]=administrative2@example.com +onelogin.saml2.sp.contact[0].telephone_number[0]=+1-123456789 +onelogin.saml2.sp.contact[0].telephone_number[1]=+1-987654321 +onelogin.saml2.sp.contact[1].contactType=other +onelogin.saml2.sp.contact[1].company=Big Corp +onelogin.saml2.sp.contact[1].email_address=info@example.com + +# Legacy contacts (legacy way to specify just a technical and a support contact with minimal info) +onelogin.saml2.contacts.technical.given_name = Technical Guy +onelogin.saml2.contacts.technical.email_address = technical@example.com +onelogin.saml2.contacts.support.given_name = Support Guy +onelogin.saml2.contacts.support.email_address = support@example.com + ## Identity Provider Data that we want connect with our SP ## # Identifier of the IdP entity (must be a URI) @@ -374,18 +399,6 @@ onelogin.saml2.security.reject_deprecated_alg = true onelogin.saml2.parsing.trim_name_ids = false onelogin.saml2.parsing.trim_attribute_values = false -# Organization -onelogin.saml2.organization.name = SP Java -onelogin.saml2.organization.displayname = SP Java Example -onelogin.saml2.organization.url = http://sp.example.com -onelogin.saml2.organization.lang = en - -# Contacts -onelogin.saml2.contacts.technical.given_name = Technical Guy -onelogin.saml2.contacts.technical.email_address = technical@example.com -onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com - # Prefix used in generated Unique IDs. # Optional, defaults to ONELOGIN_ or full ID is like ONELOGIN_ebb0badd-4f60-4b38-b20a-a8e01f0592b1. # At minimun, the prefix can be non-numeric character such as "_". diff --git a/core/src/main/java/com/onelogin/saml2/model/Contact.java b/core/src/main/java/com/onelogin/saml2/model/Contact.java index 82e3da22..eb9a52ee 100644 --- a/core/src/main/java/com/onelogin/saml2/model/Contact.java +++ b/core/src/main/java/com/onelogin/saml2/model/Contact.java @@ -1,5 +1,8 @@ package com.onelogin.saml2.model; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Contact class of OneLogin's Java Toolkit. @@ -8,34 +11,78 @@ */ public class Contact { /** - * Contact type - */ + * Contact type + */ private final String contactType; /** - * Contact given name - */ + * Contact company + */ + private final String company; + + /** + * Contact given name + */ private final String givenName; + + /** + * Contact surname + */ + private final String surName; /** - * Contact email - */ - private final String emailAddress; + * Contact email + */ + private final List emailAddresses; /** - * Constructor + * Contact phone number + */ + private final List telephoneNumbers; + + /** + * Constructor to specify minimal contact data. + *

+ * To maintain backward compatibility, a null given name and a + * null e-mail address are handled as being empty strings. * * @param contactType - * String. Contact type + * Contact type * @param givenName - * String. Contact given name + * Contact given name * @param emailAddress - * String. Contact email + * Contact e-mail + * @deprecated use {@link #Contact(String, String, String, String, List, List)} */ + @Deprecated public Contact(String contactType, String givenName, String emailAddress) { + this(contactType, null, givenName != null ? givenName : "", null, + Arrays.asList(emailAddress != null ? emailAddress : ""), null); + } + + /** + * Constructor + * + * @param contactType + * Contact type + * @param givenName + * Contact given name + * @param surName + * Contact surname + * @param company + * Contact company + * @param emailAddresses + * Contact e-mails + * @param telephoneNumbers + * Contact phone numbers + */ + public Contact(String contactType, String company, String givenName, String surName, List emailAddresses, List telephoneNumbers) { this.contactType = contactType != null? contactType : ""; - this.givenName = givenName != null? givenName : ""; - this.emailAddress = emailAddress != null? emailAddress : ""; + this.company = company; + this.givenName = givenName; + this.surName = surName; + this.emailAddresses = emailAddresses != null? emailAddresses: Collections.emptyList(); + this.telephoneNumbers = telephoneNumbers != null? telephoneNumbers: Collections.emptyList(); } /** @@ -46,17 +93,46 @@ public final String getContactType() { } /** - * @return string the contact email + * @return the contact email + * @deprecated this returns just the first e-mail address in {@link #getEmailAddresses()} */ + @Deprecated public final String getEmailAddress() { - return emailAddress; + return emailAddresses.size() > 0? emailAddresses.get(0): null; } /** - * @return string the contact given name + * @return a list containing the contact e-mail addresses (never null) + */ + public final List getEmailAddresses() { + return emailAddresses; + } + + /** + * @return the contact given name */ public final String getGivenName() { return givenName; } + + /** + * @return the contact surname + */ + public final String getSurName() { + return surName; + } + + /** + * @return the contact company + */ + public final String getCompany() { + return company; + } + /** + * @return a list containing the contact phone numbers (never null) + */ + public final List getTelephoneNumbers() { + return telephoneNumbers; + } } \ No newline at end of file diff --git a/core/src/main/java/com/onelogin/saml2/settings/Metadata.java b/core/src/main/java/com/onelogin/saml2/settings/Metadata.java index 5ed070a6..30a83184 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Metadata.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Metadata.java @@ -277,8 +277,21 @@ private String toContactsXml(List contacts) { for (Contact contact : contacts) { contactsXml.append(""); - contactsXml.append("" + Util.toXml(contact.getGivenName()) + ""); - contactsXml.append("" + Util.toXml(contact.getEmailAddress()) + ""); + final String company = contact.getCompany(); + if(company != null) + contactsXml.append("" + Util.toXml(company) + ""); + final String givenName = contact.getGivenName(); + if(givenName != null) + contactsXml.append("" + Util.toXml(givenName) + ""); + final String surName = contact.getSurName(); + if(surName != null) + contactsXml.append("" + Util.toXml(surName) + ""); + final List emailAddresses = contact.getEmailAddresses(); + emailAddresses.forEach(emailAddress -> contactsXml + .append("" + Util.toXml(emailAddress) + "")); + final List telephoneNumbers = contact.getTelephoneNumbers(); + telephoneNumbers.forEach(telephoneNumber -> contactsXml + .append("" + Util.toXml(telephoneNumber) + "")); contactsXml.append(""); } diff --git a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java index b2d2078a..292b75e6 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java @@ -9,6 +9,8 @@ import java.util.List; import com.onelogin.saml2.model.hsm.HSM; + +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -1032,7 +1034,10 @@ public List checkSPSettings() { } */ - if (contact.getEmailAddress().isEmpty() || contact.getGivenName().isEmpty()) { + if (contact.getEmailAddresses().isEmpty() || contact.getEmailAddresses().stream().allMatch(StringUtils::isEmpty) || + (StringUtils.isEmpty(contact.getCompany()) && + StringUtils.isEmpty(contact.getGivenName()) && + StringUtils.isEmpty(contact.getSurName()))) { errorMsg = "contact_not_enough_data"; errors.add(errorMsg); LOGGER.error(errorMsg); diff --git a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java index 6c7a52ff..6232044e 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java +++ b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java @@ -15,11 +15,19 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; import java.util.Properties; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +35,7 @@ import com.onelogin.saml2.model.Contact; import com.onelogin.saml2.model.KeyStoreSettings; import com.onelogin.saml2.model.Organization; +import com.onelogin.saml2.util.Constants; import com.onelogin.saml2.util.Util; /** @@ -65,6 +74,14 @@ public class SettingsBuilder { public final static String SP_PRIVATEKEY_PROPERTY_KEY = "onelogin.saml2.sp.privatekey"; public final static String SP_X509CERTNEW_PROPERTY_KEY = "onelogin.saml2.sp.x509certNew"; + public final static String SP_CONTACT_PROPERTY_KEY_PREFIX = "onelogin.saml2.sp.contact"; + public final static String SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX = "contactType"; + public final static String SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX = "company"; + public final static String SP_CONTACT_GIVEN_NAME_PROPERTY_KEY_SUFFIX = "given_name"; + public final static String SP_CONTACT_SUR_NAME_PROPERTY_KEY_SUFFIX = "sur_name"; + public final static String SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX = "email_address"; + public final static String SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX = "telephone_number"; + // KeyStore public final static String KEYSTORE_KEY = "onelogin.saml2.keystore.store"; public final static String KEYSTORE_ALIAS = "onelogin.saml2.keystore.alias"; @@ -112,9 +129,13 @@ public class SettingsBuilder { public final static String PARSING_TRIM_ATTRIBUTE_VALUES = "onelogin.saml2.parsing.trim_attribute_values"; // Misc + @Deprecated public final static String CONTACT_TECHNICAL_GIVEN_NAME = "onelogin.saml2.contacts.technical.given_name"; + @Deprecated public final static String CONTACT_TECHNICAL_EMAIL_ADDRESS = "onelogin.saml2.contacts.technical.email_address"; + @Deprecated public final static String CONTACT_SUPPORT_GIVEN_NAME = "onelogin.saml2.contacts.support.given_name"; + @Deprecated public final static String CONTACT_SUPPORT_EMAIL_ADDRESS = "onelogin.saml2.contacts.support.email_address"; public final static String ORGANIZATION_NAME = "onelogin.saml2.organization.name"; @@ -261,7 +282,7 @@ public Saml2Settings build(Saml2Settings saml2Setting) { List contacts = this.loadContacts(); if (!contacts.isEmpty()) { - saml2Setting.setContacts(loadContacts()); + saml2Setting.setContacts(contacts); } Organization org = this.loadOrganization(); @@ -464,15 +485,26 @@ private Organization loadOrganization() { /** * Loads the contacts settings from the properties file + * + * @return a list containing all the loaded contacts */ + @SuppressWarnings("deprecation") private List loadContacts() { - List contacts = new LinkedList<>(); - + // first split properties into a map of properties + // key = contact index; value = contact properties + final SortedMap> contactProps = + extractIndexedProperties(SP_CONTACT_PROPERTY_KEY_PREFIX, samlData); + // then build each contact + // multiple indexed services specified + final List contacts = contactProps.entrySet().stream() + .map(entry -> loadContact(entry.getValue(), entry.getKey())) + .collect(Collectors.toList()); + // append legacy contacts if present String technicalGn = loadStringProperty(CONTACT_TECHNICAL_GIVEN_NAME); String technicalEmailAddress = loadStringProperty(CONTACT_TECHNICAL_EMAIL_ADDRESS); if ((technicalGn != null && !technicalGn.isEmpty()) || (technicalEmailAddress != null && !technicalEmailAddress.isEmpty())) { - Contact technical = new Contact("technical", technicalGn, technicalEmailAddress); + Contact technical = new Contact(Constants.CONTACT_TYPE_TECHNICAL, technicalGn, technicalEmailAddress); contacts.add(technical); } @@ -480,13 +512,185 @@ private List loadContacts() { String supportEmailAddress = loadStringProperty(CONTACT_SUPPORT_EMAIL_ADDRESS); if ((supportGn != null && !supportGn.isEmpty()) || (supportEmailAddress != null && !supportEmailAddress.isEmpty())) { - Contact support = new Contact("support", supportGn, supportEmailAddress); + Contact support = new Contact(Constants.CONTACT_TYPE_SUPPORT, supportGn, supportEmailAddress); contacts.add(support); } return contacts; } + /** + * Loads a single contact from settings. + * + * @param contactProps + * a map containing the contact settings + * @param index + * the contact index + * @return the loaded contact + */ + private Contact loadContact(Map contactProps, int index) { + final String contactType = loadStringProperty(SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX, contactProps); + final String company = loadStringProperty(SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX, contactProps); + final String givenName = loadStringProperty(SP_CONTACT_GIVEN_NAME_PROPERTY_KEY_SUFFIX, contactProps); + final String surName = loadStringProperty(SP_CONTACT_SUR_NAME_PROPERTY_KEY_SUFFIX, contactProps); + // split properties into a map of properties + // key = e-mail address index; value = e-mail address + final SortedMap emailAddresses = extractIndexedValues(SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX, contactProps); + final List emails = toStringList(emailAddresses); + // split properties into a map of properties + // key = phone number index; value = phone numbers + final SortedMap phoneNumbers = extractIndexedValues(SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX, contactProps); + final List numbers = toStringList(phoneNumbers); + return new Contact(contactType, company, givenName, surName, emails, numbers); + } + + /** + * Given a map containing settings data, extracts all the indexed properties + * identified by a given prefix. The returned map has indexes as keys and a map + * describing the extracted indexed data as values. Keys are sorted by their + * natural order (i.e. iterating over the map will return entries in index order). + *

+ * For instance, if the prefix is foo, all the following properties + * will be extracted: + * + *

+	 * foo[0].prop1=<value1>
+	 * foo[0].prop2=<value2>
+	 * foo[1].prop1=<value3>
+	 * 
+ * + * and the returned map will be: + * + *
+	 * 0 => prop1=<value1>
+	 *      prop2=<value2>
+	 * 1 => prop1=<value3>
+	 * 
+ * + * The index is optional: if missing, "-1" is returned. In other words, in the + * above example: + * + *
+	 * foo.prop1=<value1>
+	 * foo.prop2=<value2>
+	 * 
+ * + * will be mapped to: + * + *
+	 * -1 => prop1=<value1>
+	 *       prop2=<value2>
+	 * 
+ * + * Indices can be made of maximum 9 digits, to prevent overflows. Leading zeroes + * are discarded. + * + * @param prefix + * the prefix that identifies the indexed property to extract + * @param data + * the input data + * @return a map with extracted data for each identified index + */ + private SortedMap> extractIndexedProperties(String prefix, Map data) { + final Pattern p = Pattern.compile(Pattern.quote(prefix) + + "(?:\\[(\\d{1,9})\\])?\\.(.+)"); + final SortedMap> indexedProps = new TreeMap<>(); + for(final Entry prop: data.entrySet()) { + final Matcher m = p.matcher(prop.getKey()); + if(m.matches()) { + final String indexString = m.group(1); + final int index = indexString == null? -1: Integer.parseInt(indexString); + final String suffix = m.group(2); + Map props = indexedProps.get(index); + if(props == null) { + props = new HashMap<>(); + indexedProps.put(index, props); + } + props.put(suffix, prop.getValue()); + } + } + return indexedProps; + } + + /** + * Given a map containing settings data, extracts all the indexed values + * identified by a given prefix. The returned map has indexes as keys and the + * corresponding values as values. Keys are sorted by their natural order + * (i.e. iterating over the map will return entries in index order). + *

+ * For instance, if the prefix is foo, all the following values + * will be extracted: + * + *

+	 * foo[0]=<value1>
+	 * foo[1]=<value2>
+	 * foo[2]=<value3>
+	 * 
+ * + * and the returned map will be: + * + *
+	 * 0 => <value1>
+	 * 1 => <value2>
+	 * 3 => <value3>
+	 * 
+ * + * The index is optional: if missing, "-1" is returned. In other words, in the + * above example: + * + *
+	 * foo=<value1>
+	 * 
+ * + * will be mapped to: + * + *
+	 * -1 => <value1>
+	 * 
+ * + * Indices can be made of maximum 9 digits, to prevent overflows. Leading zeroes + * are discarded. + * + * @param prefix + * the prefix that identifies the indexed property to extract + * @param data + * the input data + * @return a map with extracted values for each identified index + */ + private SortedMap extractIndexedValues(String prefix, Map data) { + final Pattern p = Pattern.compile(Pattern.quote(prefix) + + "(?:\\[(\\d{1,9})\\])?"); + final SortedMap indexedValues = new TreeMap<>(); + for(final Entry prop: data.entrySet()) { + final Matcher m = p.matcher(prop.getKey()); + if(m.matches()) { + final String indexString = m.group(1); + final int index = indexString == null? -1: Integer.parseInt(indexString); + indexedValues.put(index, prop.getValue()); + } + } + return indexedValues; + } + + /** + * Given a map of indexed property values (possibly extracted with + * {@link #extractIndexedValues(String, Map)}), returns a list containing all + * the {@link String} values contained in the map, sorted by their iteration + * order. + * + * @param indexedValues + * a map containing indexed values (key = index; value = actual + * value) + * @return a list containing all the string values in the input map, sorted by + * their iteration order; therefore, if the map is a {@link SortedMap}, + * the returned list has values sorted by their index + */ + private List toStringList(final Map indexedValues) { + return indexedValues.values().stream() + .map(value -> isString(value) ? StringUtils.trimToNull((String) value) : null) + .filter(Objects::nonNull).collect(Collectors.toList()); + } + /** * Loads the unique ID prefix. Uses default if property not set. */ @@ -568,13 +772,25 @@ private void loadSpSetting() { * @return the value */ private String loadStringProperty(String propertyKey) { - Object propValue = samlData.get(propertyKey); + return loadStringProperty(propertyKey, samlData); + } + + /** + * Loads a property of the type String from the specified data + * + * @param propertyKey the property name + * @param data the input data + * + * @return the value + */ + private String loadStringProperty(String propertyKey, Map data) { + Object propValue = data.get(propertyKey); if (isString(propValue)) { return StringUtils.trimToNull((String) propValue); } return null; } - + /** * Loads a property of the type Boolean from the Properties object * diff --git a/core/src/main/java/com/onelogin/saml2/util/Constants.java b/core/src/main/java/com/onelogin/saml2/util/Constants.java index dd3037a7..d3aae65b 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Constants.java +++ b/core/src/main/java/com/onelogin/saml2/util/Constants.java @@ -83,6 +83,13 @@ public final class Constants { public static final String STATUS_UNKNOWN_PRINCIPAL = "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"; public static final String STATUS_UNSUPPORTED_BINDING = "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"; + // Contact types + public static final String CONTACT_TYPE_TECHNICAL = "technical"; + public static final String CONTACT_TYPE_SUPPORT = "support"; + public static final String CONTACT_TYPE_ADMINISTRATIVE = "administrative"; + public static final String CONTACT_TYPE_BILLING = "billing"; + public static final String CONTACT_TYPE_OTHER = "other"; + // Canonization public static final String C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; public static final String C14N_WC = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"; @@ -91,7 +98,7 @@ public final class Constants { public static final String C14NEXC = "http://www.w3.org/2001/10/xml-exc-c14n#"; public static final String C14NEXC_WC = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"; - // Sign & Crypt + // Sign & Crypt // https://www.w3.org/TR/xmlenc-core/#sec-Alg-MessageDigest // https://www.w3.org/TR/xmlsec-algorithms/#signature-method-uris // https://tools.ietf.org/html/rfc6931 diff --git a/core/src/test/java/com/onelogin/saml2/test/settings/IdPMetadataParserTest.java b/core/src/test/java/com/onelogin/saml2/test/settings/IdPMetadataParserTest.java index 7e45aace..c3c25e44 100644 --- a/core/src/test/java/com/onelogin/saml2/test/settings/IdPMetadataParserTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/settings/IdPMetadataParserTest.java @@ -236,9 +236,12 @@ public void testInjectIntoSettings() throws Exception { assertEquals("http://localhost:8080/java-saml-jspsample/metadata.jsp", setting.getSpEntityId()); assertEquals(Constants.RSA_SHA512, setting.getSignatureAlgorithm()); assertEquals(Constants.SHA512, setting.getDigestAlgorithm()); - assertEquals(2, setting.getContacts().size()); - assertEquals("technical@example.com", setting.getContacts().get(0).getEmailAddress()); - assertEquals("support@example.com", setting.getContacts().get(1).getEmailAddress()); + assertEquals(4, setting.getContacts().size()); + assertEquals("administrative@example.com", setting.getContacts().get(0).getEmailAddresses().get(0)); + assertEquals("administrative2@example.com", setting.getContacts().get(0).getEmailAddresses().get(1)); + assertEquals("info@example.com", setting.getContacts().get(1).getEmailAddresses().get(0)); + assertEquals("technical@example.com", setting.getContacts().get(2).getEmailAddresses().get(0)); + assertEquals("support@example.com", setting.getContacts().get(3).getEmailAddresses().get(0)); assertEquals("SP Java", setting.getOrganization().getOrgName()); assertEquals("EXAMPLE", setting.getUniqueIDPrefix()); @@ -257,9 +260,12 @@ public void testInjectIntoSettings() throws Exception { assertEquals("http://localhost:8080/java-saml-jspsample/metadata.jsp", setting.getSpEntityId()); assertEquals(Constants.RSA_SHA512, setting.getSignatureAlgorithm()); assertEquals(Constants.SHA512, setting.getDigestAlgorithm()); - assertEquals(2, setting.getContacts().size()); - assertEquals("technical@example.com", setting.getContacts().get(0).getEmailAddress()); - assertEquals("support@example.com", setting.getContacts().get(1).getEmailAddress()); + assertEquals(4, setting.getContacts().size()); + assertEquals("administrative@example.com", setting.getContacts().get(0).getEmailAddresses().get(0)); + assertEquals("administrative2@example.com", setting.getContacts().get(0).getEmailAddresses().get(1)); + assertEquals("info@example.com", setting.getContacts().get(1).getEmailAddresses().get(0)); + assertEquals("technical@example.com", setting.getContacts().get(2).getEmailAddresses().get(0)); + assertEquals("support@example.com", setting.getContacts().get(3).getEmailAddresses().get(0)); assertEquals("SP Java", setting.getOrganization().getOrgName()); assertEquals("EXAMPLE", setting.getUniqueIDPrefix()); diff --git a/core/src/test/java/com/onelogin/saml2/test/settings/MetadataTest.java b/core/src/test/java/com/onelogin/saml2/test/settings/MetadataTest.java index f94e6f95..df5e3328 100644 --- a/core/src/test/java/com/onelogin/saml2/test/settings/MetadataTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/settings/MetadataTest.java @@ -147,21 +147,24 @@ public void testToContactsXml() throws IOException, CertificateEncodingException Metadata metadataObj = new Metadata(settings); String metadataStr = metadataObj.getMetadataString(); - String contactStr = "Technical Guytechnical@example.comSupport Guysupport@example.com"; - assertThat(metadataStr, containsString(contactStr)); + String administrativeContactStr = "ACMEGuyAdministrativeadministrative@example.comadministrative2@example.com+1-123456789+1-987654321"; + assertThat(metadataStr, containsString(administrativeContactStr)); + String otherContactStr = "Big Corpinfo@example.com"; + assertThat(metadataStr, containsString(otherContactStr)); Saml2Settings settings2 = new SettingsBuilder().fromFile("config/config.min.properties").build(); Metadata metadataObj2 = new Metadata(settings2); String metadataStr2 = metadataObj2.getMetadataString(); - assertThat(metadataStr2, not(containsString(contactStr))); + assertThat(metadataStr2, not(containsString(administrativeContactStr))); + assertThat(metadataStr2, not(containsString(otherContactStr))); } /** * Tests the toContactsXml method of Metadata *

* Case: contacts text containing special chars. - * + * * @throws IOException * @throws CertificateEncodingException * @throws Error @@ -173,8 +176,66 @@ public void testToContactsXmlSpecialChars() throws IOException, CertificateEncod Metadata metadataObj = new Metadata(settings); String metadataStr = metadataObj.getMetadataString(); - String contactStr = "T&chnical Guyt&chnical@example.com"Support Guy"supp&rt@example.com"; - assertThat(metadataStr, containsString(contactStr)); + String administrativeContactStr = "ACME & C."Guy"<Administrative>administrativ&@example.comadministrativ&2@example.com<+1>-123456789<+1>-987654321"; + assertThat(metadataStr, containsString(administrativeContactStr)); + String otherContactStr = "Big Corpinfo@example.com"; + assertThat(metadataStr, containsString(otherContactStr)); + + Saml2Settings settings2 = new SettingsBuilder().fromFile("config/config.min.properties").build(); + Metadata metadataObj2 = new Metadata(settings2); + String metadataStr2 = metadataObj2.getMetadataString(); + + assertThat(metadataStr2, not(containsString(administrativeContactStr))); + assertThat(metadataStr2, not(containsString(otherContactStr))); + } + + /** + * Tests the toContactsXml method of Metadata with regards to legacy contacts definition + * + * @throws IOException + * @throws CertificateEncodingException + * @throws Error + * @see com.onelogin.saml2.settings.Metadata#toContactsXml + */ + @Test + public void testToContactsXmlLegacy() throws IOException, CertificateEncodingException, Error { + Saml2Settings settings = getSettingFromAllProperties(); + Metadata metadataObj = new Metadata(settings); + String metadataStr = metadataObj.getMetadataString(); + + String technicalContactStr = "Technical Guytechnical@example.com"; + assertThat(metadataStr, containsString(technicalContactStr)); + String supportContactStr = "Support Guysupport@example.com"; + assertThat(metadataStr, containsString(supportContactStr)); + + Saml2Settings settings2 = new SettingsBuilder().fromFile("config/config.min.properties").build(); + Metadata metadataObj2 = new Metadata(settings2); + String metadataStr2 = metadataObj2.getMetadataString(); + + assertThat(metadataStr2, not(containsString(technicalContactStr))); + assertThat(metadataStr2, not(containsString(supportContactStr))); + } + + /** + * Tests the toContactsXml method of Metadata with regards to legacy contact definition + *

+ * Case: contacts text containing special chars. + * + * @throws IOException + * @throws CertificateEncodingException + * @throws Error + * @see com.onelogin.saml2.settings.Metadata#toContactsXml + */ + @Test + public void testToContactsXmlLegacySpecialChars() throws IOException, CertificateEncodingException, Error { + Saml2Settings settings = getSettingFromAllSpecialCharsProperties(); + Metadata metadataObj = new Metadata(settings); + String metadataStr = metadataObj.getMetadataString(); + + String technicalContactStr = "T&chnical Guyt&chnical@example.com"; + assertThat(metadataStr, containsString(technicalContactStr)); + String supportContactStr = ""Support Guy"supp&rt@example.com"; + assertThat(metadataStr, containsString(supportContactStr)); } /** diff --git a/core/src/test/java/com/onelogin/saml2/test/settings/SettingBuilderTest.java b/core/src/test/java/com/onelogin/saml2/test/settings/SettingBuilderTest.java index f9e31dde..b9206d4f 100644 --- a/core/src/test/java/com/onelogin/saml2/test/settings/SettingBuilderTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/settings/SettingBuilderTest.java @@ -291,15 +291,47 @@ public void testLoadFromFileAllProp() throws IOException, CertificateException, assertTrue(org.equalsTo(setting.getOrganization())); List contacts = setting.getContacts(); - assertEquals(2, contacts.size()); + assertEquals(4, contacts.size()); Contact c1 = contacts.get(0); - assertEquals("technical", c1.getContactType()); - assertEquals("technical@example.com", c1.getEmailAddress()); - assertEquals("Technical Guy", c1.getGivenName()); + assertEquals("administrative", c1.getContactType()); + assertEquals("ACME", c1.getCompany()); + assertEquals("Guy", c1.getGivenName()); + assertEquals("Administrative", c1.getSurName()); + assertEquals(2, c1.getEmailAddresses().size()); + assertEquals("administrative@example.com", c1.getEmailAddresses().get(0)); + assertEquals("administrative2@example.com", c1.getEmailAddresses().get(1)); + List c1Phones = c1.getTelephoneNumbers(); + assertEquals(2, c1Phones.size()); + assertEquals("+1-123456789", c1Phones.get(0)); + assertEquals("+1-987654321", c1Phones.get(1)); Contact c2 = contacts.get(1); - assertEquals("support", c2.getContactType()); - assertEquals("support@example.com", c2.getEmailAddress()); - assertEquals("Support Guy", c2.getGivenName()); + assertEquals("other", c2.getContactType()); + assertEquals("Big Corp", c2.getCompany()); + assertNull(c2.getGivenName()); + assertNull(c2.getSurName()); + assertEquals(1, c2.getEmailAddresses().size()); + assertEquals("info@example.com", c2.getEmailAddresses().get(0)); + assertEquals(0, c2.getTelephoneNumbers().size()); + Contact c3 = contacts.get(2); + assertEquals("technical", c3.getContactType()); + assertNull(c3.getCompany()); + assertEquals("Technical Guy", c3.getGivenName()); + assertNull(c3.getSurName()); + List c3Emails = c3.getEmailAddresses(); + assertEquals(1, c3Emails.size()); + assertEquals("technical@example.com", c3Emails.get(0)); + assertEquals("technical@example.com", c3.getEmailAddress()); + assertEquals(0, c3.getTelephoneNumbers().size()); + Contact c4 = contacts.get(3); + assertEquals("support", c4.getContactType()); + assertNull(c4.getCompany()); + assertEquals("Support Guy", c4.getGivenName()); + assertNull(c4.getSurName()); + List c4Emails = c4.getEmailAddresses(); + assertEquals(1, c4Emails.size()); + assertEquals("support@example.com", c4Emails.get(0)); + assertEquals("support@example.com", c4.getEmailAddress()); + assertEquals(0, c4.getTelephoneNumbers().size()); assertEquals("EXAMPLE", setting.getUniqueIDPrefix()); } @@ -753,6 +785,19 @@ public void testLoadFromValues() throws Exception { samlData.put(ORGANIZATION_LANG, "en"); // Contacts + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX, "administrative"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX, "ACME"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_GIVEN_NAME_PROPERTY_KEY_SUFFIX, "Guy"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_SUR_NAME_PROPERTY_KEY_SUFFIX, "Administrative"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX + "[0]", "administrative@example.com"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX + "[1]", "administrative2@example.com"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX + "[0]", "+1-123456789"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX + "[1]", "+1-987654321"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX, "other"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX, "Big Corp"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX, "info@example.com"); + + // Legacy contacts samlData.put(CONTACT_TECHNICAL_GIVEN_NAME, "Technical Guy"); samlData.put(CONTACT_TECHNICAL_EMAIL_ADDRESS, "technical@example.org"); samlData.put(CONTACT_SUPPORT_GIVEN_NAME, "Support Guy"); @@ -819,15 +864,48 @@ public void testLoadFromValues() throws Exception { assertTrue(org.equalsTo(setting.getOrganization())); List contacts = setting.getContacts(); - assertEquals(2, contacts.size()); + assertEquals(4, contacts.size()); Contact c1 = contacts.get(0); - assertEquals("technical", c1.getContactType()); - assertEquals("technical@example.org", c1.getEmailAddress()); - assertEquals("Technical Guy", c1.getGivenName()); + assertEquals("administrative", c1.getContactType()); + assertEquals("ACME", c1.getCompany()); + assertEquals("Guy", c1.getGivenName()); + assertEquals("Administrative", c1.getSurName()); + List c1Emails = c1.getEmailAddresses(); + assertEquals(2, c1Emails.size()); + assertEquals("administrative@example.com", c1Emails.get(0)); + assertEquals("administrative2@example.com", c1Emails.get(1)); + List c1Phones = c1.getTelephoneNumbers(); + assertEquals(2, c1Phones.size()); + assertEquals("+1-123456789", c1Phones.get(0)); + assertEquals("+1-987654321", c1Phones.get(1)); Contact c2 = contacts.get(1); - assertEquals("support", c2.getContactType()); - assertEquals("support@example.org", c2.getEmailAddress()); - assertEquals("Support Guy", c2.getGivenName()); + assertEquals("other", c2.getContactType()); + assertEquals("Big Corp", c2.getCompany()); + assertNull(c2.getGivenName()); + assertNull(c2.getSurName()); + List c2Emails = c2.getEmailAddresses(); + assertEquals(1, c2Emails.size()); + assertTrue(c2.getTelephoneNumbers().isEmpty()); + Contact c3 = contacts.get(2); + assertEquals("technical", c3.getContactType()); + assertNull(c3.getCompany()); + assertEquals("Technical Guy", c3.getGivenName()); + assertNull(c3.getSurName()); + List c3Emails = c3.getEmailAddresses(); + assertEquals(1, c3Emails.size()); + assertEquals("technical@example.org", c3Emails.get(0)); + assertEquals("technical@example.org", c3.getEmailAddress()); + assertTrue(c3.getTelephoneNumbers().isEmpty()); + Contact c4 = contacts.get(3); + assertEquals("support", c4.getContactType()); + assertNull(c4.getCompany()); + assertEquals("Support Guy", c4.getGivenName()); + assertNull(c4.getSurName()); + List c4Emails = c4.getEmailAddresses(); + assertEquals(1, c4Emails.size()); + assertEquals("support@example.org", c4Emails.get(0)); + assertEquals("support@example.org", c4.getEmailAddress()); + assertTrue(c4.getTelephoneNumbers().isEmpty()); assertEquals("_", setting.getUniqueIDPrefix()); @@ -917,6 +995,19 @@ public void testLoadFromValuesWithObjects() throws Exception { samlData.put(ORGANIZATION_LANG, "en"); // Contacts + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX, "administrative"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX, "ACME"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_GIVEN_NAME_PROPERTY_KEY_SUFFIX, "Guy"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_SUR_NAME_PROPERTY_KEY_SUFFIX, "Administrative"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX + "[0]", "administrative@example.com"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX + "[1]", "administrative2@example.com"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX + "[0]", "+1-123456789"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[0]." + SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX + "[1]", "+1-987654321"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_CONTACT_TYPE_PROPERTY_KEY_SUFFIX, "other"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_COMPANY_PROPERTY_KEY_SUFFIX, "Big Corp"); + samlData.put(SP_CONTACT_PROPERTY_KEY_PREFIX + "[1]." + SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX, "info@example.com"); + + // Legacy contacts samlData.put(CONTACT_TECHNICAL_GIVEN_NAME, "Technical Guy"); samlData.put(CONTACT_TECHNICAL_EMAIL_ADDRESS, "technical@example.org"); samlData.put(CONTACT_SUPPORT_GIVEN_NAME, "Support Guy"); @@ -975,15 +1066,48 @@ public void testLoadFromValuesWithObjects() throws Exception { assertTrue(org.equalsTo(setting.getOrganization())); List contacts = setting.getContacts(); - assertEquals(2, contacts.size()); + assertEquals(4, contacts.size()); Contact c1 = contacts.get(0); - assertEquals("technical", c1.getContactType()); - assertEquals("technical@example.org", c1.getEmailAddress()); - assertEquals("Technical Guy", c1.getGivenName()); + assertEquals("administrative", c1.getContactType()); + assertEquals("ACME", c1.getCompany()); + assertEquals("Guy", c1.getGivenName()); + assertEquals("Administrative", c1.getSurName()); + List c1Emails = c1.getEmailAddresses(); + assertEquals(2, c1Emails.size()); + assertEquals("administrative@example.com", c1Emails.get(0)); + assertEquals("administrative2@example.com", c1Emails.get(1)); + List c1Phones = c1.getTelephoneNumbers(); + assertEquals(2, c1Phones.size()); + assertEquals("+1-123456789", c1Phones.get(0)); + assertEquals("+1-987654321", c1Phones.get(1)); Contact c2 = contacts.get(1); - assertEquals("support", c2.getContactType()); - assertEquals("support@example.org", c2.getEmailAddress()); - assertEquals("Support Guy", c2.getGivenName()); + assertEquals("other", c2.getContactType()); + assertEquals("Big Corp", c2.getCompany()); + assertNull(c2.getGivenName()); + assertNull(c2.getSurName()); + List c2Emails = c2.getEmailAddresses(); + assertEquals(1, c2Emails.size()); + assertTrue(c2.getTelephoneNumbers().isEmpty()); + Contact c3 = contacts.get(2); + assertEquals("technical", c3.getContactType()); + assertNull(c3.getCompany()); + assertEquals("Technical Guy", c3.getGivenName()); + assertNull(c3.getSurName()); + List c3Emails = c3.getEmailAddresses(); + assertEquals(1, c3Emails.size()); + assertEquals("technical@example.org", c3Emails.get(0)); + assertEquals("technical@example.org", c3.getEmailAddress()); + assertTrue(c3.getTelephoneNumbers().isEmpty()); + Contact c4 = contacts.get(3); + assertEquals("support", c4.getContactType()); + assertNull(c4.getCompany()); + assertEquals("Support Guy", c4.getGivenName()); + assertNull(c4.getSurName()); + List c4Emails = c4.getEmailAddresses(); + assertEquals(1, c4Emails.size()); + assertEquals("support@example.org", c4Emails.get(0)); + assertEquals("support@example.org", c4.getEmailAddress()); + assertTrue(c4.getTelephoneNumbers().isEmpty()); assertEquals("ONELOGIN_", setting.getUniqueIDPrefix()); } diff --git a/core/src/test/resources/config/config.all.properties b/core/src/test/resources/config/config.all.properties index b2741928..fcdbf242 100644 --- a/core/src/test/resources/config/config.all.properties +++ b/core/src/test/resources/config/config.all.properties @@ -153,6 +153,19 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.organization.lang = en # Contacts +onelogin.saml2.sp.contact[0].contactType=administrative +onelogin.saml2.sp.contact[0].company=ACME +onelogin.saml2.sp.contact[0].given_name=Guy +onelogin.saml2.sp.contact[0].sur_name=Administrative +onelogin.saml2.sp.contact[0].email_address[0]=administrative@example.com +onelogin.saml2.sp.contact[0].email_address[1]=administrative2@example.com +onelogin.saml2.sp.contact[0].telephone_number[0]=+1-123456789 +onelogin.saml2.sp.contact[0].telephone_number[1]=+1-987654321 +onelogin.saml2.sp.contact[1].contactType=other +onelogin.saml2.sp.contact[1].company=Big Corp +onelogin.saml2.sp.contact[1].email_address=info@example.com + +# Legacy contacts onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy diff --git a/core/src/test/resources/config/config.all_specialchars.properties b/core/src/test/resources/config/config.all_specialchars.properties index a4492871..923297e0 100644 --- a/core/src/test/resources/config/config.all_specialchars.properties +++ b/core/src/test/resources/config/config.all_specialchars.properties @@ -144,6 +144,19 @@ onelogin.saml2.organization.url = http://sp.example.com?a=1&b=2 onelogin.saml2.organization.lang = en # Contacts +onelogin.saml2.sp.contact[0].contactType=administrative +onelogin.saml2.sp.contact[0].company=ACME & C. +onelogin.saml2.sp.contact[0].given_name="Guy" +onelogin.saml2.sp.contact[0].sur_name= +onelogin.saml2.sp.contact[0].email_address[0]=administrativ&@example.com +onelogin.saml2.sp.contact[0].email_address[1]=administrativ&2@example.com +onelogin.saml2.sp.contact[0].telephone_number[0]=<+1>-123456789 +onelogin.saml2.sp.contact[0].telephone_number[1]=<+1>-987654321 +onelogin.saml2.sp.contact[1].contactType=other +onelogin.saml2.sp.contact[1].company=Big Corp +onelogin.saml2.sp.contact[1].email_address=info@example.com + +# Legacy contacts onelogin.saml2.contacts.technical.given_name = T&chnical Guy onelogin.saml2.contacts.technical.email_address = t&chnical@example.com onelogin.saml2.contacts.support.given_name = "Support Guy" From 7735163e63226db3aaab717c4456b3d75d6dad70 Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Fri, 5 Nov 2021 18:12:35 +0100 Subject: [PATCH 14/34] Update microsoft identity/keyvalut dependency --- core/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index a00edff3..1a23fc65 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,13 +72,13 @@ com.azure azure-security-keyvault-keys - 4.3.3 + 4.3.4 true com.azure azure-identity - 1.3.6 + 1.3.7 true @@ -118,7 +118,7 @@ maven-surefire-plugin 2.22.2 - ${project.build.sourceEncoding} + ${project.build.sourceEncoding} ${project.build.sourceEncoding} ${project.build.sourceEncoding} ${jacoco.agent.argLine} -Dfile.encoding=${project.build.sourceEncoding} -Dline.separator=\n From 6900702b216646f0fda46040e200b38c626fa942 Mon Sep 17 00:00:00 2001 From: Mauro Molinari Date: Fri, 5 Nov 2021 18:39:17 +0100 Subject: [PATCH 15/34] Revise SP contacts settings validation The contact type check now becomes useful (and so it was restored), because with the new full Contacts support the user may indeed specify invalid contact types in settings. The "not enough data" check, instead, was fixed and it is now raised only if ALL of the contact data (company, given name, surname, e-mail addresses and phone names) are empty, reflecting the actual SAML 2.0 metadata schema constraint. Fixes #353. --- .../saml2/settings/Saml2Settings.java | 30 +++++++++---------- .../test/settings/Saml2SettingsTest.java | 2 ++ .../config/config.allerrors.properties | 4 ++- .../config/config.sperrors.properties | 4 ++- .../com/onelogin/saml2/test/AuthTest.java | 2 +- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java index 292b75e6..9ee29465 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java @@ -5,8 +5,10 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import com.onelogin.saml2.model.hsm.HSM; @@ -1017,27 +1019,25 @@ public List checkSPSettings() { List contacts = this.getContacts(); if (!contacts.isEmpty()) { -/* - List validTypes = new ArrayList(); - validTypes.add("technical"); - validTypes.add("support"); - validTypes.add("administrative"); - validTypes.add("billing"); - validTypes.add("other"); -*/ + Set validTypes = new HashSet<>(); + validTypes.add(Constants.CONTACT_TYPE_TECHNICAL); + validTypes.add(Constants.CONTACT_TYPE_SUPPORT); + validTypes.add(Constants.CONTACT_TYPE_ADMINISTRATIVE); + validTypes.add(Constants.CONTACT_TYPE_BILLING); + validTypes.add(Constants.CONTACT_TYPE_OTHER); for (Contact contact : contacts) { -/* if (!validTypes.contains(contact.getContactType())) { errorMsg = "contact_type_invalid"; errors.add(errorMsg); LOGGER.error(errorMsg); } -*/ - - if (contact.getEmailAddresses().isEmpty() || contact.getEmailAddresses().stream().allMatch(StringUtils::isEmpty) || - (StringUtils.isEmpty(contact.getCompany()) && - StringUtils.isEmpty(contact.getGivenName()) && - StringUtils.isEmpty(contact.getSurName()))) { + if ((contact.getEmailAddresses().isEmpty() + || contact.getEmailAddresses().stream().allMatch(StringUtils::isEmpty)) + && (contact.getTelephoneNumbers().isEmpty() || contact.getTelephoneNumbers() + .stream().allMatch(StringUtils::isEmpty)) + && StringUtils.isEmpty(contact.getCompany()) + && StringUtils.isEmpty(contact.getGivenName()) + && StringUtils.isEmpty(contact.getSurName())) { errorMsg = "contact_not_enough_data"; errors.add(errorMsg); LOGGER.error(errorMsg); diff --git a/core/src/test/java/com/onelogin/saml2/test/settings/Saml2SettingsTest.java b/core/src/test/java/com/onelogin/saml2/test/settings/Saml2SettingsTest.java index 8a3875da..67bbf84b 100644 --- a/core/src/test/java/com/onelogin/saml2/test/settings/Saml2SettingsTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/settings/Saml2SettingsTest.java @@ -114,6 +114,7 @@ public void testCheckSPSettingsAllErrors() throws IOException, Error { assertThat(settingsErrors, hasItem("sp_entityId_not_found")); assertThat(settingsErrors, hasItem("sp_acs_not_found")); assertThat(settingsErrors, hasItem("sp_cert_not_found_and_required")); + assertThat(settingsErrors, hasItem("contact_type_invalid")); assertThat(settingsErrors, hasItem("contact_not_enough_data")); assertThat(settingsErrors, hasItem("organization_not_enough_data")); } @@ -151,6 +152,7 @@ public void testCheckSettingsAllErrors() throws IOException, Error { assertThat(settingsErrors, hasItem("sp_entityId_not_found")); assertThat(settingsErrors, hasItem("sp_acs_not_found")); assertThat(settingsErrors, hasItem("sp_cert_not_found_and_required")); + assertThat(settingsErrors, hasItem("contact_type_invalid")); assertThat(settingsErrors, hasItem("contact_not_enough_data")); assertThat(settingsErrors, hasItem("organization_not_enough_data")); assertThat(settingsErrors, hasItem("idp_entityId_not_found")); diff --git a/core/src/test/resources/config/config.allerrors.properties b/core/src/test/resources/config/config.allerrors.properties index 1b41f6f0..80f5e1a4 100644 --- a/core/src/test/resources/config/config.allerrors.properties +++ b/core/src/test/resources/config/config.allerrors.properties @@ -19,4 +19,6 @@ onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.url = http://sp.example.com # Contacts -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.sp.contact[0].contactType=administrative +onelogin.saml2.sp.contact[1].contactType=nonexistent +onelogin.saml2.sp.contact[1].company=ACME \ No newline at end of file diff --git a/core/src/test/resources/config/config.sperrors.properties b/core/src/test/resources/config/config.sperrors.properties index 6a1a649f..f80b95d1 100644 --- a/core/src/test/resources/config/config.sperrors.properties +++ b/core/src/test/resources/config/config.sperrors.properties @@ -30,4 +30,6 @@ onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example # Contacts -onelogin.saml2.contacts.support.given_name = Support Guy \ No newline at end of file +onelogin.saml2.sp.contact[0].contactType=administrative +onelogin.saml2.sp.contact[1].contactType=nonexistent +onelogin.saml2.sp.contact[1].company=ACME \ No newline at end of file diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index 6c376839..cd45125f 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -303,7 +303,7 @@ public void testConstructorInvalidSettings() throws IOException, SettingsExcepti Saml2Settings settings = new SettingsBuilder().fromFile("config/config.sperrors.properties").build(); expectedEx.expect(SettingsException.class); - expectedEx.expectMessage("Invalid settings: sp_entityId_not_found, sp_acs_not_found, sp_cert_not_found_and_required, contact_not_enough_data, organization_not_enough_data, idp_cert_or_fingerprint_not_found_and_required, idp_cert_not_found_and_required"); + expectedEx.expectMessage("Invalid settings: sp_entityId_not_found, sp_acs_not_found, sp_cert_not_found_and_required, contact_not_enough_data, contact_type_invalid, organization_not_enough_data, idp_cert_or_fingerprint_not_found_and_required, idp_cert_not_found_and_required"); new Auth(settings, request, response); } From c02eb9fe55888aa10e3ef741dc2756d3e66d3ab2 Mon Sep 17 00:00:00 2001 From: kemalturksonmez <56357795+kemalturksonmez@users.noreply.github.com> Date: Wed, 24 Nov 2021 09:29:25 -0500 Subject: [PATCH 16/34] Update parseXML to use XMLErrorAccumulatorHandler Prevent xerces libraries from outputting to stderr and give users the ability to control logging. --- core/src/main/java/com/onelogin/saml2/util/Util.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/com/onelogin/saml2/util/Util.java b/core/src/main/java/com/onelogin/saml2/util/Util.java index 086e03f9..8a6be158 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Util.java +++ b/core/src/main/java/com/onelogin/saml2/util/Util.java @@ -394,6 +394,8 @@ public static Document parseXML(InputSource inputSource) throws ParserConfigurat } catch (Throwable e) {} DocumentBuilder builder = docfactory.newDocumentBuilder(); + XMLErrorAccumulatorHandler errorAcumulator = new XMLErrorAccumulatorHandler(); + builder.setErrorHandler(errorAcumulator); Document doc = builder.parse(inputSource); // Loop through the doc and tag every element with an ID attribute From f58823780feff1ca6e7d758be9e6af616735e677 Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Wed, 26 Jan 2022 12:19:00 -0500 Subject: [PATCH 17/34] docs: update to use 2.8.0 Signed-off-by: Rui Chen --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index df0c3bf0..d8064572 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,17 @@ Version 2.0.0 - 2.4.0, compatible with java7 / java8. We [introduced some incompatibilities](https://github.com/onelogin/java-saml/issues/90), that could be fixed and make it compatible with java6. -Version 1.1.2 is considered to be deprecated. If you have used it, we strongly recommend that you migrate to the new version. +Version 1.1.2 is considered to be deprecated. If you have used it, we strongly recommend that you migrate to the new version. We rebuilt the toolkit on 2.0.0, so code/settings that you had been using in the previous version will no longer be compatible. ## Why add SAML support to my software? SAML is an XML-based standard for web browser single sign-on and is defined by -the OASIS Security Services Technical Committee. The standard has been around +the OASIS Security Services Technical Committee. The standard has been around since 2002, but lately it has become popular due to its advantages as follows: - * **Usability** - One-click access from portals or intranets, deep linking, + * **Usability** - One-click access from portals or intranets, deep linking, password elimination and automatically renewing sessions make life easier for the user. * **Security** - Based on strong digital signatures for authentication and @@ -40,7 +40,7 @@ since 2002, but lately it has become popular due to its advantages as follows: * **IT Friendly** - SAML simplifies life for IT because it centralizes authentication, provides greater visibility and makes directory integration easier. - * **Opportunity** - B2B cloud vendor should support SAML to facilitate the + * **Opportunity** - B2B cloud vendor should support SAML to facilitate the integration of their product. @@ -75,7 +75,7 @@ In production, the **onelogin.saml2.strict** setting parameter MUST be set as ** In production also we highly recommend to register on the settings the IdP certificate instead of using the fingerprint method. The fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass. Other SAML toolkits deprecated that mechanism, we maintain it for compatibility and also to be used on test environment. -The IdPMetadataParser class does not validate in any way the URL that is introduced in order to be parsed. +The IdPMetadataParser class does not validate in any way the URL that is introduced in order to be parsed. Usually the same administrator that handles the Service Provider also sets the URL to the IdP, which should be a trusted resource. @@ -97,7 +97,7 @@ Install it as a maven dependency: com.onelogin java-saml - 2.6.0 + 2.8.0 ``` @@ -246,12 +246,12 @@ onelogin.saml2.sp.x509cert = # Future SP certificate, to be used during SP Key roll over onelogin.saml2.sp.x509certNew = -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.organization.lang = en @@ -269,7 +269,7 @@ onelogin.saml2.sp.contact[1].contactType=other onelogin.saml2.sp.contact[1].company=Big Corp onelogin.saml2.sp.contact[1].email_address=info@example.com -# Legacy contacts (legacy way to specify just a technical and a support contact with minimal info) +# Legacy contacts (legacy way to specify just a technical and a support contact with minimal info) onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy @@ -284,7 +284,7 @@ onelogin.saml2.idp.entityid = # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = -# SAML protocol binding to be used to deliver the message +# SAML protocol binding to be used to deliver the message # to the IdP. Onelogin Toolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -316,7 +316,7 @@ onelogin.saml2.idp.x509cert = # If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to # let the toolkit know which Algorithm was used. Possible values: sha1, sha256, sha384 or sha512 # 'sha1' is the default value. -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha256 # Security settings @@ -346,7 +346,7 @@ onelogin.saml2.security.want_messages_signed = false onelogin.saml2.security.want_assertions_signed = false # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null (in order to not sign) or true (sign using SP private key) +# Right now supported null (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -394,7 +394,7 @@ onelogin.saml2.security.reject_deprecated_alg = true # SAML specification states that no trimming for string elements should be performed, so no trimming will be # performed by default on extracted Name IDs and attribute values. However, some SAML implementations may add # undesirable surrounding whitespace when outputting XML (possibly due to formatting/pretty-printing). -# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and +# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and # attribute values. onelogin.saml2.parsing.trim_name_ids = false onelogin.saml2.parsing.trim_attribute_values = false @@ -665,7 +665,7 @@ and later executing the redirection manually. ### Extending the provided implementation -All the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRequest`, `LogoutResponse`) can be extended to add or change the processing behavior. +All the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRequest`, `LogoutResponse`) can be extended to add or change the processing behavior. In particular, the classes used to produce outgoing messages (`AuthnRequest`, `LogoutRequest`, and `LogoutResponse`) also provide a `postProcessXml` method that can be overridden to customise the generation of the corresponding SAML message XML, along with the ability to pass in proper extensions of the input parameter classes (`AuthnRequestParams`, `LogoutRequestParams`, and `LogoutResponseParams` respectively). @@ -683,7 +683,7 @@ auth.setSamlMessageFactory(new SamlMessageFactory() { public SamlResponse createSamlResponse(Saml2Settings settings, HttpRequest request) throws Exception { return new SamlResponseEx(settings, request); } -}); +}); // then proceed with login... auth.login(relayState, new AuthnRequestParamsEx()); // the custom generation of AuthnReqeustEx will be executed // ... or process the response as usual @@ -700,12 +700,12 @@ For Apache Tomcat this is done by setting the proxyName, proxyPort, scheme and s ### IdP with multiple certificates - + In some scenarios the IdP uses different certificates for signing/encryption, or is under key rollover phase and more than one certificate is published on IdP metadata. - + In order to handle that the toolkit offers the `onelogin.saml2.idp.x509certMulti` parameters where you can set additional certificates that will be used to validate IdP signature. However just the certificate set in `onelogin.saml2.idp.x509cert` parameter will be used for encrypting. - + ### Replay attacks From bf7671a586f74b23eadb5a59399d63289cc0c56e Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Wed, 26 Jan 2022 12:19:22 -0500 Subject: [PATCH 18/34] docs: add toc Signed-off-by: Rui Chen --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8064572..ffee6d09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OneLogin's SAML Java Toolkit +# OneLogin's SAML Java Toolkit [![Build Status](https://travis-ci.org/onelogin/java-saml.svg?branch=master)](https://travis-ci.org/onelogin/java-saml) [![Coverage Status](https://coveralls.io/repos/github/onelogin/java-saml/badge.svg?branch=master)](https://coveralls.io/github/onelogin/java-saml?branch=master) @@ -20,6 +20,45 @@ We [introduced some incompatibilities](https://github.com/onelogin/java-saml/iss Version 1.1.2 is considered to be deprecated. If you have used it, we strongly recommend that you migrate to the new version. We rebuilt the toolkit on 2.0.0, so code/settings that you had been using in the previous version will no longer be compatible. +- [Why add SAML support to my software?](#why-add-saml-support-to-my-software) +- [General description](#general-description) +- [Security warning](#security-warning) +- [Installation](#installation) + - [Hosting](#hosting) + - [Github](#github) + - [Maven](#maven) + - [Dependencies](#dependencies) +- [Working with the github repository code and Eclipse.](#working-with-the-github-repository-code-and-eclipse) + - [Get the toolkit.](#get-the-toolkit) + - [Adding java-saml toolkit components as a project](#adding-java-saml-toolkit-components-as-a-project) + - [Adding the java-saml-tookit-jspsample as a project](#adding-the-java-saml-tookit-jspsample-as-a-project) + - [Deploy the java-saml-tookit-jspsample](#deploy-the-java-saml-tookit-jspsample) +- [Getting started](#getting-started) + - [Learning the toolkit](#learning-the-toolkit) + - [core (com.onelogin:java-saml-core)](#core-comoneloginjava-saml-core) + - [toolkit (com.onelogin:java-saml)](#toolkit-comoneloginjava-saml) + - [samples (com.onelogin:java-saml-tookit-samples)](#samples-comoneloginjava-saml-tookit-samples) + - [How it works](#how-it-works) + - [Javadocs](#javadocs) + - [Settings](#settings) + - [Properties File](#properties-file) + - [KeyStores](#keystores) + - [Dynamic Settings](#dynamic-settings) + - [The HttpRequest](#the-httprequest) + - [Initiate SSO](#initiate-sso) + - [The SP Endpoints](#the-sp-endpoints) + - [SP Metadata](#sp-metadata) + - [Attribute Consumer Service(ACS)](#attribute-consumer-serviceacs) + - [Single Logout Service (SLS)](#single-logout-service-sls) + - [Initiate SLO](#initiate-slo) + - [Extending the provided implementation](#extending-the-provided-implementation) + - [Working behind load balancer](#working-behind-load-balancer) + - [IdP with multiple certificates](#idp-with-multiple-certificates) + - [Replay attacks](#replay-attacks) +- [Demo included in the toolkit](#demo-included-in-the-toolkit) + - [SP setup](#sp-setup) + - [IdP setup](#idp-setup) + - [How it works](#how-it-works-1) ## Why add SAML support to my software? From 4f4340cabe68bbdfd93d80f869b6ed200cd9afae Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 1 Feb 2022 17:34:45 +0100 Subject: [PATCH 19/34] Update dependencies --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f18ede37..beeef0c0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,9 +12,9 @@ UTF-8 UTF-8 - 1.7.32 + 1.7.35 4.13.2 - 1.2.6 + 1.2.10 3.12.0 From a8957cc6dda55f2b5f13c7650c790754ccb8c7e6 Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 1 Feb 2022 18:10:19 +0100 Subject: [PATCH 20/34] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffee6d09..025a7054 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Install it as a maven dependency: com.onelogin java-saml - 2.8.0 + 2.9.0 ``` From 988de2deb4f016c214e84e3c6a36e53fbb1dca45 Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 1 Feb 2022 18:14:50 +0100 Subject: [PATCH 21/34] [maven-release-plugin] prepare release v2.9.0 --- core/pom.xml | 2 +- pom.xml | 4 ++-- samples/java-saml-tookit-jspsample/pom.xml | 2 +- samples/pom.xml | 2 +- toolkit/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1a23fc65..858d4905 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.1-SNAPSHOT + 2.9.0 jar diff --git a/pom.xml b/pom.xml index beeef0c0..9a758a02 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.onelogin java-saml-toolkit - 2.8.1-SNAPSHOT + 2.9.0 pom OneLogin java-saml Toolkit Project @@ -157,7 +157,7 @@ scm:git:git@github.com:onelogin/java-saml.git scm:git:git@github.com:onelogin/java-saml.git https://github.com/onelogin/java-saml - HEAD + v2.9.0 diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index 9c6185e3..8d436f3a 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-tookit-samples - 2.8.1-SNAPSHOT + 2.9.0 java-saml-tookit-jspsample diff --git a/samples/pom.xml b/samples/pom.xml index 470d0048..00f7e1e2 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.1-SNAPSHOT + 2.9.0 java-saml-tookit-samples diff --git a/toolkit/pom.xml b/toolkit/pom.xml index e517b4de..52e785d3 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.8.1-SNAPSHOT + 2.9.0 jar From eeaf06e661828909784fe2c22bec21a2a06f757d Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Tue, 1 Feb 2022 18:14:55 +0100 Subject: [PATCH 22/34] [maven-release-plugin] prepare for next development iteration --- core/pom.xml | 2 +- pom.xml | 4 ++-- samples/java-saml-tookit-jspsample/pom.xml | 2 +- samples/pom.xml | 2 +- toolkit/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 858d4905..1ffe1f1b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.0 + 2.9.1-SNAPSHOT jar diff --git a/pom.xml b/pom.xml index 9a758a02..1e4cabea 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.onelogin java-saml-toolkit - 2.9.0 + 2.9.1-SNAPSHOT pom OneLogin java-saml Toolkit Project @@ -157,7 +157,7 @@ scm:git:git@github.com:onelogin/java-saml.git scm:git:git@github.com:onelogin/java-saml.git https://github.com/onelogin/java-saml - v2.9.0 + HEAD diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index 8d436f3a..13afeb5b 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-tookit-samples - 2.9.0 + 2.9.1-SNAPSHOT java-saml-tookit-jspsample diff --git a/samples/pom.xml b/samples/pom.xml index 00f7e1e2..799ec247 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.0 + 2.9.1-SNAPSHOT java-saml-tookit-samples diff --git a/toolkit/pom.xml b/toolkit/pom.xml index 52e785d3..47e8b5d2 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -3,7 +3,7 @@ com.onelogin java-saml-toolkit - 2.9.0 + 2.9.1-SNAPSHOT jar From c5104400509db30aa0ff4296cba7cdca02807189 Mon Sep 17 00:00:00 2001 From: Haavar Valeur Date: Mon, 7 Feb 2022 12:40:53 -0800 Subject: [PATCH 23/34] Updated org.apache.santuario:xmlsec to version 2.3.0 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 1ffe1f1b..92baa25e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -60,7 +60,7 @@ org.apache.santuario xmlsec - 2.2.3 + 2.3.0 commons-codec From aaf19433d5eb77fd76116ae70ced8e77291b86ee Mon Sep 17 00:00:00 2001 From: luozhouyang Date: Sun, 17 Apr 2022 17:30:15 +0800 Subject: [PATCH 24/34] Fixed README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 025a7054..b36c7acb 100644 --- a/README.md +++ b/README.md @@ -649,6 +649,7 @@ If we don't want that processSLO to destroy the session, pass the keepLocalSessi #### Initiate SLO In order to send a Logout Request to the IdP: + ```java Auth auth = new Auth(request, response); @@ -673,12 +674,14 @@ if (session.getAttribute("sessionIndex") != null) { sessionIndex = session.getAttribute("sessionIndex").toString(); } auth.logout(null, new LogoutRequestParams(sessionIndex, nameId, nameIdFormat)); -```java +``` + The Logout Request will be sent signed or unsigned based on the security settings 'onelogin.saml2.security.logoutrequest_signed' The IdP will return the Logout Response through the user's client to the Single Logout Service of the SP. We can set a 'RelayState' parameter containing a return url to the login function: + ```java String returnUrl = 'https://example.com'; auth.logout(relayState=returnUrl) From ad84787f20ec931819917aa65356b5c73965a4a3 Mon Sep 17 00:00:00 2001 From: Bryan Vestey Date: Fri, 12 Aug 2022 09:51:55 -0700 Subject: [PATCH 25/34] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 025a7054..4dc9f0c9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![Build Status](https://travis-ci.org/onelogin/java-saml.svg?branch=master)](https://travis-ci.org/onelogin/java-saml) [![Coverage Status](https://coveralls.io/repos/github/onelogin/java-saml/badge.svg?branch=master)](https://coveralls.io/github/onelogin/java-saml?branch=master) +## **Notice:** This project is currently not under active development, please see [#388](https://github.com/onelogin/java-saml/issues/388) for more information. + Add SAML support to your Java applications using this library. Forget those complicated libraries and use that open source library provided and supported by OneLogin Inc. From 591c358d829c1bb88b409f1b033801f78402df0a Mon Sep 17 00:00:00 2001 From: Takayuki Maruyama Date: Mon, 17 Jan 2022 23:38:12 +0000 Subject: [PATCH 26/34] Use java.time instead of joda-time fix #201 --- core/pom.xml | 7 - .../onelogin/saml2/authn/SamlResponse.java | 40 ++--- .../onelogin/saml2/logout/LogoutRequest.java | 8 +- .../onelogin/saml2/logout/LogoutResponse.java | 2 +- .../java/com/onelogin/saml2/util/Util.java | 137 +++++++++++------- .../saml2/test/authn/AuthnResponseTest.java | 32 ++-- .../onelogin/saml2/test/util/UtilsTest.java | 17 ++- .../saml2/util/DateTimeTestUtils.java | 24 +++ toolkit/pom.xml | 7 - .../main/java/com/onelogin/saml2/Auth.java | 7 +- .../com/onelogin/saml2/test/AuthTest.java | 6 +- 11 files changed, 160 insertions(+), 127 deletions(-) create mode 100644 core/src/test/java/com/onelogin/saml2/util/DateTimeTestUtils.java diff --git a/core/pom.xml b/core/pom.xml index 92baa25e..123ec966 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -44,13 +44,6 @@ true - - - joda-time - joda-time - 2.10.6 - - org.apache.commons diff --git a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java index 8fc66d8a..a7996096 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java +++ b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java @@ -3,6 +3,8 @@ import java.io.IOException; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -16,8 +18,6 @@ import com.onelogin.saml2.model.hsm.HSM; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.Instant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -297,10 +297,10 @@ public boolean isValid(String requestId) { } // Check the session Expiration - DateTime sessionExpiration = this.getSessionNotOnOrAfter(); + Instant sessionExpiration = this.getSessionNotOnOrAfter(); if (sessionExpiration != null) { - sessionExpiration = sessionExpiration.plus(Constants.ALOWED_CLOCK_DRIFT * 1000); - if (sessionExpiration.isEqualNow() || sessionExpiration.isBeforeNow()) { + sessionExpiration = ChronoUnit.SECONDS.addTo(sessionExpiration, Constants.ALOWED_CLOCK_DRIFT); + if (Util.isEqualNow(sessionExpiration) || Util.isBeforeNow(sessionExpiration)) { throw new ValidationError("The attributes have expired, based on the SessionNotOnOrAfter of the AttributeStatement of this Response", ValidationError.SESSION_EXPIRED); } } @@ -401,18 +401,18 @@ private void validateSubjectConfirmation(String responseInResponseTo) throws XPa continue; } - DateTime noa = Util.parseDateTime(notOnOrAfter.getNodeValue()); - noa = noa.plus(Constants.ALOWED_CLOCK_DRIFT * 1000); - if (noa.isEqualNow() || noa.isBeforeNow()) { + Instant noa = Util.parseDateTime(notOnOrAfter.getNodeValue()); + noa = ChronoUnit.SECONDS.addTo(noa, Constants.ALOWED_CLOCK_DRIFT); + if (Util.isEqualNow(noa) || Util.isBeforeNow(noa)) { validationIssues.add(new SubjectConfirmationIssue(i, "SubjectConfirmationData is no longer valid")); continue; } Node notBefore = subjectConfirmationDataNodes.item(c).getAttributes().getNamedItem("NotBefore"); if (notBefore != null) { - DateTime nb = Util.parseDateTime(notBefore.getNodeValue()); - nb = nb.minus(Constants.ALOWED_CLOCK_DRIFT * 1000); - if (nb.isAfterNow()) { + Instant nb = Util.parseDateTime(notBefore.getNodeValue()); + nb = ChronoUnit.SECONDS.addTo(nb, Constants.ALOWED_CLOCK_DRIFT * -1); + if (Util.isAfterNow(nb)) { validationIssues.add(new SubjectConfirmationIssue(i, "SubjectConfirmationData is not yet valid")); continue; } @@ -829,7 +829,7 @@ public List getIssuers() throws XPathExpressionException, ValidationErro * * @throws XPathExpressionException */ - public DateTime getSessionNotOnOrAfter() throws XPathExpressionException { + public Instant getSessionNotOnOrAfter() throws XPathExpressionException { String notOnOrAfter = null; NodeList entries = this.queryAssertion("/saml:AuthnStatement[@SessionNotOnOrAfter]"); if (entries.getLength() > 0) { @@ -889,7 +889,7 @@ public List getAssertionNotOnOrAfter() throws XPathExpressionException for (int i = 0; i < notOnOrAfterNodes.getLength(); i++) { final Node notOnOrAfterAttribute = notOnOrAfterNodes.item(i).getAttributes().getNamedItem("NotOnOrAfter"); if (notOnOrAfterAttribute != null) { - notOnOrAfters.add(new Instant(notOnOrAfterAttribute.getNodeValue())); + notOnOrAfters.add(Instant.parse(notOnOrAfterAttribute.getNodeValue())); }} return notOnOrAfters; } @@ -1053,17 +1053,17 @@ public boolean validateTimestamps() throws ValidationError { Node naAttribute = attrName.getNamedItem("NotOnOrAfter"); // validate NotOnOrAfter if (naAttribute != null) { - DateTime notOnOrAfterDate = Util.parseDateTime(naAttribute.getNodeValue()); - notOnOrAfterDate = notOnOrAfterDate.plus(Constants.ALOWED_CLOCK_DRIFT * 1000); - if (notOnOrAfterDate.isEqualNow() || notOnOrAfterDate.isBeforeNow()) { + Instant notOnOrAfterDate = Util.parseDateTime(naAttribute.getNodeValue()); + notOnOrAfterDate = ChronoUnit.SECONDS.addTo(notOnOrAfterDate, Constants.ALOWED_CLOCK_DRIFT); + if (Util.isEqualNow(notOnOrAfterDate) || Util.isBeforeNow(notOnOrAfterDate)) { throw new ValidationError("Could not validate timestamp: expired. Check system clock.", ValidationError.ASSERTION_EXPIRED); } } // validate NotBefore if (nbAttribute != null) { - DateTime notBeforeDate = Util.parseDateTime(nbAttribute.getNodeValue()); - notBeforeDate = notBeforeDate.minus(Constants.ALOWED_CLOCK_DRIFT * 1000); - if (notBeforeDate.isAfterNow()) { + Instant notBeforeDate = Util.parseDateTime(nbAttribute.getNodeValue()); + notBeforeDate = ChronoUnit.SECONDS.addTo(notBeforeDate, Constants.ALOWED_CLOCK_DRIFT * -1); + if (Util.isAfterNow(notBeforeDate)) { throw new ValidationError("Could not validate timestamp: not yet valid. Check system clock.", ValidationError.ASSERTION_TOO_EARLY); } } @@ -1341,7 +1341,7 @@ public Calendar getResponseIssueInstant() throws ValidationError { return null; final Calendar result = Calendar.getInstance(); try { - result.setTimeInMillis(Util.parseDateTime(issueInstantString).getMillis()); + result.setTimeInMillis(Util.parseDateTime(issueInstantString).toEpochMilli()); } catch (final IllegalArgumentException e) { throw new ValidationError( "The Response IssueInstant attribute is not in the expected UTC form of ISO-8601 format", diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java index cacd7bf8..903cd2db 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java @@ -4,6 +4,7 @@ import java.net.URL; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.time.Instant; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -13,7 +14,6 @@ import javax.xml.xpath.XPathExpressionException; import org.apache.commons.lang3.text.StrSubstitutor; -import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -446,8 +446,8 @@ public Boolean isValid() { // Check NotOnOrAfter if (rootElement.hasAttribute("NotOnOrAfter")) { String notOnOrAfter = rootElement.getAttribute("NotOnOrAfter"); - DateTime notOnOrAfterDate = Util.parseDateTime(notOnOrAfter); - if (notOnOrAfterDate.isEqualNow() || notOnOrAfterDate.isBeforeNow()) { + Instant notOnOrAfterDate = Util.parseDateTime(notOnOrAfter); + if (Util.isEqualNow(notOnOrAfterDate) || Util.isBeforeNow(notOnOrAfterDate)) { throw new ValidationError("Could not validate timestamp: expired. Check system clock.", ValidationError.RESPONSE_EXPIRED); } } @@ -571,7 +571,7 @@ public static Calendar getIssueInstant(Document samlLogoutRequestDocument) { if(issueInstantString == null) return null; issueInstant = Calendar.getInstance(); - issueInstant.setTimeInMillis(Util.parseDateTime(issueInstantString).getMillis()); + issueInstant.setTimeInMillis(Util.parseDateTime(issueInstantString).toEpochMilli()); } catch (Exception e) {} return issueInstant; } diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java index 7199fae9..4eebfd74 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java @@ -611,7 +611,7 @@ public Calendar getIssueInstant() throws ValidationError { return null; final Calendar result = Calendar.getInstance(); try { - result.setTimeInMillis(Util.parseDateTime(issueInstantString).getMillis()); + result.setTimeInMillis(Util.parseDateTime(issueInstantString).toEpochMilli()); } catch (final IllegalArgumentException e) { throw new ValidationError( "The Response IssueInstant attribute is not in the expected UTC form of ISO-8601 format", diff --git a/core/src/main/java/com/onelogin/saml2/util/Util.java b/core/src/main/java/com/onelogin/saml2/util/Util.java index 8a6be158..91249e8b 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Util.java +++ b/core/src/main/java/com/onelogin/saml2/util/Util.java @@ -27,13 +27,22 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.Period; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; @@ -75,13 +84,6 @@ import org.apache.xml.security.signature.XMLSignature; import org.apache.xml.security.transforms.Transforms; import org.apache.xml.security.utils.XMLUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Period; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; -import org.joda.time.format.ISOPeriodFormat; -import org.joda.time.format.PeriodFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; @@ -110,8 +112,7 @@ public final class Util { */ private static final Logger LOGGER = LoggerFactory.getLogger(Util.class); - private static final DateTimeFormatter DATE_TIME_FORMAT = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC(); - private static final DateTimeFormatter DATE_TIME_FORMAT_MILLS = ISODateTimeFormat.dateTime().withZoneUTC(); + private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneOffset.UTC); public static final String UNIQUE_ID_PREFIX = "ONELOGIN_"; public static final String RESPONSE_SIGNATURE_XPATH = "/samlp:Response/ds:Signature"; public static final String ASSERTION_SIGNATURE_XPATH = "/samlp:Response/saml:Assertion/ds:Signature"; @@ -1826,10 +1827,10 @@ public static String generateUniqueID() { * * @return int The new timestamp, after the duration is applied. * - * @throws IllegalArgumentException + * @throws DateTimeParseException */ - public static long parseDuration(String duration) throws IllegalArgumentException { - TimeZone timeZone = DateTimeZone.UTC.toTimeZone(); + public static long parseDuration(String duration) throws DateTimeParseException { + TimeZone timeZone = TimeZone.getTimeZone(ZoneOffset.UTC); return parseDuration(duration, Calendar.getInstance(timeZone).getTimeInMillis() / 1000); } @@ -1843,9 +1844,9 @@ public static long parseDuration(String duration) throws IllegalArgumentExceptio * * @return the new timestamp, after the duration is applied In Seconds. * - * @throws IllegalArgumentException + * @throwsa DateTimeParseException */ - public static long parseDuration(String durationString, long timestamp) throws IllegalArgumentException { + public static long parseDuration(String durationString, long timestamp) throws DateTimeParseException { boolean haveMinus = false; if (durationString.startsWith("-")) { @@ -1853,26 +1854,30 @@ public static long parseDuration(String durationString, long timestamp) throws I haveMinus = true; } - PeriodFormatter periodFormatter = ISOPeriodFormat.standard().withLocale(new Locale("UTC")); - Period period = periodFormatter.parsePeriod(durationString); + TemporalAmount amount; + if (durationString.startsWith("PT")) { + amount = Duration.parse(durationString); + } else { + amount = Period.parse(durationString); + } - DateTime dt = new DateTime(timestamp * 1000, DateTimeZone.UTC); + ZonedDateTime dt = Instant.ofEpochSecond(timestamp).atZone(ZoneOffset.UTC); - DateTime result = null; + ZonedDateTime result; if (haveMinus) { - result = dt.minus(period); + result = dt.minus(amount); } else { - result = dt.plus(period); + result = dt.plus(amount); } - return result.getMillis() / 1000; + return result.toEpochSecond(); } /** * @return the unix timestamp that matches the current time. */ public static Long getCurrentTimeStamp() { - DateTime currentDate = new DateTime(DateTimeZone.UTC); - return currentDate.getMillis() / 1000; + ZonedDateTime currentDate = ZonedDateTime.now(clock); + return currentDate.toEpochSecond(); } /** @@ -1893,8 +1898,8 @@ public static long getExpireTime(String cacheDuration, String validUntil) { } if (validUntil != null && !StringUtils.isEmpty(validUntil)) { - DateTime dt = Util.parseDateTime(validUntil); - long validUntilTimeInt = dt.getMillis() / 1000; + Instant dt = Util.parseDateTime(validUntil); + long validUntilTimeInt = dt.toEpochMilli() / 1000; if (expireTime == 0 || expireTime > validUntilTimeInt) { expireTime = validUntilTimeInt; } @@ -1940,25 +1945,7 @@ public static long getExpireTime(String cacheDuration, long validUntil) { * @return string with format yyyy-MM-ddTHH:mm:ssZ */ public static String formatDateTime(long timeInMillis) { - return DATE_TIME_FORMAT.print(timeInMillis); - } - - /** - * Create string form time In Millis with format yyyy-MM-ddTHH:mm:ssZ - * - * @param time - * The time - * @param millis - * Defines if the time is in Millis - * - * @return string with format yyyy-MM-ddTHH:mm:ssZ - */ - public static String formatDateTime(long time, boolean millis) { - if (millis) { - return DATE_TIME_FORMAT_MILLS.print(time); - } else { - return formatDateTime(time); - } + return DATE_TIME_FORMAT.format(Instant.ofEpochMilli(timeInMillis)); } /** @@ -1969,15 +1956,9 @@ public static String formatDateTime(long time, boolean millis) { * * @return datetime */ - public static DateTime parseDateTime(String dateTime) { - - DateTime parsedData = null; - try { - parsedData = DATE_TIME_FORMAT.parseDateTime(dateTime); - } catch(Exception e) { - return DATE_TIME_FORMAT_MILLS.parseDateTime(dateTime); - } - return parsedData; + public static Instant parseDateTime(String dateTime) { + TemporalAccessor parsedData = DATE_TIME_FORMAT.parse(dateTime); + return Instant.from(parsedData); } /** @@ -2007,5 +1988,53 @@ private static byte[] toBytesUtf8(String str) { } } + private static Clock clock = Clock.systemUTC(); + + /** + * Get current timestamp milliseconds. + * + * @return current timestamp + */ + public static long getCurrentTimeMillis() { + return clock.millis(); + } + + static void setFixedClock(Clock fixClock) { + clock = fixClock; + } + + static void setSystemClock() { + clock = Clock.systemUTC(); + } + + /** + * Checks if specified instant is equal to now. + * + * @param instant the instant to compare to + * @return true if instant is equal to now + */ + public static boolean isEqualNow(Instant instant) { + return instant.equals(Instant.now(clock)); + } + + /** + * Checks if specified instant is before now. + * + * @param instant the instant to compare to + * @return true if instant is before now + */ + public static boolean isBeforeNow(Instant instant) { + return instant.isBefore(Instant.now(clock)); + } + + /** + * Checks if specified instant is after now. + * + * @param instant the instant to compare to + * @return true if instant is before now + */ + public static boolean isAfterNow(Instant instant) { + return instant.isAfter(Instant.now(clock)); + } } diff --git a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java index 3d960ca7..7cec9efa 100644 --- a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java @@ -10,13 +10,10 @@ import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; import com.onelogin.saml2.util.Constants; +import com.onelogin.saml2.util.DateTimeTestUtils; import com.onelogin.saml2.util.Util; import org.hamcrest.Matchers; -import org.joda.time.DateTime; -import org.joda.time.DateTimeUtils; -import org.joda.time.Instant; -import org.joda.time.format.ISODateTimeFormat; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -28,6 +25,7 @@ import org.xml.sax.SAXException; import java.io.IOException; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -61,13 +59,13 @@ public class AuthnResponseTest { @Before public void setDateTime() { - //All calls to Joda time check will use this timestamp as "now" value : - setDateTime("2020-06-01T00:00:00Z"); + //All calls to time check will use this timestamp as "now" value : + DateTimeTestUtils.setFixedDateTime("2020-06-01T00:00:00Z"); } @After public void goBackToNormal() { - DateTimeUtils.setCurrentMillisSystem(); + DateTimeTestUtils.setCurrentMillisSystem(); } /** @@ -1157,7 +1155,7 @@ public void testGetAssertionDetails() throws IOException, Error, XPathExpression final List notOnOrAfters = samlResponse.getAssertionNotOnOrAfter(); assertEquals("pfxa46574df-b3b0-a06a-23c8-636413198772", samlResponse.getAssertionId()); - assertThat(notOnOrAfters, contains(new Instant("2010-11-18T22:02:37Z"))); + assertThat(notOnOrAfters, contains(Instant.parse("2010-11-18T22:02:37Z"))); } @@ -1170,7 +1168,7 @@ public void testGetAssertionDetails_encrypted() throws IOException, Error, XPath final List notOnOrAfters = samlResponse.getAssertionNotOnOrAfter(); assertEquals("_519c2712648ee09a06d1f9a08e9e835715fea60267", samlResponse.getAssertionId()); - assertThat(notOnOrAfters, contains(new Instant("2055-06-07T20:17:08Z"))); + assertThat(notOnOrAfters, contains(Instant.parse("2055-06-07T20:17:08Z"))); } @@ -1187,7 +1185,7 @@ public void testGetAssertionDetails_multiple() throws Exception { final List notOnOrAfters = samlResponse.getAssertionNotOnOrAfter(); assertEquals("pfx7841991c-c73f-4035-e2ee-c170c0e1d3e4", samlResponse.getAssertionId()); - assertThat(notOnOrAfters, contains(new Instant("2120-06-17T14:53:44Z"), new Instant("2010-06-17T14:53:44Z"))); + assertThat(notOnOrAfters, contains(Instant.parse("2120-06-17T14:53:44Z"), Instant.parse("2010-06-17T14:53:44Z"))); } /** @@ -1449,7 +1447,7 @@ public void testGetSessionNotOnOrAfter() throws IOException, Error, XPathExpress Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build(); String samlResponseEncoded = Util.getFileAsString("data/responses/response1.xml.base64"); SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); - assertEquals(1290203857000L, samlResponse.getSessionNotOnOrAfter().getMillis()); + assertEquals(1290203857000L, samlResponse.getSessionNotOnOrAfter().toEpochMilli()); samlResponseEncoded = Util.getFileAsString("data/responses/response2.xml.base64"); samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); @@ -1457,7 +1455,7 @@ public void testGetSessionNotOnOrAfter() throws IOException, Error, XPathExpress samlResponseEncoded = Util.getFileAsString("data/responses/valid_encrypted_assertion.xml.base64"); samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); - assertEquals(2696012228000L, samlResponse.getSessionNotOnOrAfter().getMillis()); + assertEquals(2696012228000L, samlResponse.getSessionNotOnOrAfter().toEpochMilli()); } /** @@ -2310,17 +2308,17 @@ public void testParseAzureB2CTimestamp() throws IOException, Error, XPathExpress assertEquals("No Signature found. SAML Response rejected", samlResponse.getError()); settings.setStrict(true); - setDateTime("2020-07-16T07:57:00Z"); + DateTimeTestUtils.setFixedDateTime("2020-07-16T07:57:00Z"); samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); assertFalse(samlResponse.isValid()); assertEquals("A valid SubjectConfirmation was not found on this Response: SubjectConfirmationData doesn't match a valid Recipient", samlResponse.getError()); - setDateTime("2020-07-01T00:00:00Z"); + DateTimeTestUtils.setFixedDateTime("2020-07-01T00:00:00Z"); samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); assertFalse(samlResponse.isValid()); assertEquals("Could not validate timestamp: not yet valid. Check system clock.", samlResponse.getError()); - setDateTime("2020-08-01T00:00:00Z"); + DateTimeTestUtils.setFixedDateTime("2020-08-01T00:00:00Z"); samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded)); assertFalse(samlResponse.isValid()); assertEquals("Could not validate timestamp: expired. Check system clock.", samlResponse.getError()); @@ -3333,9 +3331,5 @@ private static HttpRequest newHttpRequest(String requestURL, String samlResponse return new HttpRequest(requestURL, (String)null).addParameter("SAMLResponse", samlResponseEncoded); } - private void setDateTime(String ISOTimeStamp) { - DateTime dateTime = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC().parseDateTime(ISOTimeStamp); - DateTimeUtils.setCurrentMillisFixed(dateTime.toDate().getTime()); - } } diff --git a/core/src/test/java/com/onelogin/saml2/test/util/UtilsTest.java b/core/src/test/java/com/onelogin/saml2/test/util/UtilsTest.java index 2b047bc1..13012543 100644 --- a/core/src/test/java/com/onelogin/saml2/test/util/UtilsTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/util/UtilsTest.java @@ -31,6 +31,8 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; +import java.time.Instant; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -41,7 +43,6 @@ import org.apache.commons.codec.binary.Base64; import org.apache.xml.security.exceptions.XMLSecurityException; import org.apache.xml.security.signature.XMLSignatureException; -import org.joda.time.DateTime; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -1947,7 +1948,7 @@ public void testGenerateUniqueID_usesDefaultOnEmpty() { * * @see com.onelogin.saml2.util.Util#parseDuration */ - @Test(expected=IllegalArgumentException.class) + @Test(expected=DateTimeParseException.class) public void testParseDurationException() throws Exception { long timestamp = 1393876825L;// 2014-03-03 21:00:25 long parsedDuration = Util.parseDuration("aaa", timestamp); @@ -1982,8 +1983,8 @@ public void testParseDuration() throws Exception { try { String invalidDuration = "PT1Y"; Util.parseDuration(invalidDuration); - } catch (IllegalArgumentException anIllegalArgumentException) { - assertThat(anIllegalArgumentException.getMessage(), is("Invalid format: \"PT1Y\" is malformed at \"1Y\"")); + } catch (DateTimeParseException anDateTimeParseException) { + assertThat(anDateTimeParseException.getMessage(), is("Text cannot be parsed to a Duration")); } } @@ -2057,13 +2058,13 @@ public void testFormatDateTime() { public void testParseDateTime() { long time = 1386650371L; String datetime = "2013-12-10T04:39:31Z"; - DateTime parsedTime = Util.parseDateTime(datetime); - assertEquals(time, parsedTime.getMillis() / 1000); + Instant parsedTime = Util.parseDateTime(datetime); + assertEquals(time, parsedTime.toEpochMilli() / 1000); // Now test if toolkit supports miliseconds String datetime2 = "2013-12-10T04:39:31.120Z"; - DateTime parsedTime2 = Util.parseDateTime(datetime2); - assertEquals(time, parsedTime2.getMillis() / 1000); + Instant parsedTime2 = Util.parseDateTime(datetime2); + assertEquals(time, parsedTime2.toEpochMilli() / 1000); } /** diff --git a/core/src/test/java/com/onelogin/saml2/util/DateTimeTestUtils.java b/core/src/test/java/com/onelogin/saml2/util/DateTimeTestUtils.java new file mode 100644 index 00000000..0321fb3e --- /dev/null +++ b/core/src/test/java/com/onelogin/saml2/util/DateTimeTestUtils.java @@ -0,0 +1,24 @@ +package com.onelogin.saml2.util; + +import java.time.Clock; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +public class DateTimeTestUtils { + + /** + * Use system clock as "now". + */ + public static void setCurrentMillisSystem() { + Util.setSystemClock(); + } + + /** + * Use provided dateTime as "now". + * + * @param dateTime the timestamp + */ + public static void setFixedDateTime(String dateTime) { + Util.setFixedClock(Clock.fixed(ZonedDateTime.parse(dateTime).toInstant(), ZoneOffset.UTC)); + } +} diff --git a/toolkit/pom.xml b/toolkit/pom.xml index 47e8b5d2..a57711bc 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -65,13 +65,6 @@ provided - - - joda-time - joda-time - 2.10.6 - - org.apache.commons diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index 511914b8..0126ec35 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -5,6 +5,7 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.SignatureException; +import java.time.Instant; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -17,8 +18,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.Instant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,7 +99,7 @@ public class Auth { /** * SessionNotOnOrAfter. When the user is logged, this stored it from the AuthnStatement of the SAML Response */ - private DateTime sessionExpiration; + private Instant sessionExpiration; /** * The ID of the last message processed @@ -1453,7 +1452,7 @@ public final String getSessionIndex() { /** * @return the SessionNotOnOrAfter of the assertion */ - public final DateTime getSessionExpiration() { + public final Instant getSessionExpiration() { return sessionExpiration; } diff --git a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java index cd45125f..53c82ef5 100644 --- a/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java +++ b/toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java @@ -30,6 +30,7 @@ import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -40,7 +41,6 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.joda.time.Instant; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -1244,7 +1244,7 @@ public void testGetAssertionDetails() throws Exception { auth.processResponse(); assertThat(auth.getLastAssertionId(), is("pfxb26bb203-4e9d-8e74-a46e-def275ff4c7b")); - assertThat(auth.getLastAssertionNotOnOrAfter(), contains(new Instant("2053-08-23T06:57:01Z"))); + assertThat(auth.getLastAssertionNotOnOrAfter(), contains(Instant.parse("2053-08-23T06:57:01Z"))); } /** @@ -1275,7 +1275,7 @@ public void testGetSessionExpiration() throws Exception { assertNull(auth2.getSessionExpiration()); auth2.processResponse(); assertTrue(auth2.isAuthenticated()); - assertEquals(2639545021000L, auth2.getSessionExpiration().getMillis()); + assertEquals(2639545021000L, auth2.getSessionExpiration().toEpochMilli()); } /** From 009ff694754f19426fb77760de2687f5826ccf9b Mon Sep 17 00:00:00 2001 From: Takayuki Maruyama Date: Wed, 21 Sep 2022 14:55:41 +0000 Subject: [PATCH 27/34] fix typo --- core/src/main/java/com/onelogin/saml2/util/Util.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/onelogin/saml2/util/Util.java b/core/src/main/java/com/onelogin/saml2/util/Util.java index 91249e8b..0502e10f 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Util.java +++ b/core/src/main/java/com/onelogin/saml2/util/Util.java @@ -1844,7 +1844,7 @@ public static long parseDuration(String duration) throws DateTimeParseException * * @return the new timestamp, after the duration is applied In Seconds. * - * @throwsa DateTimeParseException + * @throws DateTimeParseException */ public static long parseDuration(String durationString, long timestamp) throws DateTimeParseException { boolean haveMinus = false; From baee4e0a0c6ab6411034d2413e837f4403f1a11f Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 14:37:38 -0800 Subject: [PATCH 28/34] Remove references to onelogin support. --- README.md | 20 ++-- core/pom.xml | 2 +- .../onelogin/saml2/authn/AuthnRequest.java | 30 +++--- .../onelogin/saml2/authn/SamlResponse.java | 10 +- .../saml2/exception/SAMLException.java | 10 +- .../onelogin/saml2/logout/LogoutRequest.java | 92 +++++++++---------- .../onelogin/saml2/logout/LogoutResponse.java | 34 +++---- .../model/AttributeConsumingService.java | 10 +- .../com/onelogin/saml2/model/Contact.java | 16 ++-- .../saml2/model/KeyStoreSettings.java | 6 +- .../onelogin/saml2/model/Organization.java | 16 ++-- .../saml2/model/RequestedAttribute.java | 16 ++-- .../saml2/model/SamlResponseStatus.java | 14 +-- .../saml2/settings/IdPMetadataParser.java | 40 ++++---- .../com/onelogin/saml2/settings/Metadata.java | 6 +- .../saml2/settings/Saml2Settings.java | 62 ++++++------- .../saml2/settings/SettingsBuilder.java | 70 +++++++------- .../com/onelogin/saml2/util/Constants.java | 20 ++-- .../onelogin/saml2/util/SchemaFactory.java | 10 +- .../java/com/onelogin/saml2/util/Util.java | 10 +- .../resources/config/config.adfs.properties | 16 ++-- .../resources/config/config.all.properties | 18 ++-- .../config/config.all_specialchars.properties | 16 ++-- .../config.allowduplicatednames.properties | 18 ++-- .../config/config.certfile.properties | 20 ++-- .../config/config.certstring.properties | 18 ++-- .../config/config.different.properties | 18 ++-- .../config/config.invalidcontacts.properties | 16 ++-- .../config.invalidspcertstring.properties | 16 ++-- .../config.knownIdpPrivateKey.properties | 12 +-- .../resources/config/config.my.properties | 18 ++-- .../config/config.mywithmulticert.properties | 18 ++-- .../config/config.mywithnocert.properties | 18 ++-- .../config/config.newattack.properties | 20 ++-- .../config/config.newattack2.properties | 20 ++-- .../config/config.samecerts.properties | 18 ++-- .../config/config.somevaluesempty.properties | 18 ++-- pom.xml | 14 +-- samples/java-saml-tookit-jspsample/pom.xml | 2 +- .../main/resources/onelogin.saml.properties | 22 ++--- .../src/main/webapp/acs.jsp | 20 ++-- .../src/main/webapp/attrs.jsp | 18 ++-- .../src/main/webapp/index.jsp | 4 +- .../src/main/webapp/sls.jsp | 12 +-- samples/pom.xml | 2 +- toolkit/pom.xml | 2 +- .../main/java/com/onelogin/saml2/Auth.java | 40 ++++---- .../onelogin/saml2/servlet/ServletUtils.java | 8 +- 48 files changed, 466 insertions(+), 470 deletions(-) diff --git a/README.md b/README.md index 4dc9f0c9..009fac58 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ -# OneLogin's SAML Java Toolkit +# SAML Java Toolkit [![Build Status](https://travis-ci.org/onelogin/java-saml.svg?branch=master)](https://travis-ci.org/onelogin/java-saml) [![Coverage Status](https://coveralls.io/repos/github/onelogin/java-saml/badge.svg?branch=master)](https://coveralls.io/github/onelogin/java-saml?branch=master) -## **Notice:** This project is currently not under active development, please see [#388](https://github.com/onelogin/java-saml/issues/388) for more information. - Add SAML support to your Java applications using this library. -Forget those complicated libraries and use that open source library provided and supported by OneLogin Inc. 2.8.0 uses xmlsec 2.2.3 which fixes [CVE-2021-40690](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-1655558) @@ -87,7 +84,7 @@ since 2002, but lately it has become popular due to its advantages as follows: ## General description -OneLogin's SAML Java toolkit lets you turn a Java application into a SP +SAML Java toolkit lets you turn a Java application into a SP (Service Provider) that can be connected to an IdP (Identity Provider). Supports: @@ -108,7 +105,6 @@ Key features: * **Easy to use** - Programmer will be allowed to code high-level and low-level programming; 2 easy-to-use APIs are available. * **Tested** - Thoroughly tested. - * **Popular** - OneLogin's customers use it. Add easy support to your java web projects. ## Security warning @@ -198,7 +194,7 @@ Select a [Tomcat Server](http://crunchify.com/step-by-step-guide-to-setup-and-in ## Getting started ### Learning the toolkit -OneLogin's new SAML Java SAML Toolkit contains different folders (core, toolkit, samples) and some files. +Java SAML Toolkit contains different folders (core, toolkit, samples) and some files. Let's start describing them: @@ -261,7 +257,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-tookit-jspsample/me onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-tookit-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -270,7 +266,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-tookit-jspsample/sls.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -326,7 +322,7 @@ onelogin.saml2.idp.entityid = onelogin.saml2.idp.single_sign_on_service.url = # SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -340,7 +336,7 @@ onelogin.saml2.idp.single_logout_service.url = onelogin.saml2.idp.single_logout_service.response.url = # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -755,7 +751,7 @@ In order to avoid replay attacks, you can store the ID of the SAML messages alre Get the ID of the last processed message with the getLastMessageId method of the Auth object. ## Demo included in the toolkit -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). +The 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). #### SP setup Configure the SP part and review the metadata of the IdP and complete the IdP info. Later configure how the toolkit will work enabling/disabling the security settings. diff --git a/core/pom.xml b/core/pom.xml index 92baa25e..b00d34e2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ jar - OneLogin java-saml Toolkit Core + java-saml Toolkit Core java-saml-core diff --git a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java index b5f3811f..8bb89b2b 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java +++ b/core/src/main/java/com/onelogin/saml2/authn/AuthnRequest.java @@ -17,7 +17,7 @@ import com.onelogin.saml2.util.Util; /** - * AuthNRequest class of OneLogin's Java Toolkit. + * AuthNRequest class of Java Toolkit. * * A class that implements SAML 2 Authentication Request */ @@ -79,7 +79,7 @@ public AuthnRequest(Saml2Settings settings) { public AuthnRequest(Saml2Settings settings, boolean forceAuthn, boolean isPassive, boolean setNameIdPolicy, String nameIdValueReq) { this(settings, new AuthnRequestParams(forceAuthn, isPassive, setNameIdPolicy, nameIdValueReq)); } - + /** * Constructs the AuthnRequest object. * @@ -126,7 +126,7 @@ public AuthnRequest(Saml2Settings settings, AuthnRequestParams params) { * This method is invoked at construction time, after all the other fields of * this class have already been initialised. Its default implementation simply * returns the input XML as-is, with no change. - * + * * @param authnRequestXml * the XML produced for this AuthnRequest by the standard * implementation provided by {@link AuthnRequest} @@ -144,10 +144,10 @@ protected String postProcessXml(final String authnRequestXml, final AuthnRequest /** * @return the base64 encoded unsigned AuthnRequest (deflated or not) * - * @param deflated + * @param deflated * If deflated or not the encoded AuthnRequest * - * @throws IOException + * @throws IOException */ public String getEncodedAuthnRequest(Boolean deflated) throws IOException { String encodedAuthnRequest; @@ -161,18 +161,18 @@ public String getEncodedAuthnRequest(Boolean deflated) throws IOException { } return encodedAuthnRequest; } - + /** * @return base64 encoded, unsigned AuthnRequest (deflated or not) - * - * @throws IOException + * + * @throws IOException */ public String getEncodedAuthnRequest() throws IOException { return getEncodedAuthnRequest(null); } /** - * @return unsigned plain-text AuthnRequest. + * @return unsigned plain-text AuthnRequest. */ public String getAuthnRequestXml() { return authnRequestString; @@ -185,9 +185,9 @@ public String getAuthnRequestXml() { * the authentication request input parameters * @param settings * Saml2Settings object. Setting data - * - * @return the StrSubstitutor object of the AuthnRequest - */ + * + * @return the StrSubstitutor object of the AuthnRequest + */ private StrSubstitutor generateSubstitutor(AuthnRequestParams params, Saml2Settings settings) { Map valueMap = new HashMap(); @@ -242,7 +242,7 @@ private StrSubstitutor generateSubstitutor(AuthnRequestParams params, Saml2Setti if (organization != null) { String displayName = organization.getOrgDisplayName(); if (!displayName.isEmpty()) { - providerStr = " ProviderName=\""+ Util.toXml(displayName) + "\""; + providerStr = " ProviderName=\""+ Util.toXml(displayName) + "\""; } } valueMap.put("providerStr", providerStr); @@ -288,10 +288,10 @@ public String getId() { return id; } - + /** * Returns the issue instant of this message. - * + * * @return a new {@link Calendar} instance carrying the issue instant of this message */ public Calendar getIssueInstant() { diff --git a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java index 8fc66d8a..03932b2f 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java +++ b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java @@ -37,7 +37,7 @@ import com.onelogin.saml2.util.Util; /** - * SamlResponse class of OneLogin's Java Toolkit. + * SamlResponse class of Java Toolkit. * * A class that implements SAML 2 Authentication Response parser/validator */ @@ -752,7 +752,7 @@ public String getResponseIssuer() throws XPathExpressionException, ValidationErr } return null; } - + /** * Gets the Assertion Issuer. * @@ -777,7 +777,7 @@ public String getAssertionIssuer() throws XPathExpressionException, ValidationEr throw new ValidationError("Issuer of the Assertion not found or multiple.", ValidationError.ISSUER_NOT_FOUND_IN_ASSERTION); } } - + /** * Gets the Issuers (from Response and Assertion). If the same issuer appears * both in the Response and in the Assertion (as it should), the returned list @@ -1102,11 +1102,11 @@ public String getError() { public Exception getValidationException() { return validationException; } - + /** * Sets the validation exception that this {@link SamlResponse} should return * when a validation error occurs. - * + * * @param validationException * the validation exception to set */ diff --git a/core/src/main/java/com/onelogin/saml2/exception/SAMLException.java b/core/src/main/java/com/onelogin/saml2/exception/SAMLException.java index a1e1547f..cc05147c 100644 --- a/core/src/main/java/com/onelogin/saml2/exception/SAMLException.java +++ b/core/src/main/java/com/onelogin/saml2/exception/SAMLException.java @@ -1,7 +1,7 @@ package com.onelogin.saml2.exception; /** - * Top-level exception class for the OneLogin SAML client. + * Top-level exception class for the SAML client. */ public class SAMLException extends Exception { @@ -10,7 +10,7 @@ public class SAMLException extends Exception { /** * Construct a SAMLException with the provided error message. * - * @param message + * @param message * The human-readable error message associated with this exception. */ public SAMLException(String message) { @@ -33,12 +33,12 @@ public SAMLException(Throwable cause) { * * @param message * The human-readable error message associated with this exception. - * - * @param cause + * + * @param cause * The upstream cause associated with this exception. */ public SAMLException(String message, Throwable cause) { super(message, cause); } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java index cacd7bf8..954ae9e9 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java @@ -29,7 +29,7 @@ import com.onelogin.saml2.util.SchemaFactory; /** - * LogoutRequest class of OneLogin's Java Toolkit. + * LogoutRequest class of Java Toolkit. * * A class that implements SAML 2 Logout Request builder/parser/validator */ @@ -71,7 +71,7 @@ public class LogoutRequest { /** * After validation, if it fails this property has the cause of the problem - */ + */ private Exception validationException; /** @@ -104,19 +104,19 @@ public class LogoutRequest { public LogoutRequest(Saml2Settings settings, HttpRequest request, String nameId, String sessionIndex, String nameIdFormat, String nameIdNameQualifier, String nameIdSPNameQualifier) { this.settings = settings; this.request = request; - + String samlLogoutRequest = null; - + if (request != null) { samlLogoutRequest = request.getParameter("SAMLRequest"); currentUrl = request.getRequestURL(); } - + if (samlLogoutRequest == null) { LogoutRequestParams params = new LogoutRequestParams(sessionIndex, nameId, nameIdFormat, nameIdNameQualifier, nameIdSPNameQualifier); id = Util.generateUniqueID(settings.getUniqueIDPrefix()); issueInstant = Calendar.getInstance(); - + StrSubstitutor substitutor = generateSubstitutor(params, settings); logoutRequestString = postProcessXml(substitutor.replace(getLogoutRequestTemplate()), params, settings); } else { @@ -264,7 +264,7 @@ public LogoutRequest(Saml2Settings settings, LogoutRequestParams params) { * scenario only), after all the other fields of this class have already been * initialised. Its default implementation simply returns the input XML as-is, * with no change. - * + * * @param logoutRequestXml * the XML produced for this LogoutRequest by the standard * implementation provided by {@link LogoutRequest} @@ -282,10 +282,10 @@ protected String postProcessXml(final String logoutRequestXml, final LogoutReque /** * @return the base64 encoded unsigned Logout Request (deflated or not) * - * @param deflated + * @param deflated * If deflated or not the encoded Logout Request * - * @throws IOException + * @throws IOException */ public String getEncodedLogoutRequest(Boolean deflated) throws IOException { String encodedLogoutRequest; @@ -299,11 +299,11 @@ public String getEncodedLogoutRequest(Boolean deflated) throws IOException { } return encodedLogoutRequest; } - + /** * @return the base64 encoded unsigned Logout Request (deflated or not) * - * @throws IOException + * @throws IOException */ public String getEncodedLogoutRequest() throws IOException { return getEncodedLogoutRequest(null); @@ -323,13 +323,13 @@ public String getLogoutRequestXml() { * the logout request input parameters * @param settings * Saml2Settings object. Setting data - * + * * @return the StrSubstitutor object of the LogoutRequest */ private StrSubstitutor generateSubstitutor(LogoutRequestParams params, Saml2Settings settings) { Map valueMap = new HashMap(); - valueMap.put("id", Util.toXml(id)); + valueMap.put("id", Util.toXml(id)); String issueInstantString = Util.formatDateTime(issueInstant.getTimeInMillis()); valueMap.put("issueInstant", issueInstantString); @@ -356,11 +356,11 @@ private StrSubstitutor generateSubstitutor(LogoutRequestParams params, Saml2Sett } } else { nameId = settings.getIdpEntityId(); - nameIdFormat = Constants.NAMEID_ENTITY; + nameIdFormat = Constants.NAMEID_ENTITY; } // From saml-core-2.0-os 8.3.6, when the entity Format is used: "The NameQualifier, SPNameQualifier, and - // SPProvidedID attributes MUST be omitted. + // SPProvidedID attributes MUST be omitted. if (nameIdFormat != null && nameIdFormat.equals(Constants.NAMEID_ENTITY)) { nameQualifier = null; spNameQualifier = null; @@ -424,7 +424,7 @@ public Boolean isValid() { if (this.request == null) { throw new Exception("The HttpRequest of the current host was not established"); } - + if (this.currentUrl == null || this.currentUrl.isEmpty()) { throw new Exception("The URL of the current host was not established"); } @@ -435,7 +435,7 @@ public Boolean isValid() { if (settings.isStrict()) { Element rootElement = logoutRequestDocument.getDocumentElement(); - rootElement.normalize(); + rootElement.normalize(); if (settings.getWantXMLValidation()) { if (!Util.validateXML(logoutRequestDocument, SchemaFactory.SAML_SCHEMA_PROTOCOL_2_0)) { @@ -479,10 +479,10 @@ public Boolean isValid() { throw new ValidationError("The Message of the Logout Request is not signed and the SP requires it", ValidationError.NO_SIGNED_MESSAGE); } } - + if (signature != null && !signature.isEmpty()) { X509Certificate cert = settings.getIdpx509cert(); - + List certList = new ArrayList(); List multipleCertList = settings.getIdpx509certMulti(); @@ -524,9 +524,9 @@ public Boolean isValid() { throw new ValidationError("Signature validation failed. Logout Request rejected", ValidationError.INVALID_SIGNATURE); } } - + LOGGER.debug("LogoutRequest validated --> " + logoutRequestString); - return true; + return true; } catch (Exception e) { validationException = e; LOGGER.debug("LogoutRequest invalid --> " + logoutRequestString); @@ -589,7 +589,7 @@ public static String getId(String samlLogoutRequestString) { Document doc = Util.loadXML(samlLogoutRequestString); return getId(doc); } - + /** * Returns the issue instant of the Logout Request Document. * @@ -618,7 +618,7 @@ public static Calendar getIssueInstant(String samlLogoutRequestString) { public static Map getNameIdData(Document samlLogoutRequestDocument, PrivateKey key) throws Exception { return getNameIdData(samlLogoutRequestDocument, key, false); } - + /** * Gets the NameID Data from the the Logout Request Document. * @@ -637,7 +637,7 @@ public static Map getNameIdData(Document samlLogoutRequestDocume NodeList encryptedIDNodes = Util.query(samlLogoutRequestDocument, "/samlp:LogoutRequest/saml:EncryptedID"); NodeList nameIdNodes; Element nameIdElem; - + if (encryptedIDNodes.getLength() == 1) { if (key == null) { throw new SettingsException("Key is required in order to decrypt the NameID", SettingsException.PRIVATE_KEY_NOT_FOUND); @@ -650,7 +650,7 @@ public static Map getNameIdData(Document samlLogoutRequestDocume if (nameIdNodes == null || nameIdNodes.getLength() != 1) { throw new Exception("Not able to decrypt the EncryptedID and get a NameID"); } - } + } else { nameIdNodes = Util.query(samlLogoutRequestDocument, "/samlp:LogoutRequest/saml:NameID"); } @@ -660,9 +660,9 @@ public static Map getNameIdData(Document samlLogoutRequestDocume } else { throw new ValidationError("No name id found in Logout Request.", ValidationError.NO_NAMEID); } - + Map nameIdData = new HashMap(); - + if (nameIdElem != null) { String value = nameIdElem.getTextContent(); if(value != null && trimValue) { @@ -723,10 +723,10 @@ public static Map getNameIdData(String samlLogoutRequestString, * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. - * + * * @param key * The SP key to decrypt the NameID if encrypted - * + * * @return the Name ID value * * @throws Exception @@ -740,10 +740,10 @@ public static String getNameId(Document samlLogoutRequestDocument, PrivateKey ke * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. - * + * * @param key * The SP key to decrypt the NameID if encrypted - * + * * @param trimValue * whether the extracted Name ID value should be trimmed * @@ -771,7 +771,7 @@ public static String getNameId(Document samlLogoutRequestDocument, PrivateKey ke public static String getNameId(Document samlLogoutRequestDocument) throws Exception { return getNameId(samlLogoutRequestDocument, null); } - + /** * Gets the NameID value provided from the SAML Logout Request String. * @@ -821,10 +821,10 @@ public static String getNameId(String samlLogoutRequestString, PrivateKey key, b public static String getNameId(String samlLogoutRequestString) throws Exception { return getNameId(samlLogoutRequestString, null); } - + /** * Gets the Issuer from Logout Request Document. - * + * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. * @@ -838,7 +838,7 @@ public static String getIssuer(Document samlLogoutRequestDocument) throws XPathE /** * Gets the Issuer from Logout Request Document. - * + * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. * @param trim @@ -864,12 +864,12 @@ public static String getIssuer(Document samlLogoutRequestDocument, boolean trim) /** * Gets the Issuer from Logout Request String. - * + * * @param samlLogoutRequestString * A Logout Request string. * * @return the issuer of the logout request - * + * * @throws XPathExpressionException */ public static String getIssuer(String samlLogoutRequestString) throws XPathExpressionException { @@ -878,14 +878,14 @@ public static String getIssuer(String samlLogoutRequestString) throws XPathExpre /** * Gets the Issuer from Logout Request String. - * + * * @param samlLogoutRequestString * A Logout Request string. * @param trim * whether the extracted issuer value should be trimmed * * @return the issuer of the logout request - * + * * @throws XPathExpressionException */ public static String getIssuer(String samlLogoutRequestString, boolean trim) throws XPathExpressionException { @@ -896,7 +896,7 @@ public static String getIssuer(String samlLogoutRequestString, boolean trim) thr /** * Gets the SessionIndexes from the LogoutRequest. - * + * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. * @return the SessionIndexes @@ -909,7 +909,7 @@ public static List getSessionIndexes(Document samlLogoutRequestDocument) /** * Gets the SessionIndexes from the LogoutRequest. - * + * * @param samlLogoutRequestDocument * A DOMDocument object loaded from the SAML Logout Request. * @param trim @@ -939,7 +939,7 @@ public static List getSessionIndexes(Document samlLogoutRequestDocument, /** * Gets the SessionIndexes from the LogoutRequest. - * + * * @param samlLogoutRequestString * A Logout Request string. * @return the SessionIndexes @@ -952,7 +952,7 @@ public static List getSessionIndexes(String samlLogoutRequestString) thr /** * Gets the SessionIndexes from the LogoutRequest. - * + * * @param samlLogoutRequestString * A Logout Request string. * @param trim @@ -970,7 +970,7 @@ public static List getSessionIndexes(String samlLogoutRequestString, boo /** * After execute a validation process, if fails this method returns the cause * - * @return the cause of the validation error + * @return the cause of the validation error */ public String getError() { if (validationException != null) { @@ -991,7 +991,7 @@ public Exception getValidationException() { /** * Sets the validation exception that this {@link LogoutRequest} should return * when a validation error occurs. - * + * * @param validationException * the validation exception to set */ @@ -1009,7 +1009,7 @@ public String getId() /** * Returns the issue instant of this message. - * + * * @return a new {@link Calendar} instance carrying the issue instant of this message */ public Calendar getIssueInstant() { diff --git a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java index 7199fae9..8fc1bc65 100644 --- a/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java +++ b/core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java @@ -29,7 +29,7 @@ import com.onelogin.saml2.util.Util; /** - * LogoutResponse class of OneLogin's Java Toolkit. + * LogoutResponse class of Java Toolkit. * * A class that implements SAML 2 Logout Response builder/parser/validator */ @@ -101,12 +101,12 @@ public LogoutResponse(Saml2Settings settings, HttpRequest request) { samlLogoutResponse = request.getParameter("SAMLResponse"); } - if (samlLogoutResponse != null && !samlLogoutResponse.isEmpty()) { + if (samlLogoutResponse != null && !samlLogoutResponse.isEmpty()) { logoutResponseString = Util.base64decodedInflated(samlLogoutResponse); logoutResponseDocument = Util.loadXML(logoutResponseString); } } - + /** * Constructs the LogoutResponse object when a new response should be generated * and sent. @@ -146,7 +146,7 @@ public String getEncodedLogoutResponse(Boolean deflated) throws IOException { } return encodedLogoutResponse; } - + /** * @return the base64 encoded, unsigned Logout Response (deflated or not) * @@ -200,7 +200,7 @@ public Boolean isValid(String requestId) { if (settings.isStrict()) { Element rootElement = logoutResponseDocument.getDocumentElement(); - rootElement.normalize(); + rootElement.normalize(); if (settings.getWantXMLValidation()) { if (!Util.validateXML(this.logoutResponseDocument, SchemaFactory.SAML_SCHEMA_PROTOCOL_2_0)) { @@ -359,7 +359,7 @@ public SamlResponseStatus getSamlResponseStatus() throws ValidationError * Xpath Expression * * @return DOMNodeList The queried nodes - * @throws XPathExpressionException + * @throws XPathExpressionException */ protected NodeList query (String query) throws XPathExpressionException { return Util.query(this.logoutResponseDocument, query, null); @@ -398,7 +398,7 @@ public void build(String inResponseTo, SamlResponseStatus responseStatus) { * Generates a Logout Response XML string. * * @param inResponseTo - * InResponseTo attribute value to bet set at the Logout Response. + * InResponseTo attribute value to bet set at the Logout Response. * @param statusCode * String StatusCode to be set on the LogoutResponse * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} @@ -439,10 +439,10 @@ public void build(String inResponseTo, String statusCode) { public void build(String inResponseTo) { build(inResponseTo, Constants.STATUS_SUCCESS); } - + /** * Generates a Logout Response XML string. - * + * * @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)} * instead, in which case this method becomes completely useless; * indeed, invoking this method in an outgoing logout response @@ -458,7 +458,7 @@ public void build(String inResponseTo) { @Deprecated public void build() { build(null); - } + } /** * Allows for an extension class to post-process the LogoutResponse XML @@ -467,7 +467,7 @@ public void build() { * This method is invoked by {@link #build(String, String)} (and all of its * overloadings) and hence only in the logout response sending scenario. Its * default implementation simply returns the input XML as-is, with no change. - * + * * @param logoutResponseXml * the XML produced for this LogoutResponse by the standard * implementation provided by {@link LogoutResponse} @@ -482,7 +482,7 @@ protected String postProcessXml(final String logoutResponseXml, final LogoutResp final Saml2Settings settings) { return logoutResponseXml; } - + /** * Substitutes LogoutResponse variables within a string by values. * @@ -513,7 +513,7 @@ private StrSubstitutor generateSubstitutor(LogoutResponseParams params, Saml2Set if (inResponseTo != null) { inResponseStr = " InResponseTo=\"" + Util.toXml(inResponseTo) + "\""; } - valueMap.put("inResponseStr", inResponseStr); + valueMap.put("inResponseStr", inResponseStr); StringBuilder statusStr = new StringBuilder("(); + this.requestedAttributes = new ArrayList(); } /** @@ -46,7 +46,7 @@ public AttributeConsumingService(String serviceName, String serviceDescription) public final void addRequestedAttribute(RequestedAttribute attr) { this.requestedAttributes.add(attr); } - + /** * @return string the service name */ @@ -68,4 +68,4 @@ public final List getRequestedAttributes() { return requestedAttributes; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/onelogin/saml2/model/Contact.java b/core/src/main/java/com/onelogin/saml2/model/Contact.java index eb9a52ee..8c03ac4a 100644 --- a/core/src/main/java/com/onelogin/saml2/model/Contact.java +++ b/core/src/main/java/com/onelogin/saml2/model/Contact.java @@ -5,9 +5,9 @@ import java.util.List; /** - * Contact class of OneLogin's Java Toolkit. + * Contact class of Java Toolkit. * - * A class that stores contact info + * A class that stores contact info */ public class Contact { /** @@ -19,12 +19,12 @@ public class Contact { * Contact company */ private final String company; - + /** * Contact given name */ private final String givenName; - + /** * Contact surname */ @@ -39,7 +39,7 @@ public class Contact { * Contact phone number */ private final List telephoneNumbers; - + /** * Constructor to specify minimal contact data. *

@@ -114,14 +114,14 @@ public final List getEmailAddresses() { public final String getGivenName() { return givenName; } - + /** * @return the contact surname */ public final String getSurName() { return surName; } - + /** * @return the contact company */ @@ -135,4 +135,4 @@ public final String getCompany() { public final List getTelephoneNumbers() { return telephoneNumbers; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/onelogin/saml2/model/KeyStoreSettings.java b/core/src/main/java/com/onelogin/saml2/model/KeyStoreSettings.java index 0f89fa88..7659f44f 100644 --- a/core/src/main/java/com/onelogin/saml2/model/KeyStoreSettings.java +++ b/core/src/main/java/com/onelogin/saml2/model/KeyStoreSettings.java @@ -3,7 +3,7 @@ import java.security.KeyStore; /** - * KeyStore class of OneLogin's Java Toolkit. + * KeyStore class of Java Toolkit. * * A class that stores KeyStore details for Certificates and Private Key */ @@ -28,7 +28,7 @@ public class KeyStoreSettings { * * @param keyStore * stores certificates and key - * + * * @param spAlias * Alias for SP key entry * @@ -62,4 +62,4 @@ public final String getSpKeyPass() { return spKeyPass; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/onelogin/saml2/model/Organization.java b/core/src/main/java/com/onelogin/saml2/model/Organization.java index c60599b4..b935391a 100644 --- a/core/src/main/java/com/onelogin/saml2/model/Organization.java +++ b/core/src/main/java/com/onelogin/saml2/model/Organization.java @@ -6,9 +6,9 @@ /** - * Organization class of OneLogin's Java Toolkit. + * Organization class of Java Toolkit. * - * A class that stores organization info + * A class that stores organization info */ public class Organization { /** @@ -25,7 +25,7 @@ public class Organization { * Organization URL */ private final String orgUrl; - + /** * Organization lang attribute */ @@ -46,7 +46,7 @@ public class Organization { public Organization(String orgName, String orgDisplayName, URL orgUrl, String orgLangAttribute) { this(orgName, orgDisplayName, orgUrl != null ? orgUrl.toString() : "", orgLangAttribute); } - + /** * Constructor
* Default the lang attribute to "en" @@ -80,7 +80,7 @@ public Organization(String orgName, String orgDisplayName, String orgUrl, String this.orgUrl = orgUrl != null ? orgUrl : ""; this.orgLangAttribute = StringUtils.defaultIfBlank(orgLangAttribute, "en"); } - + /** * Constructor
* Default the lang attribute to "en" @@ -116,13 +116,13 @@ public final String getOrgDisplayName() { public final String getOrgUrl() { return orgUrl; } - + /** * @return string the lang attribute */ public final String getOrgLangAttribute() { return orgLangAttribute; - } + } /** * Compare with another organization @@ -133,5 +133,5 @@ public final String getOrgLangAttribute() { */ public final Boolean equalsTo(Organization org) { return orgName.equals(org.getOrgName()) && orgDisplayName.equals(org.getOrgDisplayName()) && orgUrl.equals(org.getOrgUrl()) && orgLangAttribute.equals(org.getOrgLangAttribute()); - } + } } diff --git a/core/src/main/java/com/onelogin/saml2/model/RequestedAttribute.java b/core/src/main/java/com/onelogin/saml2/model/RequestedAttribute.java index 2079b57e..e0d37de7 100644 --- a/core/src/main/java/com/onelogin/saml2/model/RequestedAttribute.java +++ b/core/src/main/java/com/onelogin/saml2/model/RequestedAttribute.java @@ -4,9 +4,9 @@ /** - * RequestedAttribute class of OneLogin's Java Toolkit. + * RequestedAttribute class of Java Toolkit. * - * A class that stores RequestedAttribute of the AttributeConsumingService + * A class that stores RequestedAttribute of the AttributeConsumingService */ public class RequestedAttribute { /** @@ -23,7 +23,7 @@ public class RequestedAttribute { * If the attribute is or not required */ private final Boolean isRequired; - + /** * NameFormat of the attribute */ @@ -33,7 +33,7 @@ public class RequestedAttribute { * Values of the attribute */ private final List attributeValues; - + /** * Constructor * @@ -55,7 +55,7 @@ public RequestedAttribute(String name, String friendlyName, Boolean isRequired, this.nameFormat = nameFormat; this.attributeValues = attributeValues; } - + /** * @return string the RequestedAttribute name */ @@ -76,18 +76,18 @@ public final String getFriendlyName() { public final Boolean isRequired() { return isRequired; } - + /** * @return string the RequestedAttribute nameformat */ public final String getNameFormat() { return nameFormat; } - + /** * @return string the RequestedAttribute nameformat */ public final List getAttributeValues() { return attributeValues; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/onelogin/saml2/model/SamlResponseStatus.java b/core/src/main/java/com/onelogin/saml2/model/SamlResponseStatus.java index 7552380a..1a4e6e78 100644 --- a/core/src/main/java/com/onelogin/saml2/model/SamlResponseStatus.java +++ b/core/src/main/java/com/onelogin/saml2/model/SamlResponseStatus.java @@ -2,7 +2,7 @@ /** - * SamlResponseStatus class of OneLogin's Java Toolkit. + * SamlResponseStatus class of Java Toolkit. * * A class that stores the SAML response status info */ @@ -54,7 +54,7 @@ public String getStatusCode() { /** * Set the status code - * + * * @param statusCode * String. Status code */ @@ -88,8 +88,8 @@ public String getStatusMessage() { /** * Set the status message - * - * @param statusMessage + * + * @param statusMessage * String. Status message */ public void setStatusMessage(String statusMessage) { @@ -98,11 +98,11 @@ public void setStatusMessage(String statusMessage) { /** * Compare the status code - * - * @param status + * + * @param status * String. Status code * - * @return boolean checks the status code + * @return boolean checks the status code */ public boolean is(String status) { return statusCode != null && !statusCode.isEmpty() && statusCode.equals(status); diff --git a/core/src/main/java/com/onelogin/saml2/settings/IdPMetadataParser.java b/core/src/main/java/com/onelogin/saml2/settings/IdPMetadataParser.java index d2d46426..42ee439c 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/IdPMetadataParser.java +++ b/core/src/main/java/com/onelogin/saml2/settings/IdPMetadataParser.java @@ -20,7 +20,7 @@ import com.onelogin.saml2.util.Util; /** - * IdPMetadataParser class of OneLogin's Java Toolkit. + * IdPMetadataParser class of Java Toolkit. * * A class that implements the settings parser from IdP Metadata * @@ -36,7 +36,7 @@ public class IdPMetadataParser { /** * Get IdP Metadata Info from XML Document - * + * * @param xmlDocument * XML document hat contains IdP metadata * @param entityId @@ -47,7 +47,7 @@ public class IdPMetadataParser { * Parse specific binding SSO endpoint. * @param desiredSLOBinding * Parse specific binding SLO endpoint. - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws XPathExpressionException */ @@ -149,12 +149,12 @@ public static Map parseXML(Document xmlDocument, String entityId /** * Get IdP Metadata Info from XML Document - * + * * @param xmlDocument * XML document that contains IdP metadata * @param entityId * Entity Id of the desired IdP, if no entity Id is provided and the XML metadata contains more than one IDPSSODescriptor, the first is returned - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws XPathException */ @@ -164,10 +164,10 @@ public static Map parseXML(Document xmlDocument, String entityId /** * Get IdP Metadata Info from XML Document - * + * * @param xmlDocument * XML document that contains IdP metadata - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws XPathException */ @@ -177,7 +177,7 @@ public static Map parseXML(Document xmlDocument) throws XPathExc /** * Get IdP Metadata Info from XML file - * + * * @param xmlFileName * Filename of the XML filename that contains IdP metadata * @param entityId @@ -188,7 +188,7 @@ public static Map parseXML(Document xmlDocument) throws XPathExc * Parse specific binding SSO endpoint. * @param desiredSLOBinding * Parse specific binding SLO endpoint. - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -210,12 +210,12 @@ public static Map parseFileXML(String xmlFileName, String entity /** * Get IdP Metadata Info from XML file - * + * * @param xmlFileName * Filename of the XML filename that contains IdP metadata * @param entityId * Entity Id of the desired IdP, if no entity Id is provided and the XML metadata contains more than one IDPSSODescriptor, the first is returned - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -225,10 +225,10 @@ public static Map parseFileXML(String xmlFileName, String entity /** * Get IdP Metadata Info from XML file - * + * * @param xmlFileName * Filename of the XML filename that contains IdP metadata - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -238,7 +238,7 @@ public static Map parseFileXML(String xmlFileName) throws Except /** * Get IdP Metadata Info from XML file - * + * * @param xmlURL * URL to the XML document that contains IdP metadata * @param entityId @@ -249,7 +249,7 @@ public static Map parseFileXML(String xmlFileName) throws Except * Parse specific binding SSO endpoint. * @param desiredSLOBinding * Parse specific binding SLO endpoint. - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -260,12 +260,12 @@ public static Map parseRemoteXML(URL xmlURL, String entityId, St /** * Get IdP Metadata Info from XML file - * + * * @param xmlURL * URL to the XML document that contains IdP metadata * @param entityId * Entity Id of the desired IdP, if no entity Id is provided and the XML metadata contains more than one IDPSSODescriptor, the first is returned - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -275,10 +275,10 @@ public static Map parseRemoteXML(URL xmlURL, String entityId) th /** * Get IdP Metadata Info from XML file - * + * * @param xmlURL * URL to the XML document that contains IdP metadata - * + * * @return Mapped values with metadata info in Saml2Settings format * @throws Exception */ @@ -293,7 +293,7 @@ public static Map parseRemoteXML(URL xmlURL) throws Exception { * the Saml2Settings object * @param metadataInfo * mapped values with metadata info in Saml2Settings format - * + * * @return the Saml2Settings object with metadata info settings loaded */ public static Saml2Settings injectIntoSettings(Saml2Settings settings, Map metadataInfo) { diff --git a/core/src/main/java/com/onelogin/saml2/settings/Metadata.java b/core/src/main/java/com/onelogin/saml2/settings/Metadata.java index 30a83184..5a11b5b8 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Metadata.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Metadata.java @@ -28,7 +28,7 @@ import com.onelogin.saml2.util.Util; /** - * Metadata class of OneLogin's Java Toolkit. + * Metadata class of Java Toolkit. * * A class that contains methods related to the metadata of the SP */ @@ -114,7 +114,7 @@ public Metadata(Saml2Settings settings) throws CertificateEncodingException { LOGGER.debug("metadata --> " + unsignedMetadataString); metadataString = unsignedMetadataString; } - + /** * Allows for an extension class to post-process the SAML metadata XML generated * for this metadata instance, in order to customize the result. @@ -122,7 +122,7 @@ public Metadata(Saml2Settings settings) throws CertificateEncodingException { * This method is invoked at construction time, after all the other fields of * this class have already been initialised. Its default implementation simply * returns the input XML as-is, with no change. - * + * * @param metadataXml * the XML produced for this metadata instance by the standard * implementation provided by {@link Metadata} diff --git a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java index 9ee29465..4a2fa5eb 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java @@ -24,10 +24,10 @@ import com.onelogin.saml2.util.Util; /** - * Saml2Settings class of OneLogin's Java Toolkit. + * Saml2Settings class of Java Toolkit. * * A class that implements the settings handler - */ + */ public class Saml2Settings { /** * Private property to construct a logger for this class. @@ -37,7 +37,7 @@ public class Saml2Settings { // Toolkit settings private boolean strict = true; private boolean debug = false; - + // SP private String spEntityId = ""; private URL spAssertionConsumerServiceUrl = null; @@ -86,7 +86,7 @@ public class Saml2Settings { // Compress private boolean compressRequest = true; private boolean compressResponse = true; - + // Parsing private boolean trimNameIds = false; private boolean trimAttributeValues = false; @@ -96,7 +96,7 @@ public class Saml2Settings { private Organization organization = null; private boolean spValidationOnly = false; - + /** * @return the strict setting value */ @@ -310,7 +310,7 @@ public boolean getWantAssertionsEncrypted() { public boolean getWantNameId() { return wantNameId; } - + /** * @return the wantNameIdEncrypted setting value */ @@ -394,10 +394,10 @@ public HSM getHsm() { public boolean isDebugActive() { return this.debug; } - + /** * Set the strict setting value - * + * * @param strict * the strict to be set */ @@ -770,7 +770,7 @@ public void setRequestedAuthnContextComparison(String requestedAuthnContextCompa * Set the wantXMLValidation setting value * * @param wantXMLValidation - * the wantXMLValidation value to be set. Based on it the SP will validate SAML messages against the XML scheme + * the wantXMLValidation value to be set. Based on it the SP will validate SAML messages against the XML scheme */ public void setWantXMLValidation(boolean wantXMLValidation) { this.wantXMLValidation = wantXMLValidation; @@ -857,7 +857,7 @@ public boolean isCompressResponseEnabled() { *

* Default is false, that is Name IDs are kept intact, as the SAML * specification prescribes. - * + * * @param trimNameIds * set to true to trim parsed Name IDs, set to * false to keep them intact @@ -865,26 +865,26 @@ public boolean isCompressResponseEnabled() { public void setTrimNameIds(boolean trimNameIds) { this.trimNameIds = trimNameIds; } - + /** * Determines whether Name IDs should trimmed when extracting them from parsed * SAML messages. *

* Default is false, that is Name IDs are kept intact, as the SAML * specification prescribes. - * + * * @return true if Name IDs should be trimmed, false * otherwise */ public boolean isTrimNameIds() { return trimNameIds; } - + /** * Sets whether attribute values in parsed SAML messages should be trimmed. *

* Default is false. - * + * * @param trimAttributeValues * set to true to trim parsed attribute values, set to * false to keep them intact @@ -892,23 +892,23 @@ public boolean isTrimNameIds() { public void setTrimAttributeValues(boolean trimAttributeValues) { this.trimAttributeValues = trimAttributeValues; } - + /** * Determines whether attribute values should be trimmed when extracting them * from parsed SAML messages. *

* Default is false. - * + * * @return true if attribute values should be trimmed, * false otherwise */ public boolean isTrimAttributeValues() { return trimAttributeValues; } - + /** * Set contacts info that will be listed on the Service Provider metadata - * + * * @param contacts * the contacts to set */ @@ -928,21 +928,21 @@ protected final void setOrganization(Organization organization) { /** * Checks the settings . - * + * * @return errors found on the settings data */ public List checkSettings() { List errors = new ArrayList<>(this.checkSPSettings()); - if (!spValidationOnly) { + if (!spValidationOnly) { errors.addAll(this.checkIdPSettings()); } return errors; } - + /** * Checks the IdP settings . - * + * * @return errors found on the IdP settings data */ public List checkIdPSettings() { @@ -964,7 +964,7 @@ public List checkIdPSettings() { if (!checkIdpx509certRequired() && !checkRequired(this.getIdpCertFingerprint())) { errorMsg = "idp_cert_or_fingerprint_not_found_and_required"; errors.add(errorMsg); - LOGGER.error(errorMsg); + LOGGER.error(errorMsg); } if (!checkIdpx509certRequired() && this.getNameIdEncrypted()) { @@ -978,7 +978,7 @@ public List checkIdPSettings() { /** * Auxiliary method to check Idp certificate is configured. - * + * * @return true if the Idp Certificate settings are valid */ private boolean checkIdpx509certRequired () { @@ -1072,7 +1072,7 @@ public boolean checkSPCerts() { return (cert != null && key != null); } - + /** * Auxiliary method to check required properties. * @@ -1115,7 +1115,7 @@ public boolean getSPValidationOnly() { return this.spValidationOnly; } - + /** * Gets the SP metadata. The XML representation. * @@ -1139,22 +1139,22 @@ public String getSPMetadata() throws CertificateEncodingException { this.getSignatureAlgorithm(), this.getDigestAlgorithm() ); - } catch (Exception e) { + } catch (Exception e) { LOGGER.debug("Error executing signMetadata: " + e.getMessage(), e); } } return metadataString; } - + /** * Validates an XML SP Metadata. * * @param metadataString Metadata's XML that will be validate - * + * * @return Array The list of found errors * - * @throws Exception + * @throws Exception */ public static List validateMetadata(String metadataString) throws Exception { @@ -1194,7 +1194,7 @@ public static List validateMetadata(String metadataString) throws Except } } // TODO Validate Sign if required with Util.validateMetadataSign - + return errors; } } diff --git a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java index 6232044e..aec3d6ea 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java +++ b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java @@ -39,7 +39,7 @@ import com.onelogin.saml2.util.Util; /** - * SettingsBuilder class of OneLogin's Java Toolkit. + * SettingsBuilder class of Java Toolkit. * * A class that implements the settings builder */ @@ -81,7 +81,7 @@ public class SettingsBuilder { public final static String SP_CONTACT_SUR_NAME_PROPERTY_KEY_SUFFIX = "sur_name"; public final static String SP_CONTACT_EMAIL_ADDRESS_PROPERTY_KEY_PREFIX = "email_address"; public final static String SP_CONTACT_TELEPHONE_NUMBER_PROPERTY_KEY_PREFIX = "telephone_number"; - + // KeyStore public final static String KEYSTORE_KEY = "onelogin.saml2.keystore.store"; public final static String KEYSTORE_ALIAS = "onelogin.saml2.keystore.alias"; @@ -127,7 +127,7 @@ public class SettingsBuilder { // Parsing public final static String PARSING_TRIM_NAME_IDS = "onelogin.saml2.parsing.trim_name_ids"; public final static String PARSING_TRIM_ATTRIBUTE_VALUES = "onelogin.saml2.parsing.trim_attribute_values"; - + // Misc @Deprecated public final static String CONTACT_TECHNICAL_GIVEN_NAME = "onelogin.saml2.contacts.technical.given_name"; @@ -163,7 +163,7 @@ public SettingsBuilder fromFile(String propFileName) throws Error, IOException { * * @param propFileName OneLogin_Saml2_Settings * @param keyStoreSetting KeyStore which have the Private/Public keys - * + * * @return the SettingsBuilder object with the settings loaded from the file * * @throws IOException @@ -254,9 +254,9 @@ public Saml2Settings build() { /** * Builds the Saml2Settings object. Read the Properties object and set all the * SAML settings - * + * * @param saml2Setting an existing Saml2Settings - * + * * @return the Saml2Settings object with all the SAML settings loaded * */ @@ -485,14 +485,14 @@ private Organization loadOrganization() { /** * Loads the contacts settings from the properties file - * + * * @return a list containing all the loaded contacts */ @SuppressWarnings("deprecation") private List loadContacts() { // first split properties into a map of properties // key = contact index; value = contact properties - final SortedMap> contactProps = + final SortedMap> contactProps = extractIndexedProperties(SP_CONTACT_PROPERTY_KEY_PREFIX, samlData); // then build each contact // multiple indexed services specified @@ -521,7 +521,7 @@ private List loadContacts() { /** * Loads a single contact from settings. - * + * * @param contactProps * a map containing the contact settings * @param index @@ -552,39 +552,39 @@ private Contact loadContact(Map contactProps, int index) { *

* For instance, if the prefix is foo, all the following properties * will be extracted: - * + * *

 	 * foo[0].prop1=<value1>
 	 * foo[0].prop2=<value2>
 	 * foo[1].prop1=<value3>
 	 * 
- * + * * and the returned map will be: - * + * *
 	 * 0 => prop1=<value1>
 	 *      prop2=<value2>
 	 * 1 => prop1=<value3>
 	 * 
- * + * * The index is optional: if missing, "-1" is returned. In other words, in the * above example: - * + * *
 	 * foo.prop1=<value1>
 	 * foo.prop2=<value2>
 	 * 
- * + * * will be mapped to: - * + * *
 	 * -1 => prop1=<value1>
 	 *       prop2=<value2>
 	 * 
- * + * * Indices can be made of maximum 9 digits, to prevent overflows. Leading zeroes * are discarded. - * + * * @param prefix * the prefix that identifies the indexed property to extract * @param data @@ -592,7 +592,7 @@ private Contact loadContact(Map contactProps, int index) { * @return a map with extracted data for each identified index */ private SortedMap> extractIndexedProperties(String prefix, Map data) { - final Pattern p = Pattern.compile(Pattern.quote(prefix) + + final Pattern p = Pattern.compile(Pattern.quote(prefix) + "(?:\\[(\\d{1,9})\\])?\\.(.+)"); final SortedMap> indexedProps = new TreeMap<>(); for(final Entry prop: data.entrySet()) { @@ -611,46 +611,46 @@ private SortedMap> extractIndexedProperties(String } return indexedProps; } - + /** * Given a map containing settings data, extracts all the indexed values * identified by a given prefix. The returned map has indexes as keys and the - * corresponding values as values. Keys are sorted by their natural order + * corresponding values as values. Keys are sorted by their natural order * (i.e. iterating over the map will return entries in index order). *

* For instance, if the prefix is foo, all the following values * will be extracted: - * + * *

 	 * foo[0]=<value1>
 	 * foo[1]=<value2>
 	 * foo[2]=<value3>
 	 * 
- * + * * and the returned map will be: - * + * *
 	 * 0 => <value1>
 	 * 1 => <value2>
 	 * 3 => <value3>
 	 * 
- * + * * The index is optional: if missing, "-1" is returned. In other words, in the * above example: - * + * *
 	 * foo=<value1>
 	 * 
- * + * * will be mapped to: - * + * *
 	 * -1 => <value1>
 	 * 
- * + * * Indices can be made of maximum 9 digits, to prevent overflows. Leading zeroes * are discarded. - * + * * @param prefix * the prefix that identifies the indexed property to extract * @param data @@ -658,7 +658,7 @@ private SortedMap> extractIndexedProperties(String * @return a map with extracted values for each identified index */ private SortedMap extractIndexedValues(String prefix, Map data) { - final Pattern p = Pattern.compile(Pattern.quote(prefix) + + final Pattern p = Pattern.compile(Pattern.quote(prefix) + "(?:\\[(\\d{1,9})\\])?"); final SortedMap indexedValues = new TreeMap<>(); for(final Entry prop: data.entrySet()) { @@ -671,13 +671,13 @@ private SortedMap extractIndexedValues(String prefix, Map data) } return null; } - + /** * Loads a property of the type Boolean from the Properties object * @@ -976,7 +976,7 @@ protected X509Certificate loadCertificateFromFile(String filename) { LOGGER.error("Error loading certificate from file.", e); return null; } - + try { return Util.loadCert(certString); } catch (CertificateException e) { diff --git a/core/src/main/java/com/onelogin/saml2/util/Constants.java b/core/src/main/java/com/onelogin/saml2/util/Constants.java index d3aae65b..1de7c455 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Constants.java +++ b/core/src/main/java/com/onelogin/saml2/util/Constants.java @@ -1,17 +1,17 @@ package com.onelogin.saml2.util; /** - * Constants class of OneLogin's Java Toolkit. + * Constants class of Java Toolkit. * * A class that contains several constants related to the SAML protocol - */ + */ public final class Constants { /** * Value added to the current time in time condition validations. */ public static final Integer ALOWED_CLOCK_DRIFT = 180; // 3 min in seconds - // NameID Formats + // NameID Formats public static final String NAMEID_EMAIL_ADDRESS = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"; public static final String NAMEID_X509_SUBJECT_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"; public static final String NAMEID_WINDOWS_DOMAIN_QUALIFIED_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"; @@ -21,7 +21,7 @@ public final class Constants { public static final String NAMEID_TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"; public static final String NAMEID_PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"; public static final String NAMEID_ENCRYPTED = "urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted"; - + // Attribute Name Formats public static final String ATTRNAME_FORMAT_UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"; public static final String ATTRNAME_FORMAT_URI = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"; @@ -97,8 +97,8 @@ public final class Constants { public static final String C14N11_WC = "http://www.w3.org/2006/12/xml-c14n11#WithComments"; public static final String C14NEXC = "http://www.w3.org/2001/10/xml-exc-c14n#"; public static final String C14NEXC_WC = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"; - - // Sign & Crypt + + // Sign & Crypt // https://www.w3.org/TR/xmlenc-core/#sec-Alg-MessageDigest // https://www.w3.org/TR/xmlsec-algorithms/#signature-method-uris // https://tools.ietf.org/html/rfc6931 @@ -112,7 +112,7 @@ public final class Constants { public static final String RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; public static final String RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"; public static final String RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"; - + public static final String TRIPLEDES_CBC = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"; public static final String AES128_CBC = "http://www.w3.org/2001/04/xmlenc#aes128-cbc"; public static final String AES192_CBC = "http://www.w3.org/2001/04/xmlenc#aes192-cbc"; @@ -122,11 +122,11 @@ public final class Constants { public static final String A256KW = "http://www.w3.org/2001/04/xmlenc#kw-aes256"; public static final String RSA_1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5"; public static final String RSA_OAEP_MGF1P = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"; - + public static final String ENVSIG = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"; - + private Constants() { //not called } - + } diff --git a/core/src/main/java/com/onelogin/saml2/util/SchemaFactory.java b/core/src/main/java/com/onelogin/saml2/util/SchemaFactory.java index 647a0702..3cd4f46a 100644 --- a/core/src/main/java/com/onelogin/saml2/util/SchemaFactory.java +++ b/core/src/main/java/com/onelogin/saml2/util/SchemaFactory.java @@ -16,12 +16,12 @@ import org.xml.sax.SAXException; /** - * SchemaFactory class of OneLogin's Java Toolkit. + * SchemaFactory class of Java Toolkit. * - * A class that read SAML schemas that will be used to validate XMLs of the OneLogin's Java Toolkit - */ + * A class that read SAML schemas that will be used to validate XMLs of the Java Toolkit + */ public abstract class SchemaFactory { - + /** * Private property to construct a logger for this class. */ @@ -30,7 +30,7 @@ public abstract class SchemaFactory { private SchemaFactory() { //not called } - + public static final URL SAML_SCHEMA_METADATA_2_0 = SchemaFactory.class .getResource("/schemas/saml-schema-metadata-2.0.xsd"); public static final URL SAML_SCHEMA_PROTOCOL_2_0 = SchemaFactory.class diff --git a/core/src/main/java/com/onelogin/saml2/util/Util.java b/core/src/main/java/com/onelogin/saml2/util/Util.java index 8a6be158..8aa2cbe4 100644 --- a/core/src/main/java/com/onelogin/saml2/util/Util.java +++ b/core/src/main/java/com/onelogin/saml2/util/Util.java @@ -99,7 +99,7 @@ /** - * Util class of OneLogin's Java Toolkit. + * Util class of Java Toolkit. * * A class that contains several auxiliary methods related to the SAML protocol */ @@ -1127,7 +1127,7 @@ public static Boolean mustRejectDeprecatedSignatureAlgo(String signAlg, Boolean } return false; } - + /** * Validate signature of the Node. * @@ -1979,11 +1979,11 @@ public static DateTime parseDateTime(String dateTime) { } return parsedData; } - + /** * Escape a text so that it can be safely used within an XML element contents or attribute value. - * - * @param text + * + * @param text * the text to escape * @return the escaped text (null if the input is null) */ diff --git a/core/src/test/resources/config/config.adfs.properties b/core/src/test/resources/config/config.adfs.properties index 8bd0072c..3548959e 100644 --- a/core/src/test/resources/config/config.adfs.properties +++ b/core/src/test/resources/config/config.adfs.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = http://adfs.vc.example.com/adfs/services/trust # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://adfs.vc.example.com/adfs/ls -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -58,7 +58,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://adfs.vc.example.com/adfs/ls # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -92,7 +92,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -132,7 +132,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -140,4 +140,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.all.properties b/core/src/test/resources/config/config.all.properties index fcdbf242..b2004150 100644 --- a/core/src/test/resources/config/config.all.properties +++ b/core/src/test/resources/config/config.all.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -38,7 +38,7 @@ onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADAN # To be used during SP Key roll over onelogin.saml2.sp.x509certNew = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -50,8 +50,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -65,7 +65,7 @@ onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml onelogin.saml2.idp.single_logout_service.response.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutServiceResponse.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -101,7 +101,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -141,13 +141,13 @@ onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha5 # SAML specification states that no trimming for string elements should be performed, so no trimming will be # performed by default on extracted Name IDs and attribute values. However, some SAML implementations may add # undesirable surrounding whitespace when outputting XML (possibly due to formatting/pretty-printing). -# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and +# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and # attribute values. onelogin.saml2.parsing.trim_name_ids = false onelogin.saml2.parsing.trim_attribute_values = false # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.organization.lang = en diff --git a/core/src/test/resources/config/config.all_specialchars.properties b/core/src/test/resources/config/config.all_specialchars.properties index 923297e0..13ede911 100644 --- a/core/src/test/resources/config/config.all_specialchars.properties +++ b/core/src/test/resources/config/config.all_specialchars.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp?a=1&b=2 # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp?a=1&b=2 # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -38,7 +38,7 @@ onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADAN # To be used during SP Key roll over onelogin.saml2.sp.x509certNew = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -50,8 +50,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -65,7 +65,7 @@ onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml onelogin.saml2.idp.single_logout_service.response.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutServiceResponse.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -101,7 +101,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -138,7 +138,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = S&P Java +onelogin.saml2.organization.name = S&P Java onelogin.saml2.organization.displayname = S&P Java "Example" onelogin.saml2.organization.url = http://sp.example.com?a=1&b=2 onelogin.saml2.organization.lang = en diff --git a/core/src/test/resources/config/config.allowduplicatednames.properties b/core/src/test/resources/config/config.allowduplicatednames.properties index fb5af81c..e21a60e9 100644 --- a/core/src/test/resources/config/config.allowduplicatednames.properties +++ b/core/src/test/resources/config/config.allowduplicatednames.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -37,7 +37,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOK9uFHs/nXrH9LcGorG6lB7Qs42iWK6mIE56wI7dIdsOuXf6r0ht+d+YTTis24xw+wjEHXrVN0Okh6wsKftzxo8chIo60+UB5NlKdvxAC7tpGNmrf49us/m5bdNx8IY+0pPK0c6B786UlujTvx1WFdDXh3UQPBclbWtFe5S3gLxAgMBAAECgYAPj9ngtZVZXoPWowinUbOvRmZ1ZMTVI91nsSPyCUacLM92C4I+7NuEZeYiDRUnkP7TbCyrCzXN3jwlIxdczzORhlXBBgg9Sw2fkV61CnDEMgw+aEeD5A0GDA6eTwkrawiOMs8vupjsi2/stPsa+bmpI6RnfdEKBdyDP6iQQhAxiQJBAPNtM7IMvRzlZBXoDaTTpP9rN2FR0ZcX0LT5aRZJ81qi+ZOBFeHUb6MyWvzZKfPinj9JO3s/9e3JbMXemRWBmvcCQQDuc+NfAeW200QyjoC3Ed3jueLMrY1Q3zTcSUhRPw/0pIKgRGZJerro8N6QY2JziV2mxK855gKTwwBigMHL2S9XAkEAwuBfjGDqXOG/uFHn6laNNvWshjqsIdus99Tbrj5RlfP2/YFP9VTOcsXzVYy9K0P3EA8ekVLpHQ4uCFJmF3OEjQJBAMvwO69/HOufhv1CWZ25XzAsRGhPqsRXEouw9XPfXpMavEm8FkuT9xXRJFkTVxl/i6RdJYx8Rwn/Rm34t0bUKqMCQQCrAtKCUn0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x9+QU/vJr7lMLzdoy-----END PRIVATE KEY----- @@ -49,8 +49,8 @@ onelogin.saml2.idp.entityid = https://pitbulk.no-ip.org/simplesaml/saml2/idp/met # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -59,7 +59,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -93,7 +93,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -135,7 +135,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -143,4 +143,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.certfile.properties b/core/src/test/resources/config/config.certfile.properties index 97b63c38..1f0feaa9 100644 --- a/core/src/test/resources/config/config.certfile.properties +++ b/core/src/test/resources/config/config.certfile.properties @@ -12,7 +12,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -21,7 +21,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -31,8 +31,8 @@ onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bi # Usually x509cert and privateKey of the SP are provided by files placed at # the certs folder. But we can also provide them with the following parameters -onelogin.saml2.sp.x509cert = -onelogin.saml2.sp.privatekey = +onelogin.saml2.sp.x509cert = +onelogin.saml2.sp.privatekey = # Identity Provider Data that we want connect with our SP # Identifier of the IdP entity (must be a URI) @@ -42,8 +42,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -52,17 +52,17 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP onelogin.saml2.idp.x509cert = certs/certificate1 -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha1 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example -onelogin.saml2.organization.url = http://sp.example.com \ No newline at end of file +onelogin.saml2.organization.url = http://sp.example.com diff --git a/core/src/test/resources/config/config.certstring.properties b/core/src/test/resources/config/config.certstring.properties index 7bb65492..51a8d80e 100644 --- a/core/src/test/resources/config/config.certstring.properties +++ b/core/src/test/resources/config/config.certstring.properties @@ -13,7 +13,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -22,7 +22,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -35,7 +35,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -47,8 +47,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -57,16 +57,16 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----\nMIIBrTCCAaGgAwIBAgIBATADBgEAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMB4XDTEwMTAxMTIxMTUxMloXDTE1MTAxMTIxMTUxMlowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAcMDFNhbnRhIE1vbmljYTERMA8GA1UECgwIT25lTG9naW4xGTAXBgNVBAMMEGFwcC5vbmVsb2dpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPmjfjy7L35oDpeBXBoRVCgktPkLno9DOEWB7MgYMMVKs2B6ymWQLEWrDugMK1hkzWFhIb5fqWLGbWy0J0veGR9/gHOQG+rD/I36xAXnkdiXXhzoiAG/zQxM0edMOUf40n314FC8moErcUg6QabttzesO59HFz6shPuxcWaVAgxAgMBAAEwAwYBAAMBAA==\n-----END CERTIFICATE----- -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha1 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example -onelogin.saml2.organization.url = http://sp.example.com \ No newline at end of file +onelogin.saml2.organization.url = http://sp.example.com diff --git a/core/src/test/resources/config/config.different.properties b/core/src/test/resources/config/config.different.properties index 75f2cda2..23292c67 100644 --- a/core/src/test/resources/config/config.different.properties +++ b/core/src/test/resources/config/config.different.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -36,7 +36,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -63,7 +63,7 @@ onelogin.saml2.idp.single_logout_service.url = invalid_slo_url onelogin.saml2.idp.single_logout_service.response.url = invalid_slo_response_url # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -98,7 +98,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -138,7 +138,7 @@ onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha5 # SAML specification states that no trimming for string elements should be performed, so no trimming will be # performed by default on extracted Name IDs and attribute values. However, some SAML implementations may add # undesirable surrounding whitespace when outputting XML (possibly due to formatting/pretty-printing). -# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and +# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and # attribute values. onelogin.saml2.parsing.trim_name_ids = true onelogin.saml2.parsing.trim_attribute_values = true @@ -149,4 +149,4 @@ onelogin.saml2.organization.name = SP Java # Contacts onelogin.saml2.contacts.technical.given_name = Technical Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.invalidcontacts.properties b/core/src/test/resources/config/config.invalidcontacts.properties index 66aec8ce..064d9c33 100644 --- a/core/src/test/resources/config/config.invalidcontacts.properties +++ b/core/src/test/resources/config/config.invalidcontacts.properties @@ -13,7 +13,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -22,7 +22,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -44,8 +44,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -54,22 +54,22 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIIBrTCCAaGgAwIBAgIBATADBgEAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMB4XDTEwMTAxMTIxMTUxMloXDTE1MTAxMTIxMTUxMlowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAcMDFNhbnRhIE1vbmljYTERMA8GA1UECgwIT25lTG9naW4xGTAXBgNVBAMMEGFwcC5vbmVsb2dpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPmjfjy7L35oDpeBXBoRVCgktPkLno9DOEWB7MgYMMVKs2B6ymWQLEWrDugMK1hkzWFhIb5fqWLGbWy0J0veGR9/gHOQG+rD/I36xAXnkdiXXhzoiAG/zQxM0edMOUf40n314FC8moErcUg6QabttzesO59HFz6shPuxcWaVAgxAgMBAAEwAwYBAAMBAA==-----END CERTIFICATE----- -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha1 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com # Contacts onelogin.saml2.contacts.technical.email_address = technical@example.com -onelogin.saml2.contacts.support.given_name = Support Guy \ No newline at end of file +onelogin.saml2.contacts.support.given_name = Support Guy diff --git a/core/src/test/resources/config/config.invalidspcertstring.properties b/core/src/test/resources/config/config.invalidspcertstring.properties index 1974e800..2216ce10 100644 --- a/core/src/test/resources/config/config.invalidspcertstring.properties +++ b/core/src/test/resources/config/config.invalidspcertstring.properties @@ -13,7 +13,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -22,7 +22,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -44,8 +44,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -54,16 +54,16 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIIBrTCCAaGgAwIBAgIBATADBgEAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMB4XDTEwMTAxMTIxMTUxMloXDTE1MTAxMTIxMTUxMlowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAcMDFNhbnRhIE1vbmljYTERMA8GA1UECgwIT25lTG9naW4xGTAXBgNVBAMMEGFwcC5vbmVsb2dpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPmjfjy7L35oDpeBXBoRVCgktPkLno9DOEWB7MgYMMVKs2B6ymWQLEWrDugMK1hkzWFhIb5fqWLGbWy0J0veGR9/gHOQG+rD/I36xAXnkdiXXhzoiAG/zQxM0edMOUf40n314FC8moErcUg6QabttzesO59HFz6shPuxcWaVAgxAgMBAAEwAwYBAAMBAA==-----END CERTIFICATE----- -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha1 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example -onelogin.saml2.organization.url = http://sp.example.com \ No newline at end of file +onelogin.saml2.organization.url = http://sp.example.com diff --git a/core/src/test/resources/config/config.knownIdpPrivateKey.properties b/core/src/test/resources/config/config.knownIdpPrivateKey.properties index f17fdce9..a22463ea 100644 --- a/core/src/test/resources/config/config.knownIdpPrivateKey.properties +++ b/core/src/test/resources/config/config.knownIdpPrivateKey.properties @@ -21,7 +21,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -30,7 +30,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -55,8 +55,8 @@ onelogin.saml2.idp.entityid = https://pitbulk.no-ip.org/simplesaml/saml2/idp/met # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -65,7 +65,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -147,4 +147,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.my.properties b/core/src/test/resources/config/config.my.properties index b4a43464..9a83772b 100644 --- a/core/src/test/resources/config/config.my.properties +++ b/core/src/test/resources/config/config.my.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -36,7 +36,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOK9uFHs/nXrH9LcGorG6lB7Qs42iWK6mIE56wI7dIdsOuXf6r0ht+d+YTTis24xw+wjEHXrVN0Okh6wsKftzxo8chIo60+UB5NlKdvxAC7tpGNmrf49us/m5bdNx8IY+0pPK0c6B786UlujTvx1WFdDXh3UQPBclbWtFe5S3gLxAgMBAAECgYAPj9ngtZVZXoPWowinUbOvRmZ1ZMTVI91nsSPyCUacLM92C4I+7NuEZeYiDRUnkP7TbCyrCzXN3jwlIxdczzORhlXBBgg9Sw2fkV61CnDEMgw+aEeD5A0GDA6eTwkrawiOMs8vupjsi2/stPsa+bmpI6RnfdEKBdyDP6iQQhAxiQJBAPNtM7IMvRzlZBXoDaTTpP9rN2FR0ZcX0LT5aRZJ81qi+ZOBFeHUb6MyWvzZKfPinj9JO3s/9e3JbMXemRWBmvcCQQDuc+NfAeW200QyjoC3Ed3jueLMrY1Q3zTcSUhRPw/0pIKgRGZJerro8N6QY2JziV2mxK855gKTwwBigMHL2S9XAkEAwuBfjGDqXOG/uFHn6laNNvWshjqsIdus99Tbrj5RlfP2/YFP9VTOcsXzVYy9K0P3EA8ekVLpHQ4uCFJmF3OEjQJBAMvwO69/HOufhv1CWZ25XzAsRGhPqsRXEouw9XPfXpMavEm8FkuT9xXRJFkTVxl/i6RdJYx8Rwn/Rm34t0bUKqMCQQCrAtKCUn0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x9+QU/vJr7lMLzdoy-----END PRIVATE KEY----- @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = https://pitbulk.no-ip.org/simplesaml/saml2/idp/met # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -58,7 +58,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -92,7 +92,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -132,7 +132,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -140,4 +140,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.mywithmulticert.properties b/core/src/test/resources/config/config.mywithmulticert.properties index 8218a617..e51b8074 100644 --- a/core/src/test/resources/config/config.mywithmulticert.properties +++ b/core/src/test/resources/config/config.mywithmulticert.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -36,7 +36,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOK9uFHs/nXrH9LcGorG6lB7Qs42iWK6mIE56wI7dIdsOuXf6r0ht+d+YTTis24xw+wjEHXrVN0Okh6wsKftzxo8chIo60+UB5NlKdvxAC7tpGNmrf49us/m5bdNx8IY+0pPK0c6B786UlujTvx1WFdDXh3UQPBclbWtFe5S3gLxAgMBAAECgYAPj9ngtZVZXoPWowinUbOvRmZ1ZMTVI91nsSPyCUacLM92C4I+7NuEZeYiDRUnkP7TbCyrCzXN3jwlIxdczzORhlXBBgg9Sw2fkV61CnDEMgw+aEeD5A0GDA6eTwkrawiOMs8vupjsi2/stPsa+bmpI6RnfdEKBdyDP6iQQhAxiQJBAPNtM7IMvRzlZBXoDaTTpP9rN2FR0ZcX0LT5aRZJ81qi+ZOBFeHUb6MyWvzZKfPinj9JO3s/9e3JbMXemRWBmvcCQQDuc+NfAeW200QyjoC3Ed3jueLMrY1Q3zTcSUhRPw/0pIKgRGZJerro8N6QY2JziV2mxK855gKTwwBigMHL2S9XAkEAwuBfjGDqXOG/uFHn6laNNvWshjqsIdus99Tbrj5RlfP2/YFP9VTOcsXzVYy9K0P3EA8ekVLpHQ4uCFJmF3OEjQJBAMvwO69/HOufhv1CWZ25XzAsRGhPqsRXEouw9XPfXpMavEm8FkuT9xXRJFkTVxl/i6RdJYx8Rwn/Rm34t0bUKqMCQQCrAtKCUn0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x9+QU/vJr7lMLzdoy-----END PRIVATE KEY----- @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = https://pitbulk.no-ip.org/simplesaml/saml2/idp/met # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -58,7 +58,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -94,7 +94,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -134,7 +134,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -142,4 +142,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.mywithnocert.properties b/core/src/test/resources/config/config.mywithnocert.properties index d737de60..ef1d5df6 100644 --- a/core/src/test/resources/config/config.mywithnocert.properties +++ b/core/src/test/resources/config/config.mywithnocert.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -35,7 +35,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe # the certs folder. But we can also provide them with the following parameters onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -47,8 +47,8 @@ onelogin.saml2.idp.entityid = https://pitbulk.no-ip.org/simplesaml/saml2/idp/met # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -57,7 +57,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -92,7 +92,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -129,7 +129,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -137,4 +137,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.newattack.properties b/core/src/test/resources/config/config.newattack.properties index 3255de68..a7d8b83a 100644 --- a/core/src/test/resources/config/config.newattack.properties +++ b/core/src/test/resources/config/config.newattack.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -35,7 +35,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe # the certs folder. But we can also provide them with the following parameters onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICGzCCAYQCCQCNNcQXom32VDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSU4xFTATBgNVBAcTDEluZGlhbmFwb2xpczERMA8GA1UEChMIT25lTG9naW4xDDAKBgNVBAsTA0VuZzAeFw0xNDA0MjMxODQxMDFaFw0xNTA0MjMxODQxMDFaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTjEVMBMGA1UEBxMMSW5kaWFuYXBvbGlzMREwDwYDVQQKEwhPbmVMb2dpbjEMMAoGA1UECxMDRW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALM2vGCiQ/vm+a6v40+VX2zdqHA2Q/1vF1ibQzJ54MJCOVWvs+vQXfZFhdm0OPM2IrDU7oqvKPqP6xOAeJK6H0yP7M4YL3fatSvIYmmfyXC9kt3Svz/NyrHzPhUnJ0ye/sUSXxnzQxwcm/9PwAqrQaA3QpQkH57ybF/OoryPe+2h-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 #onelogin.saml2.sp.privatekey = -----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABAoGBALGR6bRBit+yV5TUU3MZSrf8WQSLWDLgs/33FQSAEYSib4+DJke2lKbI6jkGUoSJgFUXFbaQLtMY2+3VDsMKPBdAge9gIdvbkC4yoKjLGm/FBDOxxZcfLpR+9OPqU3qM9D0CNuliBWI7Je+p/zs09HIYucpDXy9E18KA1KNF6rfhAkEA9KoNam6wAKnmvMzz31ws3RuIOUeo2rx6aaVY95+P9tTxd6U+pNkwxy1aCGP+InVSwlYNA1aQ4Axi/GdMIWMkxwJBAPO1CP7cQNZQmu7yusY+GUObDII5YK9WLaY4RAicn5378crPBFxvUkqf9G6FHo7u88iTCIp+vwa3Hn9Tumg3iP0CQQDgUXWBasCVqzCxU5wY4tMDWjXYhpoLCpmVeRML3dDJt004rFm2HKe7Rhpw7PTZNQZOxUSjFeA4e0LaNf838UWLAkB8QfbHM3ffjhOg96PhhjINdVWoZCb230LBOHj/xxPfUmFTHcBEfQIBSJMxcrBFAnLL9qPpMXymqOFk3ETz9DTlAj8E0qGbp78aVbTOtuwEwNJII+RPw+Zkc+lKR+yaWkAzfIXw527NPHH3+rnBG72wyZr9ud4LAum9jh+5No1LQpk=-----END RSA PRIVATE KEY----- onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOjqb5Bm9hD/EvQSUuC6krVANxgvh/k9yTCw2BL2lS9Xt/NOoIeTxOEvFOTjYxDYxwmw55QlU/vbwqHKaMUKrGA/hW7BGT2ukCXT6aHLow93KPIDobXiOsNZLrnKwtyEri3+/CkQPPRJCUSgbWQzOWVKbvNlLdet6ADsOM1pRhCrAgMBAAECgYEAsZHptEGK37JXlNRTcxlKt/xZBItYMuCz/fcVBIARhKJvj4MmR7aUpsjqOQZShImAVRcVtpAu0xjb7dUOwwo8F0CB72Ah29uQLjKgqMsab8UEM7HFlx8ulH704+pTeoz0PQI26WIFYjsl76n/OzT0chi5ykNfL0TXwoDUo0Xqt+ECQQD0qg1qbrAAqea8zPPfXCzdG4g5R6javHpppVj3n4/21PF3pT6k2TDHLVoIY/4idVLCVg0DVpDgDGL8Z0whYyTHAkEA87UI/txA1lCa7vK6xj4ZQ5sMgjlgr1YtpjhECJyfnfvxys8EXG9SSp/0boUeju7zyJMIin6/Brcef1O6aDeI/QJBAOBRdYFqwJWrMLFTnBji0wNaNdiGmgsKmZV5Ewvd0Mm3TTisWbYcp7tGGnDs9Nk1Bk7FRKMV4Dh7Qto1/zfxRYsCQHxB9sczd9+OE6D3o+GGMg11VahkJvbfQsE4eP/HE99SYVMdwER9AgFIkzFysEUCcsv2o+kxfKao4WTcRPP0NOUCPwTSoZunvxpVtM627ATA0kgj5E/D5mRz6UpH7JpaQDN8hfDnbs08cff6ucEbvbDJmv253gsC6b2OH7k2jUtCmQ==-----END PRIVATE KEY----- @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -58,12 +58,12 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP -#onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQ0FADA8MQswCQYDVQQGEwJ1czEPMA0GA1UECAwGSGF3YWlpMQswCQYDVQQKDAJNZTEPMA0GA1UEAwwGbWUuY29tMB4XDTE2MDYxNDE0MDIxM1oXDTE3MDYxNDE0MDIxM1owPDELMAkGA1UEBhMCdXMxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UECgwCTWUxDzANBgNVBAMMBm1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5xWsnAmIgCwkwbQodP4eiLAUOPmuurlV29whcGt6Ac3hvOQtnMm9gdlNJrvjlv4ZaG3H6A0Akys811Amdm+oKveXymFoLG4KHLMjTMIfQvKOl8Id/+Uvx69Zdw/0ouemhIagpw1z/bOXzL/i/3KxGJg8nwaV3dxtbPNSFzcDvy0CAwEAAaNQME4wHQYDVR0OBBYEFE4gjnKB5yJGWZMcu5lHlRnSAae2MB8GA1UdIwQYMBaAFE4gjnKB5yJGWZMcu5lHlRnSAae2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADgYEAOsmRx6tknVDHC8E+Eas2eF6O4Hm15Yt5XAjzIX3OiE2zvqm3fOk3HNjcHOAIFB7Mdvr6+23ARXpZFKiS2+MkUs5wmEzCLqU/hROyjyj9PYG1jMPrAHPOpWjVtlWuJslN28I6ziM8uq+uitTjIdt8JZ6P2dWtoTmDgsVUmFM0naU=-----END CERTIFICATE----- +#onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQ0FADA8MQswCQYDVQQGEwJ1czEPMA0GA1UECAwGSGF3YWlpMQswCQYDVQQKDAJNZTEPMA0GA1UEAwwGbWUuY29tMB4XDTE2MDYxNDE0MDIxM1oXDTE3MDYxNDE0MDIxM1owPDELMAkGA1UEBhMCdXMxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UECgwCTWUxDzANBgNVBAMMBm1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5xWsnAmIgCwkwbQodP4eiLAUOPmuurlV29whcGt6Ac3hvOQtnMm9gdlNJrvjlv4ZaG3H6A0Akys811Amdm+oKveXymFoLG4KHLMjTMIfQvKOl8Id/+Uvx69Zdw/0ouemhIagpw1z/bOXzL/i/3KxGJg8nwaV3dxtbPNSFzcDvy0CAwEAAaNQME4wHQYDVR0OBBYEFE4gjnKB5yJGWZMcu5lHlRnSAae2MB8GA1UdIwQYMBaAFE4gjnKB5yJGWZMcu5lHlRnSAae2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADgYEAOsmRx6tknVDHC8E+Eas2eF6O4Hm15Yt5XAjzIX3OiE2zvqm3fOk3HNjcHOAIFB7Mdvr6+23ARXpZFKiS2+MkUs5wmEzCLqU/hROyjyj9PYG1jMPrAHPOpWjVtlWuJslN28I6ziM8uq+uitTjIdt8JZ6P2dWtoTmDgsVUmFM0naU=-----END CERTIFICATE----- onelogin.saml2.idp.certfingerprint = 385b1eec71143f00db6af936e2ea12a28771d72c onelogin.saml2.idp.certfingerprint_algorithm = sha1 @@ -94,7 +94,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -131,7 +131,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -139,4 +139,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.newattack2.properties b/core/src/test/resources/config/config.newattack2.properties index 80a5d8f6..5f08a1c9 100644 --- a/core/src/test/resources/config/config.newattack2.properties +++ b/core/src/test/resources/config/config.newattack2.properties @@ -14,13 +14,13 @@ onelogin.saml2.sp.entityid = example.com # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = https://example.com/endpoint # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -32,7 +32,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe # the certs folder. But we can also provide them with the following parameters onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICGzCCAYQCCQCNNcQXom32VDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSU4xFTATBgNVBAcTDEluZGlhbmFwb2xpczERMA8GA1UEChMIT25lTG9naW4xDDAKBgNVBAsTA0VuZzAeFw0xNDA0MjMxODQxMDFaFw0xNTA0MjMxODQxMDFaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTjEVMBMGA1UEBxMMSW5kaWFuYXBvbGlzMREwDwYDVQQKEwhPbmVMb2dpbjEMMAoGA1UECxMDRW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALM2vGCiQ/vm+a6v40+VX2zdqHA2Q/1vF1ibQzJ54MJCOVWvs+vQXfZFhdm0OPM2IrDU7oqvKPqP6xOAeJK6H0yP7M4YL3fatSvIYmmfyXC9kt3Svz/NyrHzPhUnJ0ye/sUSXxnzQxwcm/9PwAqrQaA3QpQkH57ybF/OoryPe+2h-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 #onelogin.saml2.sp.privatekey = -----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABAoGBALGR6bRBit+yV5TUU3MZSrf8WQSLWDLgs/33FQSAEYSib4+DJke2lKbI6jkGUoSJgFUXFbaQLtMY2+3VDsMKPBdAge9gIdvbkC4yoKjLGm/FBDOxxZcfLpR+9OPqU3qM9D0CNuliBWI7Je+p/zs09HIYucpDXy9E18KA1KNF6rfhAkEA9KoNam6wAKnmvMzz31ws3RuIOUeo2rx6aaVY95+P9tTxd6U+pNkwxy1aCGP+InVSwlYNA1aQ4Axi/GdMIWMkxwJBAPO1CP7cQNZQmu7yusY+GUObDII5YK9WLaY4RAicn5378crPBFxvUkqf9G6FHo7u88iTCIp+vwa3Hn9Tumg3iP0CQQDgUXWBasCVqzCxU5wY4tMDWjXYhpoLCpmVeRML3dDJt004rFm2HKe7Rhpw7PTZNQZOxUSjFeA4e0LaNf838UWLAkB8QfbHM3ffjhOg96PhhjINdVWoZCb230LBOHj/xxPfUmFTHcBEfQIBSJMxcrBFAnLL9qPpMXymqOFk3ETz9DTlAj8E0qGbp78aVbTOtuwEwNJII+RPw+Zkc+lKR+yaWkAzfIXw527NPHH3+rnBG72wyZr9ud4LAum9jh+5No1LQpk=-----END RSA PRIVATE KEY----- onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOjqb5Bm9hD/EvQSUuC6krVANxgvh/k9yTCw2BL2lS9Xt/NOoIeTxOEvFOTjYxDYxwmw55QlU/vbwqHKaMUKrGA/hW7BGT2ukCXT6aHLow93KPIDobXiOsNZLrnKwtyEri3+/CkQPPRJCUSgbWQzOWVKbvNlLdet6ADsOM1pRhCrAgMBAAECgYEAsZHptEGK37JXlNRTcxlKt/xZBItYMuCz/fcVBIARhKJvj4MmR7aUpsjqOQZShImAVRcVtpAu0xjb7dUOwwo8F0CB72Ah29uQLjKgqMsab8UEM7HFlx8ulH704+pTeoz0PQI26WIFYjsl76n/OzT0chi5ykNfL0TXwoDUo0Xqt+ECQQD0qg1qbrAAqea8zPPfXCzdG4g5R6javHpppVj3n4/21PF3pT6k2TDHLVoIY/4idVLCVg0DVpDgDGL8Z0whYyTHAkEA87UI/txA1lCa7vK6xj4ZQ5sMgjlgr1YtpjhECJyfnfvxys8EXG9SSp/0boUeju7zyJMIin6/Brcef1O6aDeI/QJBAOBRdYFqwJWrMLFTnBji0wNaNdiGmgsKmZV5Ewvd0Mm3TTisWbYcp7tGGnDs9Nk1Bk7FRKMV4Dh7Qto1/zfxRYsCQHxB9sczd9+OE6D3o+GGMg11VahkJvbfQsE4eP/HE99SYVMdwER9AgFIkzFysEUCcsv2o+kxfKao4WTcRPP0NOUCPwTSoZunvxpVtM627ATA0kgj5E/D5mRz6UpH7JpaQDN8hfDnbs08cff6ucEbvbDJmv253gsC6b2OH7k2jUtCmQ==-----END PRIVATE KEY----- @@ -45,8 +45,8 @@ onelogin.saml2.idp.entityid = idp.example.com # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/saml/sso -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -55,12 +55,12 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/saml/slo # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Public x509 certificate of the IdP -#onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQ0FADA8MQswCQYDVQQGEwJ1czEPMA0GA1UECAwGSGF3YWlpMQswCQYDVQQKDAJNZTEPMA0GA1UEAwwGbWUuY29tMB4XDTE2MDYxNDE0MDIxM1oXDTE3MDYxNDE0MDIxM1owPDELMAkGA1UEBhMCdXMxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UECgwCTWUxDzANBgNVBAMMBm1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5xWsnAmIgCwkwbQodP4eiLAUOPmuurlV29whcGt6Ac3hvOQtnMm9gdlNJrvjlv4ZaG3H6A0Akys811Amdm+oKveXymFoLG4KHLMjTMIfQvKOl8Id/+Uvx69Zdw/0ouemhIagpw1z/bOXzL/i/3KxGJg8nwaV3dxtbPNSFzcDvy0CAwEAAaNQME4wHQYDVR0OBBYEFE4gjnKB5yJGWZMcu5lHlRnSAae2MB8GA1UdIwQYMBaAFE4gjnKB5yJGWZMcu5lHlRnSAae2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADgYEAOsmRx6tknVDHC8E+Eas2eF6O4Hm15Yt5XAjzIX3OiE2zvqm3fOk3HNjcHOAIFB7Mdvr6+23ARXpZFKiS2+MkUs5wmEzCLqU/hROyjyj9PYG1jMPrAHPOpWjVtlWuJslN28I6ziM8uq+uitTjIdt8JZ6P2dWtoTmDgsVUmFM0naU=-----END CERTIFICATE----- +#onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQ0FADA8MQswCQYDVQQGEwJ1czEPMA0GA1UECAwGSGF3YWlpMQswCQYDVQQKDAJNZTEPMA0GA1UEAwwGbWUuY29tMB4XDTE2MDYxNDE0MDIxM1oXDTE3MDYxNDE0MDIxM1owPDELMAkGA1UEBhMCdXMxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UECgwCTWUxDzANBgNVBAMMBm1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5xWsnAmIgCwkwbQodP4eiLAUOPmuurlV29whcGt6Ac3hvOQtnMm9gdlNJrvjlv4ZaG3H6A0Akys811Amdm+oKveXymFoLG4KHLMjTMIfQvKOl8Id/+Uvx69Zdw/0ouemhIagpw1z/bOXzL/i/3KxGJg8nwaV3dxtbPNSFzcDvy0CAwEAAaNQME4wHQYDVR0OBBYEFE4gjnKB5yJGWZMcu5lHlRnSAae2MB8GA1UdIwQYMBaAFE4gjnKB5yJGWZMcu5lHlRnSAae2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADgYEAOsmRx6tknVDHC8E+Eas2eF6O4Hm15Yt5XAjzIX3OiE2zvqm3fOk3HNjcHOAIFB7Mdvr6+23ARXpZFKiS2+MkUs5wmEzCLqU/hROyjyj9PYG1jMPrAHPOpWjVtlWuJslN28I6ziM8uq+uitTjIdt8JZ6P2dWtoTmDgsVUmFM0naU=-----END CERTIFICATE----- onelogin.saml2.idp.certfingerprint = 4b68c453c7d994aad9025c99d5efcf566287fe8d onelogin.saml2.idp.certfingerprint_algorithm = sha1 @@ -91,7 +91,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -128,7 +128,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -136,4 +136,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.samecerts.properties b/core/src/test/resources/config/config.samecerts.properties index 9d94a4d3..bae8d2f4 100644 --- a/core/src/test/resources/config/config.samecerts.properties +++ b/core/src/test/resources/config/config.samecerts.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -35,7 +35,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe # the certs folder. But we can also provide them with the following parameters onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICeDCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wHhcNMTUxMDE4MjAxMjM1WhcNMTgwNzE0MjAxMjM1WjBZMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lTG9naW4gSW5jMR4wHAYDVQQDDBVqYXZhLXNhbWwuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAGjUDBOMB0GA1UdDgQWBBTifMwN3CQ5ZOPkV5tDJsutU8teFDAfBgNVHSMEGDAWgBTifMwN3CQ5ZOPkV5tDJsutU8teFDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAG3nAEUjJaA75SkzID5FKLolsxG5TE/0HU0+yEUAVkXiqvqN4mPWq/JjoK5+uP4LEZIb4pRrCqI3iHp+vazLLYSeyV3kaGN7q35Afw8nk8WM0f7vImbQ69j1S8GQ+6E0PEI26qBLykGkMn3GUVtBBWSdpP093NuNLJiOomnHqhqj-----END CERTIFICATE----- -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALvwEktX1+4y2AhEqxVwOO6HO7Wtzi3hr5becRkfLYGjNSyhzZCjI1DsNL61JSWDO3nviZd9fSkFnRC4akFUm0CS6GJ7TZe4T5o+9aowQ6N8e8cts9XPXyP6Inz7q4sD8pO2EInlfwHYPQCqFmz/SDW7cDgIC8vb0ygOsiXdreANAgMBAAECgYA7VPVRl+/xoVeWdKdWY1F17HerSa23ynI2vQ8TkUY6kR3ucz6ElRxHJesY8fNCPoX+XuMfUly7IKyPZMkWyvEgDPo7J5mYqP5VsTK0Li4AwR/BA93Aw6gaX7/EYi3HjBh8QdNSt4fi9yOea/hv04yfR9Lx/a5fvQIyhqaDtT2QeQJBAOnCgnxnj70/sv9UsFPa8t1OGdAfXtOgEoklh1F2NR9jid6FPw5E98eCpdZ00MfRrmUavgqg6Y4swZISyzJIjGMCQQDN0YNsC4S+eJJM6aOCpupKluWE/cCWB01UQYekyXH7OdUtl49NlKEUPBSAvtaLMuMKlTNOjlPrx4Q+/c5i0vTPAkEA5H7CR9J/OZETaewhc8ZYkaRvLPYNHjWhCLhLXoB6itUkhgOfUFZwEXAOpOOI1VmL675JN2B1DAmJqTx/rQYnWwJBAMx3ztsAmnBq8dTM6y65ydouDHhRawjg2jbRHwNbSQvuyVSQ08Gb3WZvxWKdtB/3fsydqqnpBYAf5sZ5eJZ+wssCQAOiIKnhdYe+RBbBwykzjUqtzEmt4fwCFE8tD4feEx77D05j5f7u7KYh1mL0G2zIbnUryi7jwc4ye98VirRpZ1w=-----END PRIVATE KEY----- @@ -47,8 +47,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -57,7 +57,7 @@ onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0: onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -91,7 +91,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -128,7 +128,7 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com @@ -136,4 +136,4 @@ onelogin.saml2.organization.url = http://sp.example.com onelogin.saml2.contacts.technical.given_name = Technical Guy onelogin.saml2.contacts.technical.email_address = technical@example.com onelogin.saml2.contacts.support.given_name = Support Guy -onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file +onelogin.saml2.contacts.support.email_address = support@example.com diff --git a/core/src/test/resources/config/config.somevaluesempty.properties b/core/src/test/resources/config/config.somevaluesempty.properties index 60d87e8f..7d32326a 100644 --- a/core/src/test/resources/config/config.somevaluesempty.properties +++ b/core/src/test/resources/config/config.somevaluesempty.properties @@ -14,7 +14,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata. # URL Location where the from the IdP will be returned onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -23,7 +23,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp # SAML protocol binding for the Single Logout Service of the SP. -# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +# SAMLToolkit supports for this endpoint the HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # Specifies constraints on the name identifier to be used to @@ -36,7 +36,7 @@ onelogin.saml2.sp.nameidformat = onelogin.saml2.sp.x509cert = -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = @@ -48,8 +48,8 @@ onelogin.saml2.idp.entityid = http://idp.example.com/ # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = http://idp.example.com/simplesaml/saml2/idp/SSOService.php -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -63,7 +63,7 @@ onelogin.saml2.idp.single_logout_service.url = http://idp.example.com/simplesaml onelogin.saml2.idp.single_logout_service.response.url = # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -98,7 +98,7 @@ onelogin.saml2.security.want_messages_signed = true onelogin.saml2.security.want_assertions_signed = true # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null/false (in order to not sign) or true (sign using SP private key) +# Right now supported null/false (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = true # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -135,7 +135,7 @@ onelogin.saml2.security.signature_algorithm = onelogin.saml2.security.digest_algorithm = # Organization -onelogin.saml2.organization.name = +onelogin.saml2.organization.name = onelogin.saml2.organization.displayname = onelogin.saml2.organization.url = @@ -143,4 +143,4 @@ onelogin.saml2.organization.url = onelogin.saml2.contacts.technical.given_name = onelogin.saml2.contacts.technical.email_address = onelogin.saml2.contacts.support.given_name = -onelogin.saml2.contacts.support.email_address = \ No newline at end of file +onelogin.saml2.contacts.support.email_address = diff --git a/pom.xml b/pom.xml index 1e4cabea..d6ebe7a8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,9 +5,9 @@ 2.9.1-SNAPSHOT pom - OneLogin java-saml Toolkit Project - A Java SAML toolkit by OneLogin - https://github.com/onelogin/java-saml + java-saml Toolkit Project + A Java SAML toolkit + https://github.com/saml-toolkit/java-saml UTF-8 @@ -154,9 +154,9 @@ - scm:git:git@github.com:onelogin/java-saml.git - scm:git:git@github.com:onelogin/java-saml.git - https://github.com/onelogin/java-saml + scm:git:git@github.com:saml-toolkit/java-saml.git + scm:git:git@github.com:saml-toolkit/java-saml.git + https://github.com/saml-toolkit/java-saml HEAD @@ -172,7 +172,7 @@ Sixto Martín García https://github.com/pitbulk - OneLogin + SAML Toolkit diff --git a/samples/java-saml-tookit-jspsample/pom.xml b/samples/java-saml-tookit-jspsample/pom.xml index 13afeb5b..d960d4f7 100644 --- a/samples/java-saml-tookit-jspsample/pom.xml +++ b/samples/java-saml-tookit-jspsample/pom.xml @@ -8,7 +8,7 @@ java-saml-tookit-jspsample war - OneLogin java-saml Toolkit Sample Webapp + java-saml Toolkit Sample Webapp diff --git a/samples/java-saml-tookit-jspsample/src/main/resources/onelogin.saml.properties b/samples/java-saml-tookit-jspsample/src/main/resources/onelogin.saml.properties index ce813fd3..e7249704 100644 --- a/samples/java-saml-tookit-jspsample/src/main/resources/onelogin.saml.properties +++ b/samples/java-saml-tookit-jspsample/src/main/resources/onelogin.saml.properties @@ -19,7 +19,7 @@ onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-tookit-jspsample/me onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-tookit-jspsample/acs.jsp # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-POST binding only onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST @@ -28,7 +28,7 @@ onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2 onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-tookit-jspsample/sls.jsp # SAML protocol binding to be used when returning the or sending the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -42,7 +42,7 @@ onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspe onelogin.saml2.sp.x509cert = -# Requires Format PKCS#8 BEGIN PRIVATE KEY +# Requires Format PKCS#8 BEGIN PRIVATE KEY # 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 onelogin.saml2.sp.privatekey = @@ -56,8 +56,8 @@ onelogin.saml2.idp.entityid = # URL Target of the IdP where the SP will send the Authentication Request Message onelogin.saml2.idp.single_sign_on_service.url = -# SAML protocol binding to be used to deliver the message -# to the IdP. Onelogin Toolkit supports for this endpoint the +# SAML protocol binding to be used to deliver the message +# to the IdP. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -71,7 +71,7 @@ onelogin.saml2.idp.single_logout_service.url = onelogin.saml2.idp.single_logout_service.response.url = # SAML protocol binding to be used when returning the -# message. Onelogin Toolkit supports for this endpoint the +# message. SAMLToolkit supports for this endpoint the # HTTP-Redirect binding only onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect @@ -85,7 +85,7 @@ onelogin.saml2.idp.x509cert = # If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to # let the toolkit know which Algorithm was used. Possible values: sha1, sha256, sha384 or sha512 # 'sha1' is the default value. -# onelogin.saml2.idp.certfingerprint = +# onelogin.saml2.idp.certfingerprint = # onelogin.saml2.idp.certfingerprint_algorithm = sha256 @@ -116,7 +116,7 @@ onelogin.saml2.security.want_messages_signed = false onelogin.saml2.security.want_assertions_signed = false # Indicates a requirement for the Metadata of this SP to be signed. -# Right now supported null (in order to not sign) or true (sign using SP private key) +# Right now supported null (in order to not sign) or true (sign using SP private key) onelogin.saml2.security.sign_metadata = # Indicates a requirement for the Assertions received by this SP to be encrypted @@ -153,16 +153,16 @@ onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig- # 'http://www.w3.org/2001/04/xmlenc#sha256' # 'http://www.w3.org/2001/04/xmldsig-more#sha384' # 'http://www.w3.org/2001/04/xmlenc#sha512' -onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha256 +onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha256 # Reject Signatures with deprecated algorithms (sha1) onelogin.saml2.security.reject_deprecated_alg = true # Organization -onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.name = SP Java onelogin.saml2.organization.displayname = SP Java Example onelogin.saml2.organization.url = http://sp.example.com -onelogin.saml2.organization.lang = +onelogin.saml2.organization.lang = # Contacts onelogin.saml2.contacts.technical.given_name = Technical Guy diff --git a/samples/java-saml-tookit-jspsample/src/main/webapp/acs.jsp b/samples/java-saml-tookit-jspsample/src/main/webapp/acs.jsp index 99d640d8..9c8ff2e0 100644 --- a/samples/java-saml-tookit-jspsample/src/main/webapp/acs.jsp +++ b/samples/java-saml-tookit-jspsample/src/main/webapp/acs.jsp @@ -2,7 +2,7 @@ <%@page import="com.onelogin.saml2.servlet.ServletUtils"%> <%@page import="java.util.Collection"%> <%@page import="java.util.List"%> -<%@page import="java.util.Map"%> +<%@page import="java.util.Map"%> <%@page import="org.apache.commons.lang3.StringUtils" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> @@ -12,7 +12,7 @@ - A Java SAML Toolkit by OneLogin demo + A Java SAML Toolkit @@ -24,9 +24,9 @@
-

A Java SAML Toolkit by OneLogin demo

+

A Java SAML Toolkit

- + <% Auth auth = new Auth(request, response); @@ -61,7 +61,7 @@ session.setAttribute("sessionIndex", sessionIndex); session.setAttribute("nameidNameQualifier", nameidNameQualifier); session.setAttribute("nameidSPNameQualifier", nameidSPNameQualifier); - + String relayState = request.getParameter("RelayState"); @@ -69,12 +69,12 @@ !relayState.contains("/dologin.jsp")) { // We don't want to be redirected to login.jsp neither response.sendRedirect(request.getParameter("RelayState")); } else { - + if (attributes.isEmpty()) { %> - <% + <% } else { %> @@ -86,7 +86,7 @@ - <% + <% Collection keys = attributes.keySet(); for(String name :keys){ out.println("" + name + ""); @@ -94,13 +94,13 @@ for(String value :values) { out.println("
  • " + value + "
  • "); } - + out.println(""); } %> - <% + <% } %> See user data stored at session diff --git a/samples/java-saml-tookit-jspsample/src/main/webapp/attrs.jsp b/samples/java-saml-tookit-jspsample/src/main/webapp/attrs.jsp index f98e2cea..65c4aced 100644 --- a/samples/java-saml-tookit-jspsample/src/main/webapp/attrs.jsp +++ b/samples/java-saml-tookit-jspsample/src/main/webapp/attrs.jsp @@ -13,7 +13,7 @@ - A Java SAML Toolkit by OneLogin demo + A Java SAML Toolkit @@ -25,19 +25,19 @@
    -

    A Java SAML Toolkit by OneLogin demo

    +

    A Java SAML Toolkit

    <% Boolean found = false; @SuppressWarnings("unchecked") - Enumeration elems = (Enumeration) session.getAttributeNames(); - + Enumeration elems = (Enumeration) session.getAttributeNames(); + while (elems.hasMoreElements() && !found) { String value = (String) elems.nextElement(); if (value.equals("attributes") || value.equals("nameId")) { found = true; } } - + if (found) { String nameId = (String) session.getAttribute("nameId"); @SuppressWarnings("unchecked") @@ -46,11 +46,11 @@ if (!nameId.isEmpty()) { out.println("
    NameId: " + nameId + "
    "); } - + if (attributes.isEmpty()) { %> - <% + <% } else { %> @@ -63,7 +63,7 @@ - <% + <% Collection keys = attributes.keySet(); for(String name :keys){ out.println("" + name + ""); @@ -71,7 +71,7 @@ for(String value :values) { out.println("
  • " + value + "
  • "); } - + out.println(""); } %> diff --git a/samples/java-saml-tookit-jspsample/src/main/webapp/index.jsp b/samples/java-saml-tookit-jspsample/src/main/webapp/index.jsp index b783a4e8..9483fb2d 100644 --- a/samples/java-saml-tookit-jspsample/src/main/webapp/index.jsp +++ b/samples/java-saml-tookit-jspsample/src/main/webapp/index.jsp @@ -6,7 +6,7 @@ - A Java SAML Toolkit by OneLogin demo + A Java SAML Toolkit @@ -18,7 +18,7 @@
    -

    A Java SAML Toolkit by OneLogin demo

    +

    A Java SAML Toolkit

    Login Login and access to attrs.jsp page
    diff --git a/samples/java-saml-tookit-jspsample/src/main/webapp/sls.jsp b/samples/java-saml-tookit-jspsample/src/main/webapp/sls.jsp index bf80405c..83f2ad7d 100644 --- a/samples/java-saml-tookit-jspsample/src/main/webapp/sls.jsp +++ b/samples/java-saml-tookit-jspsample/src/main/webapp/sls.jsp @@ -2,7 +2,7 @@ <%@page import="java.util.Collection"%> <%@page import="java.util.HashMap"%> <%@page import="java.util.List"%> -<%@page import="java.util.Map"%> +<%@page import="java.util.Map"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> @@ -11,7 +11,7 @@ - A Java SAML Toolkit by OneLogin demo + A Java SAML Toolkit @@ -23,14 +23,14 @@
    -

    A Java SAML Toolkit by OneLogin demo

    - Logout +

    A Java SAML Toolkit

    + Logout <% Auth auth = new Auth(request, response); auth.processSLO(); - + List errors = auth.getErrors(); - + if (errors.isEmpty()) { out.println("

    Sucessfully logged out

    "); out.println("Login"); diff --git a/samples/pom.xml b/samples/pom.xml index 799ec247..36ab644b 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -7,7 +7,7 @@ java-saml-tookit-samples - OneLogin java-saml Toolkit Samples + java-saml Toolkit Samples pom diff --git a/toolkit/pom.xml b/toolkit/pom.xml index 47e8b5d2..37d2f787 100644 --- a/toolkit/pom.xml +++ b/toolkit/pom.xml @@ -7,7 +7,7 @@ jar - OneLogin java-saml Toolkit + java-saml Toolkit java-saml diff --git a/toolkit/src/main/java/com/onelogin/saml2/Auth.java b/toolkit/src/main/java/com/onelogin/saml2/Auth.java index 511914b8..6d035df9 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/Auth.java +++ b/toolkit/src/main/java/com/onelogin/saml2/Auth.java @@ -42,7 +42,7 @@ import com.onelogin.saml2.util.Util; /** - * Main class of OneLogin's Java Toolkit. + * Main class of Java Toolkit. * * This class implements the SP SAML instance. * Defines the methods that you can invoke in your application in @@ -106,7 +106,7 @@ public class Auth { * The ID of the last message processed */ private String lastMessageId; - + /** * The issue instant of the last message processed */ @@ -169,9 +169,9 @@ public class Auth { * encrypted, by default tries to return the decrypted XML */ private String lastResponse; - + private static final SamlMessageFactory DEFAULT_SAML_MESSAGE_FACTORY = new SamlMessageFactory() {}; - + private SamlMessageFactory samlMessageFactory = DEFAULT_SAML_MESSAGE_FACTORY; /** @@ -197,7 +197,7 @@ public Auth() throws IOException, SettingsException, Error { public Auth(KeyStoreSettings keyStoreSetting) throws IOException, SettingsException, Error { this("onelogin.saml.properties", keyStoreSetting); } - + /** * Initializes the SP SAML instance. * @@ -242,7 +242,7 @@ public Auth(HttpServletRequest request, HttpServletResponse response) throws IOE /** * Initializes the SP SAML instance. - * + * * @param keyStoreSetting KeyStoreSettings is a KeyStore which have the Private/Public keys * @param request HttpServletRequest object to be processed * @param response HttpServletResponse object to be used @@ -616,11 +616,11 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo */ public String login(String relayState, AuthnRequestParams authnRequestParams, Boolean stay, Map parameters) throws IOException, SettingsException { AuthnRequest authnRequest = samlMessageFactory.createAuthnRequest(settings, authnRequestParams); - + if (parameters == null) { parameters = new HashMap(); } - + String samlRequest = authnRequest.getEncodedAuthnRequest(); parameters.put("SAMLRequest", samlRequest); @@ -628,7 +628,7 @@ public String login(String relayState, AuthnRequestParams authnRequestParams, Bo if (relayState == null) { relayState = ServletUtils.getSelfRoutedURLNoQuery(request); } - + if (!relayState.isEmpty()) { parameters.put("RelayState", relayState); } @@ -1137,7 +1137,7 @@ public void logout(String relayState, String nameId, String sessionIndex) /** * Initiates the SLO process. - * + * * @throws IOException * @throws SettingsException */ @@ -1323,7 +1323,7 @@ public String processSLO(Boolean keepLocalSession, String requestId, Boolean sta } String inResponseTo = logoutRequest.id; - LogoutResponse logoutResponseBuilder = samlMessageFactory.createOutgoingLogoutResponse(settings, + LogoutResponse logoutResponseBuilder = samlMessageFactory.createOutgoingLogoutResponse(settings, new LogoutResponseParams(inResponseTo, Constants.STATUS_SUCCESS)); lastResponse = logoutResponseBuilder.getLogoutResponseXml(); @@ -1463,10 +1463,10 @@ public final DateTime getSessionExpiration() { public String getLastMessageId() { return lastMessageId; } - + /** * Returns the issue instant of the last message processed. - * + * * @return The issue instant of the last message processed */ public Calendar getLastMessageIssueInstant() { @@ -1516,10 +1516,10 @@ public Exception getLastValidationException() { public String getLastRequestId() { return lastRequestId; } - + /** * Returns the issue instant of the last request generated (AuthnRequest or LogoutRequest). - * + * * @return the issue instant of the last request generated (AuthnRequest or LogoutRequest), * null if none */ @@ -1593,7 +1593,7 @@ public String buildResponseSignature(String samlResponse, String relayState, Str private String buildSignature(String samlMessage, String relayState, String signAlgorithm, String type) throws SettingsException, IllegalArgumentException { String signature = ""; - + if (!settings.checkSPCerts()) { String errorMsg = "Trying to sign the " + type + " but can't load the SP private key"; LOGGER.error("buildSignature error. " + errorMsg); @@ -1601,16 +1601,16 @@ private String buildSignature(String samlMessage, String relayState, String sign } PrivateKey key = settings.getSPkey(); - + String msg = type + "=" + Util.urlEncoder(samlMessage); if (StringUtils.isNotEmpty(relayState)) { msg += "&RelayState=" + Util.urlEncoder(relayState); } - + if (StringUtils.isEmpty(signAlgorithm)) { signAlgorithm = Constants.RSA_SHA1; } - + msg += "&SigAlg=" + Util.urlEncoder(signAlgorithm); try { @@ -1656,7 +1656,7 @@ public String getLastResponseXML() { *

    * This allows consumers to provide their own extension classes for SAML message * XML generation and/or processing. - * + * * @param samlMessageFactory * the factory to use to create SAML message objects; if * null, a default provider will be used which creates diff --git a/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java b/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java index c62bdd71..1c2f7bb9 100644 --- a/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java +++ b/toolkit/src/main/java/com/onelogin/saml2/servlet/ServletUtils.java @@ -15,7 +15,7 @@ import com.onelogin.saml2.util.Util; /** - * ServletUtils class of OneLogin's Java Toolkit. + * ServletUtils class of Java Toolkit. * * A class that contains several auxiliary methods related to HttpServletRequest and HttpServletResponse */ @@ -24,7 +24,7 @@ public class ServletUtils { private ServletUtils() { //not called } - + /** * Creates an HttpRequest from an HttpServletRequest. * @@ -148,7 +148,7 @@ public static String getSelfRoutedURLNoQuery(HttpServletRequest request) { * GET parameters to be added * @param stay * True if we want to stay (returns the url string) False to execute redirection - * + * * @return string the target URL * @throws IOException * @@ -197,7 +197,7 @@ public static String sendRedirect(HttpServletResponse response, String location, public static void sendRedirect(HttpServletResponse response, String location, Map parameters) throws IOException { sendRedirect(response, location, parameters, false); } - + /** * Redirect to location url * From 684bfe045bc3fdb0a4fde2f266dd45dcd16a0fd7 Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 14:51:46 -0800 Subject: [PATCH 29/34] Update joda-time. --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index b00d34e2..b179390e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -48,7 +48,7 @@ joda-time joda-time - 2.10.6 + 2.10.14 From d5b713d0166c1562100b9aaf31c74571479d7cd8 Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 15:03:03 -0800 Subject: [PATCH 30/34] Enable manual github actions workflow run. --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 88ce2a45..60e476d3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -3,7 +3,7 @@ name: java-saml CI with Maven -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: test: From 0e244b9a601132de7b738444edc73e34c57812db Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 15:15:21 -0800 Subject: [PATCH 31/34] Update azure-security-keyvault-keys. --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index b179390e..3ebcc721 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,7 +72,7 @@ com.azure azure-security-keyvault-keys - 4.3.4 + 4.3.8 true From 094ddc2a3b0fe864c5caa1dbdb1586d6e6a5c113 Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 15:19:24 -0800 Subject: [PATCH 32/34] Update azure-security-keyvault-kyes. --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 3ebcc721..4e516a41 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,7 +72,7 @@ com.azure azure-security-keyvault-keys - 4.3.8 + 4.5.2 true From 70608f8d10770a976298ca8bb7aea13980d13a63 Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 15:29:43 -0800 Subject: [PATCH 33/34] Mess around with dependencies to avoid vulnerabilities. --- core/pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 4e516a41..98fc070b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,7 +72,13 @@ com.azure azure-security-keyvault-keys - 4.5.2 + 4.3.8 + true + + + com.fasterxml.jackson.core + jackson-databind + 2.13.4.2 true From e5c394d4a983266eb90d4b789db089b38be18980 Mon Sep 17 00:00:00 2001 From: George Khaburzaniya Date: Fri, 18 Nov 2022 15:35:48 -0800 Subject: [PATCH 34/34] Lower dependency values. --- core/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 98fc070b..bcf90b8b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -48,7 +48,7 @@ joda-time joda-time - 2.10.14 + 2.10.6 @@ -72,7 +72,7 @@ com.azure azure-security-keyvault-keys - 4.3.8 + 4.3.4 true