Author: bdaw
Date: 2009-12-09 10:40:03 -0500 (Wed, 09 Dec 2009)
New Revision: 13853
Added:
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSOAgent.java
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSORESTAuthenticationValve.java
Log:
- OpenSSO REST support
Added:
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSOAgent.java
===================================================================
---
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSOAgent.java
(rev 0)
+++
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSOAgent.java 2009-12-09
15:40:03 UTC (rev 13853)
@@ -0,0 +1,223 @@
+/*
+* JBoss, a division of Red Hat
+* Copyright 2009, Red Hat Middleware, LLC, and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+
+
+package org.jboss.portal.identity.sso.opensso;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.PostMethod;
+
+
+/**
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ * @author <a href="mailto:boleslaw dot dawidowicz at redhat anotherdot
com">Boleslaw Dawidowicz</a>
+ */
+public class OpenSSOAgent
+{
+ private static Logger log = Logger.getLogger(OpenSSOAgent.class);
+ private static OpenSSOAgent singleton;
+
+ private String cookieName;
+ private String serverUrl;
+
+ private OpenSSOAgent(String serverUrl, String cookieName)
+ {
+ this.serverUrl = serverUrl;
+ this.cookieName = cookieName;
+ }
+
+ public static OpenSSOAgent getInstance(String serverUrl, String cookieName)
+ {
+ if(OpenSSOAgent.singleton == null)
+ {
+ synchronized(OpenSSOAgent.class)
+ {
+ if(OpenSSOAgent.singleton == null)
+ {
+ OpenSSOAgent.singleton = new OpenSSOAgent(serverUrl, cookieName);
+ }
+ }
+ }
+ return OpenSSOAgent.singleton;
+ }
+
+ public String validateTicket(HttpServletRequest httpRequest) throws Exception
+ {
+ String token = null;
+ Cookie[] cookies = httpRequest.getCookies();
+ for(Cookie cookie: cookies)
+ {
+ if(cookie.getName().equals(this.cookieName))
+ {
+ token = cookie.getValue();
+ break;
+ }
+ }
+
+ if(token != null)
+ {
+ boolean isValid = this.isTokenValid(token);
+
+ if(!isValid)
+ {
+ throw new IllegalStateException("OpenSSO Token is not valid!!");
+ }
+
+ String subject = this.getSubject(token);
+ if(subject != null)
+ {
+ return subject;
+ }
+ }
+
+ return null;
+ }
+
+ public void invalidateTicket(HttpServletResponse httpResponse)
+ {
+ Cookie clear = new Cookie(this.cookieName, null);
+ clear.setMaxAge(0);
+ httpResponse.addCookie(clear);
+
+ }
+ //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ private boolean isTokenValid(String token) throws Exception
+ {
+ HttpClient client = new HttpClient();
+ PostMethod post = null;
+ try
+ {
+ String url = this.serverUrl+"/identity/isTokenValid";
+ post = new PostMethod(url);
+ post.addParameter("tokenid", token);
+
+ int status = client.executeMethod(post);
+ String response = post.getResponseBodyAsString();
+
+ log.debug("-------------------------------------------------------");
+ log.debug("Status: "+status);
+ log.debug("Response: "+response);
+ log.debug("-------------------------------------------------------");
+
+ if(response.contains(Boolean.TRUE.toString()))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ finally
+ {
+ if(post != null)
+ {
+ post.releaseConnection();
+ }
+ }
+ }
+
+ private String getSubject(String token) throws Exception
+ {
+ HttpClient client = new HttpClient();
+ PostMethod post = null;
+ try
+ {
+ String uid = null;
+ String url = this.serverUrl+"/identity/attributes";
+ post = new PostMethod(url);
+ post.addParameter("subjectid", token);
+ post.addParameter("attributes_names", "uid");
+
+ int status = client.executeMethod(post);
+ String response = post.getResponseBodyAsString();
+
+ log.debug("--------------------------------------------------------");
+ log.debug("Status: "+status);
+ log.debug(response);
+ log.debug("--------------------------------------------------------");
+
+ if(response != null)
+ {
+ Properties properties = this.loadAttributes(response);
+ uid = properties.getProperty("uid");
+ }
+
+
+ return uid;
+ }
+ finally
+ {
+ if(post != null)
+ {
+ post.releaseConnection();
+ }
+ }
+ }
+
+ private Properties loadAttributes(String response) throws Exception
+ {
+ InputStream is = null;
+ try
+ {
+ Properties properties = new Properties();
+
+ String[] tokens = response.split("\n");
+ String name = null;
+ for(String token: tokens)
+ {
+ if(token.startsWith("userdetails.attribute.name"))
+ {
+ name = token.substring(token.indexOf("=")+1).trim();
+ }
+ else if(token.startsWith("userdetails.attribute.value"))
+ {
+ String value = token.substring(token.indexOf("=")+1).trim();
+ value = value.trim();
+
+ if(name != null)
+ {
+ properties.setProperty(name, value);
+ }
+
+ //cleanup
+ name = null;
+ }
+ }
+
+ return properties;
+ }
+ finally
+ {
+ if(is != null)
+ {
+ is.close();
+ }
+ }
+ }
+}
Added:
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSORESTAuthenticationValve.java
===================================================================
---
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSORESTAuthenticationValve.java
(rev 0)
+++
modules/identity/branches/JBP_IDENTITY_BRANCH_1_1/sso/src/main/java/org/jboss/portal/identity/sso/opensso/OpenSSORESTAuthenticationValve.java 2009-12-09
15:40:03 UTC (rev 13853)
@@ -0,0 +1,408 @@
+/*
+* JBoss, a division of Red Hat
+* Copyright 2006, Red Hat Middleware, LLC, and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+
+package org.jboss.portal.identity.sso.opensso;
+
+import org.apache.catalina.valves.ValveBase;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.Context;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.Constants;
+import org.jboss.portal.identity.helper.IdentityTools;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
+
+
+/**
+ * @author <a href="mailto:boleslaw dot dawidowicz at redhat anotherdot
com">Boleslaw Dawidowicz</a>
+ * @version $Revision: 0.1 $
+ */
+public class OpenSSORESTAuthenticationValve extends ValveBase
+{
+ /** . */
+ private static final org.jboss.logging.Logger log =
org.jboss.logging.Logger.getLogger(OpenSSOAuthenticationValve.class);
+
+ public static final String WEB_REQUEST_KEY =
"javax.servlet.http.HttpServletRequest";
+
+ private Set urlPatterns;
+
+ private String serverURL;
+
+ private String cookieName;
+
+ private String loginURL;
+
+ private String logoutURL;
+
+ private boolean appendLoginGoto = true;
+
+ private boolean appendLogoutGoto = true;
+
+ private String loginParameters;
+
+ private String logoutParameters;
+
+ private String authType = "FORM";
+
+ public void invoke(Request request, Response response) throws IOException,
ServletException
+ {
+
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpSession session = httpRequest.getSession();
+ request.setAttribute("ssoEnabled", "true");
+
+
+ OpenSSOAgent agent = OpenSSOAgent.getInstance(this.serverURL, this.cookieName);
+
+ String openSSOSubject = null;
+
+ try
+ {
+ openSSOSubject = agent.validateTicket(request);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to validate OpenSSO token:: ", e);
+ }
+
+ String requestURI = request.getRequestURI();
+
+ // When token is not present and secured portal url is requested
+
+ if (isSecuredURI(requestURI) && openSSOSubject == null)
+ {
+
+ // Perform OpenSSO login by going to the OpenSSO authentication server
+
+ redirectToOpenSSOLogin(request, response);
+ return;
+ }
+
+ // When token present and valid
+
+ if (openSSOSubject != null)
+ {
+
+ try
+ {
+ // Perform the portal JAAS authentication
+
+ request.setAttribute("ssoSuccess", new Boolean(true));
+ Principal principal = ((Context)
this.container).getRealm().authenticate(openSSOSubject, (String) null);
+ if (principal != null)
+ {
+ this.register(request, response, principal, getAuthType(),
openSSOSubject,
+ (String) null);
+ }
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to perform JAAS login: ", e);
+ }
+ }
+
+ // Continue processing the request
+
+ this.getNext().invoke(request, response);
+
+
+ // Signout request
+
+ if ((openSSOSubject != null &&
request.getAttribute("org.jboss.portal.logout") != null))
+ {
+ agent.invalidateTicket(response);
+ redirectToOpenSSOLogout(request,response);
+ }
+ else if (openSSOSubject == null && request.getUserPrincipal() != null)
+ {
+ // Illegal state - no SSO token present but still authenticated
+ request.getSession().invalidate();
+ }
+
+ }
+
+ private void redirectToOpenSSOLogin(HttpServletRequest request, HttpServletResponse
response) throws IOException
+ {
+
+ StringBuffer redirect = new StringBuffer();
+ redirect.append(getLoginURL());
+ if (isAppendLoginGoto())
+ {
+ redirect.append("?goto=")
+ .append(request.getRequestURL());
+ }
+
+ if (getLoginParameters() != null && getLoginParameters().length() > 0)
+ {
+ if (isAppendLoginGoto())
+ {
+ redirect.append("&");
+ }
+ else
+ {
+ redirect.append("?");
+ }
+ redirect.append(getLoginParameters());
+ }
+
+ if (log.isDebugEnabled()) log.debug("Redirect to OpenSSO login URL: " +
redirect.toString());
+
+ response.sendRedirect(redirect.toString());
+ }
+
+ private void redirectToOpenSSOLogout(HttpServletRequest request, HttpServletResponse
response) throws IOException
+ {
+
+ StringBuffer redirect = new StringBuffer();
+ redirect.append(getLogoutURL());
+ if (isAppendLogoutGoto())
+ {
+ StringBuffer url = new StringBuffer();
+ if (request.isSecure())
+ {
+ url.append("https://");
+ }
+ else
+ {
+ url.append("http://");
+ }
+ url.append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append(request.getContextPath());
+
+ redirect.append("?goto=")
+ .append(url);
+ }
+
+ if (getLogoutParameters() != null && getLogoutParameters().length() >
0)
+ {
+ if (isAppendLogoutGoto())
+ {
+ redirect.append("&");
+ }
+ else
+ {
+ redirect.append("?");
+ }
+ redirect.append(getLogoutParameters());
+ }
+
+ if (log.isDebugEnabled()) log.debug("Redirect to OpenSSO logout URL: " +
redirect.toString());
+
+ response.sendRedirect(redirect.toString());
+ }
+
+
+
+ private boolean isSecuredURI(String uri)
+ {
+ Set patterns = getSecuredUrlPatterns();
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Checking if requested uri '" + uri + "'
matches secured url patterns: " + patterns);
+ }
+
+ for (Iterator iterator = patterns.iterator(); iterator.hasNext();)
+ {
+ String pattern = (String)iterator.next();
+
+ if (uri.indexOf(pattern) != -1)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public Set getSecuredUrlPatterns()
+ {
+ if (urlPatterns == null)
+ {
+ urlPatterns = IdentityTools.findSecuredURLs((Context)this.container);
+
+ //Remove wildcards
+ Set urls = new HashSet();
+ for (Iterator iterator = urlPatterns.iterator(); iterator.hasNext();)
+ {
+ String pattern = (String)iterator.next();
+ urls.add(pattern.replaceAll("\\*",""));
+ }
+ urlPatterns = urls;
+ }
+
+ return urlPatterns;
+ }
+
+ /**
+ * Register an authenticated Principal and authentication type in our
+ * request, in the current session (if there is one), and with our
+ * SingleSignOn valve, if there is one. Set the appropriate cookie to be
+ * returned.
+ *
+ * @param request
+ * The servlet request we are processing
+ * @param response
+ * The servlet response we are generating
+ * @param principal
+ * The authenticated Principal to be registered
+ * @param authType
+ * The authentication type to be registered
+ * @param username
+ * Username used to authenticate (if any)
+ * @param password
+ * Password used to authenticate (if any)
+ */
+ private void register(Request request, Response response,
+ Principal principal, String authType, String username, String password)
+ {
+ // Cache the authentication information in our request
+ request.setAuthType(authType);
+ request.setUserPrincipal(principal);
+
+ Session session = request.getSessionInternal(false);
+ // Cache the authentication information in our session, if any
+ if (session != null)
+ {
+ session.setAuthType(authType);
+ session.setPrincipal(principal);
+ if (username != null)
+ {
+ session.setNote(Constants.SESS_USERNAME_NOTE, username);
+ }
+ else
+ {
+ session.removeNote(Constants.SESS_USERNAME_NOTE);
+ }
+ if (password != null)
+ {
+ session.setNote(Constants.SESS_PASSWORD_NOTE, password);
+ }
+ else
+ {
+ session.removeNote(Constants.SESS_PASSWORD_NOTE);
+ }
+ }
+ }
+
+
+ public String getLoginURL()
+ {
+ return loginURL;
+ }
+
+ public void setLoginURL(String loginURL)
+ {
+ this.loginURL = loginURL;
+ }
+
+ public String getLogoutURL()
+ {
+ return logoutURL;
+ }
+
+ public void setLogoutURL(String logoutURL)
+ {
+ this.logoutURL = logoutURL;
+ }
+
+ public boolean isAppendLoginGoto()
+ {
+ return appendLoginGoto;
+ }
+
+ public void setAppendLoginGoto(boolean appendLoginGoto)
+ {
+ this.appendLoginGoto = appendLoginGoto;
+ }
+
+ public boolean isAppendLogoutGoto()
+ {
+ return appendLogoutGoto;
+ }
+
+ public void setAppendLogoutGoto(boolean appendLogoutGoto)
+ {
+ this.appendLogoutGoto = appendLogoutGoto;
+ }
+
+ public String getLoginParameters()
+ {
+ return loginParameters;
+ }
+
+ public void setLoginParameters(String loginParameters)
+ {
+ this.loginParameters = loginParameters;
+ }
+
+ public String getLogoutParameters()
+ {
+ return logoutParameters;
+ }
+
+ public void setLogoutParameters(String logoutParameters)
+ {
+ this.logoutParameters = logoutParameters;
+ }
+
+ public String getAuthType()
+ {
+ return authType;
+ }
+
+ public void setAuthType(String authType)
+ {
+ this.authType = authType;
+ }
+
+ public String getServerURL()
+ {
+ return serverURL;
+ }
+
+ public void setServerURL(String serverURL)
+ {
+ this.serverURL = serverURL;
+ }
+
+ public String getCookieName()
+ {
+ return cookieName;
+ }
+
+ public void setCookieName(String cookieName)
+ {
+ this.cookieName = cookieName;
+ }
+}