[java-redshift] branch master updated: Adjust linefeeds.
Scott Cantor
cantor.2 at osu.edu
Tue May 21 19:40:15 EDT 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-redshift.
View the commit online:
http://git.shibboleth.net/view/?p=java-redshift.git;a=commit;h=a54d4e003f68cd1e60cf047dc74e776e8c77a302
The following commit(s) were added to refs/heads/master by this push:
new a54d4e0 Adjust linefeeds.
a54d4e0 is described below
commit a54d4e003f68cd1e60cf047dc74e776e8c77a302
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue May 21 19:40:12 2019 -0400
Adjust linefeeds.
---
.classpath | 6 -
.../amazon/redshift/ECPCredentialsProvider.java | 544 ++++++++++-----------
2 files changed, 272 insertions(+), 278 deletions(-)
diff --git a/.classpath b/.classpath
index 002ad57..a5d9509 100644
--- a/.classpath
+++ b/.classpath
@@ -18,12 +18,6 @@
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
- <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
- <attributes>
- <attribute name="maven.pomderived" value="true"/>
- <attribute name="test" value="true"/>
- </attributes>
- </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
diff --git a/src/main/java/net/shibboleth/utilities/amazon/redshift/ECPCredentialsProvider.java b/src/main/java/net/shibboleth/utilities/amazon/redshift/ECPCredentialsProvider.java
index fbe8b43..5872ab3 100755
--- a/src/main/java/net/shibboleth/utilities/amazon/redshift/ECPCredentialsProvider.java
+++ b/src/main/java/net/shibboleth/utilities/amazon/redshift/ECPCredentialsProvider.java
@@ -1,273 +1,273 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.shibboleth.utilities.amazon.redshift;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.time.Instant;
-import java.util.Base64;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import com.amazon.redshift.plugin.SamlCredentialsProvider;
-import com.amazon.redshift.shaded.apache.http.HttpHost;
-import com.amazon.redshift.shaded.apache.http.auth.AuthScope;
-import com.amazon.redshift.shaded.apache.http.auth.UsernamePasswordCredentials;
-import com.amazon.redshift.shaded.apache.http.client.AuthCache;
-import com.amazon.redshift.shaded.apache.http.client.ClientProtocolException;
-import com.amazon.redshift.shaded.apache.http.client.methods.CloseableHttpResponse;
-import com.amazon.redshift.shaded.apache.http.client.methods.HttpPost;
-import com.amazon.redshift.shaded.apache.http.client.protocol.HttpClientContext;
-import com.amazon.redshift.shaded.apache.http.entity.ContentType;
-import com.amazon.redshift.shaded.apache.http.entity.StringEntity;
-import com.amazon.redshift.shaded.apache.http.impl.auth.BasicScheme;
-import com.amazon.redshift.shaded.apache.http.impl.client.BasicAuthCache;
-import com.amazon.redshift.shaded.apache.http.impl.client.BasicCredentialsProvider;
-import com.amazon.redshift.shaded.apache.http.impl.client.CloseableHttpClient;
-import com.amazon.redshift.shaded.apache.http.util.EntityUtils;
-
-/**
- * SAML ECP plugin for Amazon Redshift JDBC driver.
- *
- * <p>This extends an interface built-in to the JDBC driver library. It relies
- * on one shadowed dependency inside that library (the Apache HttpClient) to avoid
- * additional dependencies on the classpath.</p>
- */
-public class ECPCredentialsProvider extends SamlCredentialsProvider {
- /**
- * This property key called "saml_assertion" is used to provide some assertion
- * information through the connection string.
- * jdbc:redshift:iam://[host]:[port]/[database]?saml_assertion=[value]
- *
- * The restrictions on "key_name" are:
- * <p>
- * - The name must be unique. It can not match any existing connection property key name in
- * the Redshift JDBC driver. The connection property names are case-insensitive, so even
- * if the case does not match what is found in the documentation, it is not allowed.
- * <p>
- * - The key name may not have any spaces.
- * <p>
- * - The key name may only contain the characters [a-z]|[A-Z] or underscore '_'.
- */
-
- /** This key is built-n to the Amazon driver. */
- public static final String KEY_SAML_ASSERTION = "saml_assertion";
-
- /** Overrides the SAML AuthnRequest template used, must be a resource on the classpath. */
- public static final String KEY_ECP_TEMPLATE = "ecp_template";
-
- /** Sets the path to the ECP encpoint, defaults to the conventional Shibboleth IdP default. */
- public static final String KEY_ECP_PATH = "ecp_path";
-
- /** XML element name to locate in the response from the IdP, defaults to 'saml2p:Response'. */
- public static final String KEY_ECP_TAG = "ecp_tag";
-
- /** Optional property resource containing HTTP headers to pass in request. */
- public static final String KEY_ECP_HEADERS = "ecp_headers";
-
- /** The SAML Response message. */
- private String samlResponse;
-
- /** Effective path to IdP ECP endpoint. */
- private String idpPath;
-
- /** Path to classpath resource containing SAML request template. */
- private String template;
-
- /** XML start tag for SAML Response. */
- private String startTag;
-
- /** XML closing tag for SAML Response. */
- private String endTag;
-
- /** Property resource containing additional request headers. */
- private String headerPropertyFile;
-
- /**
- * Constructor.
- */
- public ECPCredentialsProvider() {
- idpPath = "/idp/profile/SAML2/SOAP/ECP";
- template = "/templates/ecp-request.xml";
- startTag = "<saml2p:Response ";
- endTag = "</saml2p:Response>";
- }
-
- /**
- * This method is used to get the values associated with different connection string properties.
- * <p>
- * We override it in this custom credentials provider to add a check for any additional
- * connection properties that were added, which are not included in the existing Redshift JDBC
- * driver. It allows us to store these values using the appropriate fields as mentioned above.
- * <p>
- * For any new connection property keys added to this class, add an if-condition to check, if
- * the current key matches the connection property key, store the value associated with the key
- * in the appropriate field.
- * <p>
- * If no new connection property keys are required, you may leave the implementation blank and
- * simply return a call to the parent class implementation.
- * <p>
- * Please see the example below.
- *
- * @param key A string representing the connection property key.
- * @param value The value associated with the connection property key.
- */
- @Override
- public void addParameter(final String key, final String value) {
- // The parent class will take care of setting up all other connection properties which are
- // mentioned in the Redshift JDBC driver documentation.
- super.addParameter(key, value);
-
- // Add if-condition checks for any connection properties which are specific to your
- // implementation of this custom SAML credentials provider.
- if (KEY_SAML_ASSERTION.equalsIgnoreCase(key)) {
- samlResponse = value;
- } else if (KEY_ECP_PATH.equalsIgnoreCase(key)) {
- idpPath = value;
- } else if (KEY_ECP_TEMPLATE.equalsIgnoreCase(key)) {
- template = value;
- } else if (KEY_ECP_TAG.equalsIgnoreCase(key)) {
- startTag = "<" + value + " ";
- endTag = "</" + value + ">";
- } else if (KEY_ECP_HEADERS.equalsIgnoreCase(key)) {
- headerPropertyFile = value;
- }
- }
-
- /** {@inheritDoc} */
- @Override
- protected String getSamlAssertion() throws IOException {
- if (samlResponse != null) {
- return samlResponse;
- }
-
- final String soapResponse = doRequest();
-
- if (!soapResponse.contains("urn:oasis:names:tc:SAML:2.0:status:Success")) {
- throw new IOException("SAML Response was unsuccessful");
- }
-
- final int startTagPos = soapResponse.indexOf(startTag);
- final int endTagPos = soapResponse.indexOf(endTag);
-
- if (startTagPos == -1 || endTagPos == -1 || endTagPos <= startTagPos) {
- throw new IOException("Unable to locate start/end tags in SOAP response.");
- }
-
- return Base64.getEncoder().encodeToString(
- soapResponse.substring(startTagPos, endTagPos + endTag.length()).getBytes());
- }
-
- /**
- * Performs the ECP exchange with the IdP and returns the SOAP response body.
- *
- * @return well-formed SOAP envelope
- *
- * @throws IOException if an error occurs
- */
- private String doRequest() throws IOException {
- // Set up Base URL for connection
- final StringBuilder ecpBaseUrl = new StringBuilder("https://");
- ecpBaseUrl.append(m_idpHost);
- if (m_idpPort > 0) {
- ecpBaseUrl.append(':').append(m_idpPort);
- }
- ecpBaseUrl.append(idpPath);
-
- final HttpClientContext httpContext = HttpClientContext.create();
-
- // Primes the request with credentials.
- final AuthCache authCache = new BasicAuthCache();
- authCache.put(new HttpHost(m_idpHost, m_idpPort > 0 ? m_idpPort : 443, "https"), new BasicScheme());
- httpContext.setAuthCache(authCache);
-
- // Supply the credentials.
- final BasicCredentialsProvider creds = new BasicCredentialsProvider();
- creds.setCredentials(new AuthScope(m_idpHost, m_idpPort > 0 ? m_idpPort : 443),
- new UsernamePasswordCredentials(m_userName, m_password));
- httpContext.setCredentialsProvider(creds);
-
- try (final CloseableHttpClient client = getHttpClient()) {
- final HttpPost post = new HttpPost(ecpBaseUrl.toString());
-
- if (headerPropertyFile != null) {
- final Properties props = new Properties();
- try (final FileInputStream in = new FileInputStream(headerPropertyFile)) {
- props.load(in);
- }
- if (!props.isEmpty()) {
- for (final Map.Entry<Object,Object> entry : props.entrySet()) {
- post.addHeader(entry.getKey().toString(), entry.getValue().toString());
- }
- }
- }
-
- post.setEntity(new StringEntity(getAuthnRequest(), ContentType.TEXT_XML));
-
- final CloseableHttpResponse resp = client.execute(post, httpContext);
- if (resp.getStatusLine().getStatusCode() != 200) {
- throw new IOException("Request to IdP failed: " + resp.getStatusLine().getReasonPhrase());
- } else if (!resp.getEntity().getContentType().getValue().startsWith(ContentType.TEXT_XML.getMimeType())) {
- throw new IOException("Invalid response content type: " + resp.getEntity().getContentType().getValue());
- }
-
- return EntityUtils.toString(resp.getEntity());
-
- } catch (final ClientProtocolException | GeneralSecurityException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Generate the SOAP request to the IdP.
- *
- * @return SOAP-based AuthnRequest
- *
- * @throws IOException if an error occurs constructing the request
- */
- private String getAuthnRequest() throws IOException {
- try (final InputStream in = getClass().getResourceAsStream(template)) {
-
- if (in == null) {
- throw new IOException("Unable to load template: " + template);
- }
-
- final StringBuilder builder = new StringBuilder();
- int ch = in.read();
- while (ch != -1) {
- builder.append((char) ch);
- ch = in.read();
- }
-
- ch = builder.indexOf("${ID}");
- if (ch != -1) {
- builder.replace(ch, ch + 5, "_" + UUID.randomUUID().toString());
- }
-
- ch = builder.indexOf("${IssueInstant}");
- if (ch != -1) {
- builder.replace(ch, ch + 15, Instant.now().toString());
- }
-
- return builder.toString();
- }
- }
-
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.shibboleth.utilities.amazon.redshift;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.time.Instant;
+import java.util.Base64;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+
+import com.amazon.redshift.plugin.SamlCredentialsProvider;
+import com.amazon.redshift.shaded.apache.http.HttpHost;
+import com.amazon.redshift.shaded.apache.http.auth.AuthScope;
+import com.amazon.redshift.shaded.apache.http.auth.UsernamePasswordCredentials;
+import com.amazon.redshift.shaded.apache.http.client.AuthCache;
+import com.amazon.redshift.shaded.apache.http.client.ClientProtocolException;
+import com.amazon.redshift.shaded.apache.http.client.methods.CloseableHttpResponse;
+import com.amazon.redshift.shaded.apache.http.client.methods.HttpPost;
+import com.amazon.redshift.shaded.apache.http.client.protocol.HttpClientContext;
+import com.amazon.redshift.shaded.apache.http.entity.ContentType;
+import com.amazon.redshift.shaded.apache.http.entity.StringEntity;
+import com.amazon.redshift.shaded.apache.http.impl.auth.BasicScheme;
+import com.amazon.redshift.shaded.apache.http.impl.client.BasicAuthCache;
+import com.amazon.redshift.shaded.apache.http.impl.client.BasicCredentialsProvider;
+import com.amazon.redshift.shaded.apache.http.impl.client.CloseableHttpClient;
+import com.amazon.redshift.shaded.apache.http.util.EntityUtils;
+
+/**
+ * SAML ECP plugin for Amazon Redshift JDBC driver.
+ *
+ * <p>This extends an interface built-in to the JDBC driver library. It relies
+ * on one shadowed dependency inside that library (the Apache HttpClient) to avoid
+ * additional dependencies on the classpath.</p>
+ */
+public class ECPCredentialsProvider extends SamlCredentialsProvider {
+ /**
+ * This property key called "saml_assertion" is used to provide some assertion
+ * information through the connection string.
+ * jdbc:redshift:iam://[host]:[port]/[database]?saml_assertion=[value]
+ *
+ * The restrictions on "key_name" are:
+ * <p>
+ * - The name must be unique. It can not match any existing connection property key name in
+ * the Redshift JDBC driver. The connection property names are case-insensitive, so even
+ * if the case does not match what is found in the documentation, it is not allowed.
+ * <p>
+ * - The key name may not have any spaces.
+ * <p>
+ * - The key name may only contain the characters [a-z]|[A-Z] or underscore '_'.
+ */
+
+ /** This key is built-n to the Amazon driver. */
+ public static final String KEY_SAML_ASSERTION = "saml_assertion";
+
+ /** Overrides the SAML AuthnRequest template used, must be a resource on the classpath. */
+ public static final String KEY_ECP_TEMPLATE = "ecp_template";
+
+ /** Sets the path to the ECP encpoint, defaults to the conventional Shibboleth IdP default. */
+ public static final String KEY_ECP_PATH = "ecp_path";
+
+ /** XML element name to locate in the response from the IdP, defaults to 'saml2p:Response'. */
+ public static final String KEY_ECP_TAG = "ecp_tag";
+
+ /** Optional property resource containing HTTP headers to pass in request. */
+ public static final String KEY_ECP_HEADERS = "ecp_headers";
+
+ /** The SAML Response message. */
+ private String samlResponse;
+
+ /** Effective path to IdP ECP endpoint. */
+ private String idpPath;
+
+ /** Path to classpath resource containing SAML request template. */
+ private String template;
+
+ /** XML start tag for SAML Response. */
+ private String startTag;
+
+ /** XML closing tag for SAML Response. */
+ private String endTag;
+
+ /** Property resource containing additional request headers. */
+ private String headerPropertyFile;
+
+ /**
+ * Constructor.
+ */
+ public ECPCredentialsProvider() {
+ idpPath = "/idp/profile/SAML2/SOAP/ECP";
+ template = "/templates/ecp-request.xml";
+ startTag = "<saml2p:Response ";
+ endTag = "</saml2p:Response>";
+ }
+
+ /**
+ * This method is used to get the values associated with different connection string properties.
+ * <p>
+ * We override it in this custom credentials provider to add a check for any additional
+ * connection properties that were added, which are not included in the existing Redshift JDBC
+ * driver. It allows us to store these values using the appropriate fields as mentioned above.
+ * <p>
+ * For any new connection property keys added to this class, add an if-condition to check, if
+ * the current key matches the connection property key, store the value associated with the key
+ * in the appropriate field.
+ * <p>
+ * If no new connection property keys are required, you may leave the implementation blank and
+ * simply return a call to the parent class implementation.
+ * <p>
+ * Please see the example below.
+ *
+ * @param key A string representing the connection property key.
+ * @param value The value associated with the connection property key.
+ */
+ @Override
+ public void addParameter(final String key, final String value) {
+ // The parent class will take care of setting up all other connection properties which are
+ // mentioned in the Redshift JDBC driver documentation.
+ super.addParameter(key, value);
+
+ // Add if-condition checks for any connection properties which are specific to your
+ // implementation of this custom SAML credentials provider.
+ if (KEY_SAML_ASSERTION.equalsIgnoreCase(key)) {
+ samlResponse = value;
+ } else if (KEY_ECP_PATH.equalsIgnoreCase(key)) {
+ idpPath = value;
+ } else if (KEY_ECP_TEMPLATE.equalsIgnoreCase(key)) {
+ template = value;
+ } else if (KEY_ECP_TAG.equalsIgnoreCase(key)) {
+ startTag = "<" + value + " ";
+ endTag = "</" + value + ">";
+ } else if (KEY_ECP_HEADERS.equalsIgnoreCase(key)) {
+ headerPropertyFile = value;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected String getSamlAssertion() throws IOException {
+ if (samlResponse != null) {
+ return samlResponse;
+ }
+
+ final String soapResponse = doRequest();
+
+ if (!soapResponse.contains("urn:oasis:names:tc:SAML:2.0:status:Success")) {
+ throw new IOException("SAML Response was unsuccessful");
+ }
+
+ final int startTagPos = soapResponse.indexOf(startTag);
+ final int endTagPos = soapResponse.indexOf(endTag);
+
+ if (startTagPos == -1 || endTagPos == -1 || endTagPos <= startTagPos) {
+ throw new IOException("Unable to locate start/end tags in SOAP response.");
+ }
+
+ return Base64.getEncoder().encodeToString(
+ soapResponse.substring(startTagPos, endTagPos + endTag.length()).getBytes());
+ }
+
+ /**
+ * Performs the ECP exchange with the IdP and returns the SOAP response body.
+ *
+ * @return well-formed SOAP envelope
+ *
+ * @throws IOException if an error occurs
+ */
+ private String doRequest() throws IOException {
+ // Set up Base URL for connection
+ final StringBuilder ecpBaseUrl = new StringBuilder("https://");
+ ecpBaseUrl.append(m_idpHost);
+ if (m_idpPort > 0) {
+ ecpBaseUrl.append(':').append(m_idpPort);
+ }
+ ecpBaseUrl.append(idpPath);
+
+ final HttpClientContext httpContext = HttpClientContext.create();
+
+ // Primes the request with credentials.
+ final AuthCache authCache = new BasicAuthCache();
+ authCache.put(new HttpHost(m_idpHost, m_idpPort > 0 ? m_idpPort : 443, "https"), new BasicScheme());
+ httpContext.setAuthCache(authCache);
+
+ // Supply the credentials.
+ final BasicCredentialsProvider creds = new BasicCredentialsProvider();
+ creds.setCredentials(new AuthScope(m_idpHost, m_idpPort > 0 ? m_idpPort : 443),
+ new UsernamePasswordCredentials(m_userName, m_password));
+ httpContext.setCredentialsProvider(creds);
+
+ try (final CloseableHttpClient client = getHttpClient()) {
+ final HttpPost post = new HttpPost(ecpBaseUrl.toString());
+
+ if (headerPropertyFile != null) {
+ final Properties props = new Properties();
+ try (final FileInputStream in = new FileInputStream(headerPropertyFile)) {
+ props.load(in);
+ }
+ if (!props.isEmpty()) {
+ for (final Map.Entry<Object,Object> entry : props.entrySet()) {
+ post.addHeader(entry.getKey().toString(), entry.getValue().toString());
+ }
+ }
+ }
+
+ post.setEntity(new StringEntity(getAuthnRequest(), ContentType.TEXT_XML));
+
+ final CloseableHttpResponse resp = client.execute(post, httpContext);
+ if (resp.getStatusLine().getStatusCode() != 200) {
+ throw new IOException("Request to IdP failed: " + resp.getStatusLine().getReasonPhrase());
+ } else if (!resp.getEntity().getContentType().getValue().startsWith(ContentType.TEXT_XML.getMimeType())) {
+ throw new IOException("Invalid response content type: " + resp.getEntity().getContentType().getValue());
+ }
+
+ return EntityUtils.toString(resp.getEntity());
+
+ } catch (final ClientProtocolException | GeneralSecurityException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Generate the SOAP request to the IdP.
+ *
+ * @return SOAP-based AuthnRequest
+ *
+ * @throws IOException if an error occurs constructing the request
+ */
+ private String getAuthnRequest() throws IOException {
+ try (final InputStream in = getClass().getResourceAsStream(template)) {
+
+ if (in == null) {
+ throw new IOException("Unable to load template: " + template);
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ int ch = in.read();
+ while (ch != -1) {
+ builder.append((char) ch);
+ ch = in.read();
+ }
+
+ ch = builder.indexOf("${ID}");
+ if (ch != -1) {
+ builder.replace(ch, ch + 5, "_" + UUID.randomUUID().toString());
+ }
+
+ ch = builder.indexOf("${IssueInstant}");
+ if (ch != -1) {
+ builder.replace(ch, ch + 15, Instant.now().toString());
+ }
+
+ return builder.toString();
+ }
+ }
+
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list