You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by wo...@apache.org on 2014/10/13 13:35:05 UTC

svn commit: r1631352 - in /portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso: SSOInitHttpRequestCommand.java SSOReverseProxyServlet.java SSOWebContentPortlet.java

Author: woonsan
Date: Mon Oct 13 11:35:05 2014
New Revision: 1631352

URL: http://svn.apache.org/r1631352
Log:
JS2-1304, JS2-1305: migrating http client 3.x based sso integration code to http client 4.x based one.

Added:
    portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOInitHttpRequestCommand.java
Modified:
    portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java
    portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOWebContentPortlet.java

Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOInitHttpRequestCommand.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOInitHttpRequestCommand.java?rev=1631352&view=auto
==============================================================================
--- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOInitHttpRequestCommand.java (added)
+++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOInitHttpRequestCommand.java Mon Oct 13 11:35:05 2014
@@ -0,0 +1,80 @@
+/*
+ * 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.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
+import org.apache.portals.applications.webcontent2.proxy.command.InitHttpRequestCommand;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.apache.portals.applications.webcontent2.proxy.impl.ServletRequestContext;
+
+
+public class SSOInitHttpRequestCommand extends InitHttpRequestCommand
+{
+
+    @Override
+    protected HttpRequestBase createHttpRequest(final ProxyContext context) throws ReverseProxyException, IOException
+    {
+        List<JetspeedSSOSiteCredentials> ssoCredsList = getJetspeedSSOSiteCredentials(context);
+
+        if (ssoCredsList != null && !ssoCredsList.isEmpty())
+        {
+            JetspeedSSOSiteCredentials firstCreds = ssoCredsList.get(0);
+
+            if (firstCreds.isFormAuthentication())
+            {
+                URI remoteURI = context.getRemoteURI();
+
+                if (remoteURI != null && remoteURI.equals(firstCreds.getBaseURI()))
+                {
+                    HttpRequestBase httpRequest = new HttpPost(remoteURI);
+                    List <NameValuePair> formParams = new ArrayList<NameValuePair>();
+                    formParams.add(new BasicNameValuePair(firstCreds.getFormUserField(), firstCreds.getUsername()));
+                    formParams.add(new BasicNameValuePair(firstCreds.getFormPwdField(), firstCreds.getPassword()));
+                    ((HttpPost) httpRequest).setEntity(new UrlEncodedFormEntity(formParams));
+                    return httpRequest;
+                }
+            }
+        }
+
+        return super.createHttpRequest(context);
+    }
+
+    private List<JetspeedSSOSiteCredentials> getJetspeedSSOSiteCredentials(final ProxyContext context)
+    {
+        List<JetspeedSSOSiteCredentials> ssoCredsList = null;
+
+        HttpSession session = ((ServletRequestContext) context.getRequestContext()).getServletRequest().getSession(false);
+
+        if (session != null) {
+            ssoCredsList = (List<JetspeedSSOSiteCredentials>) session.getAttribute(SSOReverseProxyIFramePortlet.SUBJECT_SSO_SITE_CREDS);
+        }
+
+        return ssoCredsList;
+    }
+}

Modified: 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=1631352&r1=1631351&r2=1631352&view=diff
==============================================================================
--- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java (original)
+++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOReverseProxyServlet.java Mon Oct 13 11:35:05 2014
@@ -19,6 +19,8 @@ package org.apache.jetspeed.portlets.sso
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 
+import org.apache.portals.applications.webcontent2.proxy.command.InitHttpRequestCommand;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
 import org.apache.portals.applications.webcontent2.proxy.servlet.SimpleReverseProxyServlet;
 
 public class SSOReverseProxyServlet extends SimpleReverseProxyServlet
@@ -37,4 +39,18 @@ public class SSOReverseProxyServlet exte
         setHttpClientContextBuilder(new JetspeedHttpClientContextBuilder());
         super.init(servletConfig);
     }
+
+    @Override
+    protected ProxyProcessingChain createProxyServiceCommand() {
+        ProxyProcessingChain proxyChain = super.createProxyServiceCommand();
+        ProxyProcessingChain processingChain = (ProxyProcessingChain) proxyChain.getCommand(1);
+        int index = processingChain.getCommandIndex(InitHttpRequestCommand.class);
+
+        if (index != -1) {
+            processingChain.removeCommand(index);
+            processingChain.addCommand(index, new SSOInitHttpRequestCommand());
+        }
+
+        return proxyChain;
+    }
 }

Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOWebContentPortlet.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOWebContentPortlet.java?rev=1631352&r1=1631351&r2=1631352&view=diff
==============================================================================
--- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOWebContentPortlet.java (original)
+++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/sso/SSOWebContentPortlet.java Mon Oct 13 11:35:05 2014
@@ -17,8 +17,13 @@
 package org.apache.jetspeed.portlets.sso;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
@@ -27,10 +32,29 @@ import javax.portlet.PortletContext;
 import javax.portlet.PortletException;
 import javax.portlet.PortletMode;
 import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
 import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 
-import org.apache.commons.httpclient.auth.BasicScheme;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Consts;
+import org.apache.http.HttpHost;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicNameValuePair;
 import org.apache.jetspeed.CommonPortletServices;
 import org.apache.jetspeed.security.JetspeedPrincipal;
 import org.apache.jetspeed.security.PasswordCredential;
@@ -89,7 +113,7 @@ public class SSOWebContentPortlet extend
 
     // ...standardized auth types
 
-    public static final String BASIC_AUTH_SCHEME_NAME = (new BasicScheme()).getSchemeName();
+    public static final String BASIC_AUTH_SCHEME_NAME = "basic";
 
     // supporting parameters - for various sso types
 
@@ -187,7 +211,6 @@ public class SSOWebContentPortlet extend
             // processPreferencesAction(request, actionResponse);
             // get the POST params -- requires HTML post params named above 
             String siteUrl = actionRequest.getPreferences().getValue("SRC", "");
-            String localUser = actionRequest.getUserPrincipal().getName();
             SSOSite site = sso.getSiteByUrl(siteUrl);
 
             try
@@ -294,17 +317,216 @@ public class SSOWebContentPortlet extend
         super.doEdit(request, response);
     }
 
+    @Override
+    protected HttpClientContext getHttpClientContext(PortletRequest request, HttpRequestBase httpRequest)
+    {
+        HttpClientContext httpClientContext = null;
+
+        PortletPreferences prefs = request.getPreferences();
+        String type = getSingleSignOnAuthType(prefs);
+
+        if (SSO_TYPE_BASIC_PREEMPTIVE.equalsIgnoreCase(type))
+        {
+            // Preemptive, basic authentication
+            String ssoUserName = StringUtils.defaultString((String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME));
+            String ssoPassword = StringUtils.defaultString((String)request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD));
+
+            httpClientContext = HttpClientContext.create();
+            httpClientContext.setCredentialsProvider(new BasicCredentialsProvider());
+            httpClientContext.setAuthCache(new BasicAuthCache());
+            URI targetURI = httpRequest.getURI();
+            String targetScheme = targetURI.getScheme();
+            String targetHost = targetURI.getHost();
+            int targetPort = (targetURI.getPort() > 0 ? targetURI.getPort() : ("https".equals(targetScheme) ? 443 : 80));
+            HttpHost targetHttpHost = new HttpHost(targetHost, targetPort, targetScheme);
+            // set Basic authentication scheme
+            httpClientContext.getAuthCache().put(targetHttpHost, new BasicScheme());
+            httpClientContext.getCredentialsProvider().setCredentials(
+                                         new AuthScope(targetHost, targetPort),
+                                         new UsernamePasswordCredentials(ssoUserName, ssoPassword));
+        }
+
+        return httpClientContext;
+    }
+
+    @Override
+    protected byte[] doPreemptiveAuthentication(CloseableHttpClient client, CookieStore cookieStore, HttpRequestBase httpRequest, RenderRequest request, RenderResponse response)
+    {
+        byte[] result = super.doPreemptiveAuthentication(client, cookieStore, httpRequest, request, response);
+
+        if ( result != null)
+        {
+            // already handled
+            return result ;
+        }
+
+        PortletPreferences prefs = request.getPreferences();
+        String type = getSingleSignOnAuthType(prefs);
+
+        if (StringUtils.startsWith(type, SSO_TYPE_FORM))
+        {
+            try
+            {
+                Boolean formAuth = (Boolean) PortletMessaging.receive(request, FORM_AUTH_STATE);
+
+                if (formAuth != null)
+                {
+                    // already been here, done that
+                    return (formAuth.booleanValue() ? result : null);
+                }
+                else
+                {
+                    // stop recursion, but assume failure, ...for now
+                    PortletMessaging.publish(request, FORM_AUTH_STATE, Boolean.FALSE);
+                }
+
+                String formAction = prefs.getValue(SSO_TYPE_FORM_ACTION_URL, "");
+
+                if (StringUtils.isEmpty(formAction))
+                {
+                    log.warn("sso.type specified as 'form', but no: "+SSO_TYPE_FORM_ACTION_URL+", action was specified - unable to preemptively authenticate by form.");
+                    return null ;
+                }
+
+                String userNameField = prefs.getValue(SSO_TYPE_FORM_USERNAME_FIELD, "");
+
+                if (StringUtils.isEmpty(userNameField))
+                {
+                    log.warn("sso.type specified as 'form', but no: "+SSO_TYPE_FORM_USERNAME_FIELD+", username field was specified - unable to preemptively authenticate by form.");
+                    return null ;
+                }
+
+                String passwordField = prefs.getValue(SSO_TYPE_FORM_PASSWORD_FIELD, "password");
+
+                if (StringUtils.isEmpty(passwordField))
+                {
+                    log.warn("sso.type specified as 'form', but no: "+SSO_TYPE_FORM_PASSWORD_FIELD+", password field was specified - unable to preemptively authenticate by form.");
+                    return null ;
+                }
+
+                String userName = StringUtils.defaultString((String) request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME));
+                String password = StringUtils.defaultString((String)request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD));
+
+                // get submit method
+                boolean isPost = true;
+
+                if (StringUtils.contains(type, '.')) {
+                    isPost = StringUtils.equalsIgnoreCase(StringUtils.substringAfter(type, "."), HttpPost.METHOD_NAME);
+                } else {
+                    isPost = StringUtils.equalsIgnoreCase(type, HttpPost.METHOD_NAME);
+                }
+
+                String formMethod = (isPost) ? HttpPost.METHOD_NAME : HttpGet.METHOD_NAME;
+
+                // get parameter map
+                Map<String, String[]> formParams = new HashMap<String, String[]>();
+                formParams.put(userNameField, new String[] { userName });
+                formParams.put(passwordField, new String[] { password });
+                String formArgs = prefs.getValue(SSO_TYPE_FORM_ACTION_ARGS, "");
+
+                if (StringUtils.isNotEmpty(formArgs))
+                {
+                    String [] pairs = StringUtils.split(formArgs, ";");
+                    String paramName;
+                    String paramValue;
+
+                    for (String pair : pairs)
+                    {
+                        paramName = StringUtils.substringBefore(pair, "=");
+                        paramValue = StringUtils.substringAfter(pair, "=");
+
+                        if (StringUtils.isNotEmpty(paramName))
+                        {
+                            formParams.put(paramName, new String[] { paramValue });
+                        }
+                    }
+                }
+
+                // resuse client - in case new cookies get set - but create a new method (for the formAction)
+                HttpRequestBase httpFormRequest = createHttpRequest(client, formMethod, formAction, null, formParams, request);
+                result = doHttpWebContent(client, cookieStore, httpFormRequest, 0, request, response, null);
+
+                PortletMessaging.publish(request, FORM_AUTH_STATE, Boolean.valueOf(result != null));
+                return result ;
+            }
+            catch (Exception ex)
+            {
+                // bad
+                log.error("Form-based authentication failed", ex);
+            }
+        }
+        else if (type.equalsIgnoreCase(SSO_TYPE_URL) || type.equalsIgnoreCase(SSO_TYPE_URL_BASE64))
+        {
+            // set user name and password parameters in the HttpMethod
+            String userNameParam = prefs.getValue(SSO_TYPE_URL_USERNAME_PARAM, "");
+
+            if (StringUtils.isEmpty(userNameParam))
+            {
+                log.warn("sso.type specified as 'url', but no: "+SSO_TYPE_URL_USERNAME_PARAM+", username parameter was specified - unable to preemptively authenticate by URL.");
+                return null ;
+            }
+
+            String passwordParam = prefs.getValue(SSO_TYPE_URL_PASSWORD_PARAM, "");
+
+            if (StringUtils.isEmpty(passwordParam))
+            {
+                log.warn("sso.type specified as 'url', but no: "+SSO_TYPE_URL_PASSWORD_PARAM+", password parameter was specified - unable to preemptively authenticate by URL.");
+                return null ;
+            }
+
+            String userName = StringUtils.defaultString((String)request.getAttribute(SSO_REQUEST_ATTRIBUTE_USERNAME));
+            String password = StringUtils.defaultString((String)request.getAttribute(SSO_REQUEST_ATTRIBUTE_PASSWORD));
+
+            if (SSO_TYPE_URL_BASE64.equalsIgnoreCase(type))
+            {
+                Base64 encoder = new Base64() ;
+                userName = new String(encoder.encode(userName.getBytes()));
+                password = new String(encoder.encode(password.getBytes()));
+            }
+
+            // GET and POST accept args differently
+            if ( httpRequest instanceof HttpPost )
+            {
+                // add POST data
+                List<NameValuePair> formParams = new ArrayList<NameValuePair>();
+                formParams.add(new BasicNameValuePair(userNameParam, userName));
+                formParams.add(new BasicNameValuePair(passwordParam, password));
+                UrlEncodedFormEntity httpEntity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+                ((HttpPost) httpRequest).setEntity(httpEntity);
+            }
+            else
+            {
+                try
+                {
+                    // augment GET query string
+                    URIBuilder uriBuilder = new URIBuilder(httpRequest.getURI());
+                    uriBuilder.addParameter(userNameParam, userName);
+                    uriBuilder.addParameter(passwordParam, password);
+                    httpRequest.setURI(uriBuilder.build());
+                }
+                catch (URISyntaxException e)
+                {
+                    log.error("URI syntax error.", e);
+                }
+            }
+
+            return result ;
+        }
+
+        // not handled
+        return null ;
+    }
+
     protected String getSingleSignOnAuthType(PortletPreferences prefs)
     {
-        String type = prefs.getValue(SSO_TYPE,SSO_TYPE_DEFAULT);
+        String type = prefs.getValue(SSO_TYPE, SSO_TYPE_DEFAULT);
 
-        if (type != null && type.equalsIgnoreCase(SSO_TYPE_HTTP))
+        if (SSO_TYPE_HTTP.equalsIgnoreCase(type))
         {
-            log.warn("sso.type: "+SSO_TYPE_HTTP+", has been deprecated - use: "+SSO_TYPE_BASIC+", or: "+SSO_TYPE_BASIC_PREEMPTIVE);
+            log.warn("sso.type: " + SSO_TYPE_HTTP + ", has been deprecated - use: " + SSO_TYPE_BASIC + ", or: " + SSO_TYPE_BASIC_PREEMPTIVE);
             type = SSO_TYPE_BASIC;
         }
 
         return type;
     }
-
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org