Author: woonsan Date: Thu Sep 11 05:25:44 2014 New Revision: 1624197 URL: http://svn.apache.org/r1624197 Log: JS2-1304: basic authentication based sso integration in SSOReverseProxyIFramePortlet
Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedHttpClientContextBuilder.java portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedSSOSiteCredentials.java portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java Modified: portals/jetspeed-2/applications/j2-admin/trunk/pom.xml portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyIFramePortlet.java portals/jetspeed-2/applications/j2-admin/trunk/src/main/webapp/WEB-INF/web.xml Modified: portals/jetspeed-2/applications/j2-admin/trunk/pom.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/pom.xml?rev=1624197&r1=1624196&r2=1624197&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/pom.xml (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/pom.xml Thu Sep 11 05:25:44 2014 @@ -44,6 +44,7 @@ <commons-fileupload.version>1.3.1</commons-fileupload.version> <commons-io.version>2.4</commons-io.version> <commons-beanutils.version>1.9.2</commons-beanutils.version> + <commons-codec.version>1.6</commons-codec.version> <slf4j.version>1.5.6</slf4j.version> <javax.servlet.jstl.version>1.1.2</javax.servlet.jstl.version> <javax.servlet.version>2.4</javax.servlet.version> @@ -216,6 +217,11 @@ <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>${commons-codec.version}</version> + </dependency> <!-- Runtime Dependencies --> <dependency> Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedHttpClientContextBuilder.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedHttpClientContextBuilder.java?rev=1624197&view=auto ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedHttpClientContextBuilder.java (added) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedHttpClientContextBuilder.java Thu Sep 11 05:25:44 2014 @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 org.apache.jetspeed.portlets.sso; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.portals.applications.webcontent2.proxy.HttpClientContextBuilder; +import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext; +import org.apache.portals.applications.webcontent2.proxy.impl.ServletRequestContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JetspeedHttpClientContextBuilder implements HttpClientContextBuilder +{ + + private static Logger log = LoggerFactory.getLogger(JetspeedHttpClientContextBuilder.class); + + public HttpClientContext build() + { + ProxyContext proxyContext = ProxyContext.getCurrentProxyContext(); + HttpServletRequest request = ((ServletRequestContext) proxyContext.getRequestContext()).getServletRequest(); + + List<JetspeedSSOSiteCredentials> ssoCredsList = (List<JetspeedSSOSiteCredentials>) request.getAttribute(SSOReverseProxyIFramePortlet.SUBJECT_SSO_SITE_CREDS); + + if (ssoCredsList == null) + { + HttpSession session = request.getSession(false); + + if (session == null) + { + return null; + } + + ssoCredsList = (List<JetspeedSSOSiteCredentials>) session.getAttribute(SSOReverseProxyIFramePortlet.SUBJECT_SSO_SITE_CREDS); + } + + if (ssoCredsList == null || ssoCredsList.isEmpty()) + { + return null; + } + + HttpClientContext httpClientContext = HttpClientContext.create(); + + try + { + httpClientContext.setCredentialsProvider(new BasicCredentialsProvider()); + httpClientContext.setAuthCache(new BasicAuthCache()); + + for (JetspeedSSOSiteCredentials ssoCreds : ssoCredsList) + { + HttpHost targetHost = new HttpHost(ssoCreds.getHost(), ssoCreds.getPort(), ssoCreds.getScheme()); + // set Basic authentication scheme + httpClientContext.getAuthCache().put(targetHost, new BasicScheme()); + httpClientContext.getCredentialsProvider().setCredentials( + new AuthScope(targetHost.getHostName(), targetHost.getPort(), ssoCreds.getRealm()), + new UsernamePasswordCredentials(ssoCreds.getUsername(), ssoCreds.getPassword())); + } + } + catch (Exception e) + { + if (log.isDebugEnabled()) + { + log.warn("Failed to retrieve sso site credentials.", e); + } + else + { + log.warn("Failed to retrieve sso site credentials. {}", e.toString()); + } + } + + return httpClientContext; + } +} Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedSSOSiteCredentials.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedSSOSiteCredentials.java?rev=1624197&view=auto ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedSSOSiteCredentials.java (added) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/JetspeedSSOSiteCredentials.java Thu Sep 11 05:25:44 2014 @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 org.apache.jetspeed.portlets.sso; + +import java.io.Serializable; +import java.net.URI; + +public class JetspeedSSOSiteCredentials implements Serializable +{ + + private static final long serialVersionUID = 1L; + + private URI baseURI; + private String host; + private int port = -1; + private String realm; + private String scheme; + + private String username; + private String password; + + private boolean challengeResponseAuthentication = true; + private boolean formAuthentication = false; + private String formUserField; + private String formPwdField; + + public JetspeedSSOSiteCredentials() + { + this(null); + } + + public JetspeedSSOSiteCredentials(URI baseURI) + { + this(baseURI, null); + } + + public JetspeedSSOSiteCredentials(URI baseURI, String host) + { + this(baseURI, host, -1); + } + + public JetspeedSSOSiteCredentials(URI baseURI, String host, int port) + { + this(baseURI, host, port, null); + } + + public JetspeedSSOSiteCredentials(URI baseURI, String host, int port, String realm) + { + this.baseURI = baseURI; + this.host = host; + this.port = port; + this.realm = realm; + } + + public URI getBaseURI() + { + return baseURI; + } + + public void setBaseURI(URI baseURI) + { + this.baseURI = baseURI; + } + + public String getHost() + { + return host; + } + + public void setHost(String host) + { + this.host = host; + } + + public int getPort() + { + return port; + } + + public void setPort(int port) + { + this.port = port; + } + + public String getRealm() + { + return realm; + } + + public void setRealm(String realm) + { + this.realm = realm; + } + + public String getScheme() + { + return scheme; + } + + public void setScheme(String scheme) + { + this.scheme = scheme; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public boolean isChallengeResponseAuthentication() + { + return challengeResponseAuthentication; + } + + public void setChallengeResponseAuthentication(boolean challengeResponseAuthentication) + { + this.challengeResponseAuthentication = challengeResponseAuthentication; + } + + public boolean isFormAuthentication() + { + return formAuthentication; + } + + public void setFormAuthentication(boolean formAuthentication) + { + this.formAuthentication = formAuthentication; + } + + public String getFormUserField() + { + return formUserField; + } + + public void setFormUserField(String formUserField) + { + this.formUserField = formUserField; + } + + public String getFormPwdField() + { + return formPwdField; + } + + public void setFormPwdField(String formPwdField) + { + this.formPwdField = formPwdField; + } +} Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyIFramePortlet.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyIFramePortlet.java?rev=1624197&r1=1624196&r2=1624197&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyIFramePortlet.java (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyIFramePortlet.java Thu Sep 11 05:25:44 2014 @@ -16,14 +16,21 @@ */ package org.apache.jetspeed.portlets.sso; +import java.io.IOException; import java.net.URI; import java.security.AccessController; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import javax.portlet.PortletConfig; import javax.portlet.PortletException; +import javax.portlet.PortletSession; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; import javax.security.auth.Subject; +import org.apache.commons.lang.StringUtils; import org.apache.jetspeed.security.JSSubject; import org.apache.jetspeed.security.PasswordCredential; import org.apache.jetspeed.sso.SSOManager; @@ -40,28 +47,42 @@ import org.slf4j.LoggerFactory; */ public class SSOReverseProxyIFramePortlet extends IFrameGenericPortlet { - + public static final String SUBJECT_SSO_SITE_CREDS = "org.apache.jetspeed.portlets.sso.ssoSiteCredsOfSubject"; - + private static Logger log = LoggerFactory.getLogger(SSOReverseProxyIFramePortlet.class); - + private SSOManager ssoManager; - + public void init(PortletConfig config) throws PortletException { super.init(config); - + ssoManager = (SSOManager) config.getPortletContext().getAttribute("cps:SSO"); - + if (null == ssoManager) - { + { throw new PortletException("Failed to find SSO Provider on portlet initialization"); } } - // TODO - private void readSSOSiteCredentialsOfSubject() + @Override + public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException + { + List<JetspeedSSOSiteCredentials> ssoCredsList = getJetspeedSSOSiteCredentialsList(); + + if (ssoCredsList != null && !ssoCredsList.isEmpty()) + { + request.getPortletSession().setAttribute(SUBJECT_SSO_SITE_CREDS, ssoCredsList, PortletSession.APPLICATION_SCOPE); + } + + super.doView(request, response); + } + + protected List<JetspeedSSOSiteCredentials> getJetspeedSSOSiteCredentialsList() { + List<JetspeedSSOSiteCredentials> ssoCredsList = new ArrayList<JetspeedSSOSiteCredentials>(); + try { Subject subject = JSSubject.getSubject(AccessController.getContext()); @@ -69,9 +90,33 @@ public class SSOReverseProxyIFramePortle if (ssoSites != null) { + URI siteURI = null; + String scheme = "http"; + String host = null; + int port = 80; + for (SSOSite ssoSite : ssoSites) { - URI siteURI = URI.create(ssoSite.getURL()); + siteURI = URI.create(ssoSite.getURL()); + + if (StringUtils.isNotEmpty(siteURI.getScheme())) + { + scheme = siteURI.getScheme(); + } + + host = siteURI.getHost(); + + if (StringUtils.isEmpty(host)) + { + log.warn("Skipping invalid SSO site URI (no host): '{}'.", host); + continue; + } + + if (siteURI.getPort() > 0) + { + port = siteURI.getPort(); + } + Collection<SSOUser> ssoUsers = ssoManager.getRemoteUsers(ssoSite, subject); if (ssoUsers != null) @@ -80,12 +125,17 @@ public class SSOReverseProxyIFramePortle { String realm = ssoSite.getRealm(); PasswordCredential pwc = ssoManager.getCredentials(ssoUser); - String username = pwc.getUserName(); - String password = pwc.getPassword(); - if (ssoSite.isFormAuthentication()) - { - } + JetspeedSSOSiteCredentials ssoCreds = new JetspeedSSOSiteCredentials(siteURI, host, port, realm); + ssoCreds.setScheme(scheme); + ssoCreds.setChallengeResponseAuthentication(ssoSite.isChallengeResponseAuthentication()); + ssoCreds.setFormAuthentication(ssoSite.isFormAuthentication()); + ssoCreds.setFormUserField(ssoSite.getFormUserField()); + ssoCreds.setFormPwdField(ssoSite.getFormPwdField()); + ssoCreds.setUsername(pwc.getUserName()); + ssoCreds.setPassword(pwc.getPassword()); + + ssoCredsList.add(ssoCreds); } } } @@ -93,10 +143,16 @@ public class SSOReverseProxyIFramePortle } catch (Exception e) { - if (log.isWarnEnabled()) + if (log.isDebugEnabled()) + { + log.warn("Failed to retrieve sso site credentials.", e); + } + else { log.warn("Failed to retrieve sso site credentials. {}", e.toString()); } } + + return ssoCredsList; } } Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java?rev=1624197&view=auto ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java (added) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java Thu Sep 11 05:25:44 2014 @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 org.apache.jetspeed.portlets.sso; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; + +import org.apache.portals.applications.webcontent2.proxy.servlet.SimpleReverseProxyServlet; + +public class SSOReverseProxyServlet extends SimpleReverseProxyServlet +{ + + private static final long serialVersionUID = 1L; + + public SSOReverseProxyServlet() + { + super(); + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException + { + setHttpClientContextBuilder(new JetspeedHttpClientContextBuilder()); + super.init(servletConfig); + } +} Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/webapp/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/webapp/WEB-INF/web.xml?rev=1624197&r1=1624196&r2=1624197&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/webapp/WEB-INF/web.xml (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/webapp/WEB-INF/web.xml Thu Sep 11 05:25:44 2014 @@ -205,10 +205,10 @@ <listener-class>org.apache.jetspeed.security.mfa.impl.MFAServletListener</listener-class> </listener> - <!-- Default Reverse Proxy Servlet --> + <!-- SSO Enabled Reverse Proxy Servlet --> <servlet> - <servlet-name>ReverseProxyServlet</servlet-name> - <servlet-class>org.apache.portals.applications.webcontent2.proxy.servlet.SimpleReverseProxyServlet</servlet-class> + <servlet-name>SSOReverseProxyServlet</servlet-name> + <servlet-class>org.apache.jetspeed.portlets.sso.SSOReverseProxyServlet</servlet-class> <init-param> <param-name>mappings</param-name> <param-value> @@ -260,7 +260,7 @@ <!-- Map /rproxy path to the Default Reverse Proxy Servlet --> <servlet-mapping> - <servlet-name>ReverseProxyServlet</servlet-name> + <servlet-name>SSOReverseProxyServlet</servlet-name> <url-pattern>/rproxy/*</url-pattern> </servlet-mapping> --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscr...@portals.apache.org For additional commands, e-mail: jetspeed-dev-h...@portals.apache.org