import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.Principal;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import edu.internet2.middleware.shibboleth.aa.arp.AAPrincipal;
import edu.internet2.middleware.shibboleth.aa.arp.ArpEngine;
import edu.internet2.middleware.shibboleth.aa.arp.ArpException;
-import edu.internet2.middleware.shibboleth.common.Constants;
-import edu.internet2.middleware.shibboleth.hs.HandleEntry;
import edu.internet2.middleware.shibboleth.hs.HandleException;
+import edu.internet2.middleware.shibboleth.hs.HandleRepository;
+import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
import edu.internet2.middleware.shibboleth.hs.HandleRepositoryFactory;
/**
public class AAServlet extends HttpServlet {
protected AAResponder responder;
- protected HandleRepositoryFactory hrf;
+ protected HandleRepository handleRepository;
protected Properties configuration;
private static Logger log = Logger.getLogger(AAServlet.class.getName());
ArpEngine arpEngine = new ArpEngine(configuration);
- hrf = getHandleRepository();
+ handleRepository = HandleRepositoryFactory.getInstance(configuration);
log.info(
"Using JNDI context ("
} catch (AAException ae) {
log.fatal("The AA could not be initialized: " + ae);
throw new UnavailableException("Attribute Authority failed to initialize.");
- } catch (HandleException he) {
+ } catch (HandleRepositoryException he) {
log.fatal(
"The AA could not be initialized due to a problem with the Handle Repository configuration: "
+ he);
List attrs = null;
SAMLException ourSE = null;
AASaml saml = null;
- String userName = null;
+ Principal principal = null;
try {
saml =
log.info("AA: handle:" + handle);
if (handle.equalsIgnoreCase("foo")) {
// for testing only
- userName = "dummy";
+ new AAPrincipal("dummy");
} else {
- if (hrf == null) {
- throw new HandleException("No HandleRepository found! Has HS initialized?");
- } else {
- HandleEntry he = hrf.getHandleEntry(handle);
- userName = he.getUsername();
- if (userName == null)
- throw new HandleException("HandleServer returns null for user name!");
+ principal = handleRepository.getPrincipal(handle);
+ if (principal == null) {
+ throw new HandleException("Received a request for an invalid/unknown handle.");
}
}
attrs =
Arrays.asList(
responder.getReleaseAttributes(
- new AAPrincipal(userName),
+ principal,
configuration.getProperty(
"edu.internet2.middleware.shibboleth.aa.AAServlet.ldapUserDnPhrase"),
shar,
resource));
- log.info("Got " + attrs.size() + " attributes for " + userName);
+ log.info("Got " + attrs.size() + " attributes for " + principal.getName());
saml.respond(resp, attrs, null);
- log.info("Successfully responded about " + userName);
+ log.info("Successfully responded about " + principal.getName());
} catch (org.opensaml.SAMLException se) {
- log.error("AA failed for " + userName + " because of: " + se);
+ log.error("AA failed for " + principal.getName() + " because of: " + se);
try {
saml.fail(resp, se);
} catch (Exception ee) {
+ se);
}
} catch (HandleException he) {
- log.error("AA failed for " + userName + " because of: " + he);
+ log.error("AA failed for " + principal.getName() + " because of: " + he);
try {
QName[] codes = new QName[2];
codes[0] = SAMLException.REQUESTER;
- codes[1] = new QName(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS, "InvalidHandle");
- saml.fail(resp, new SAMLException(Arrays.asList(codes), "AA got a HandleException: " + he));
+ codes[1] =
+ new QName(
+ edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,
+ "InvalidHandle");
+ saml.fail(
+ resp,
+ new SAMLException(Arrays.asList(codes), "AA got a HandleException: " + he));
} catch (Exception ee) {
throw new ServletException(
"AA failed to even make a SAML Failure message because "
e.printStackTrace();
log.error(
"Attribute Authority Error for principal ("
- + userName
+ + principal.getName()
+ ") : "
+ e.getClass().getName()
+ " : "
}
- private synchronized HandleRepositoryFactory getHandleRepository()
- throws HandleException, AAException{
-
- ServletConfig sc = getServletConfig();
- ServletContext sctx = sc.getServletContext();
- HandleRepositoryFactory hrf = (HandleRepositoryFactory)sctx.getAttribute("HandleRepository");
-
- log.debug("Context attribute for HandleRepository: "+hrf);
-
-
- if(hrf == null){
- // make one
- String repositoryType = this.getServletContext().getInitParameter("repository");
- if(repositoryType == null)
- throw new AAException("repository parameter not set. Unknown Handle repository type");
- hrf = HandleRepositoryFactory.getInstance( Constants.POLICY_CLUBSHIB,
- repositoryType,
- this );
- sctx.setAttribute("HandleRepository", hrf);
- log.info("A new HandleRepository created by AA: "+hrf);
-
- }
- return hrf;
- }
-
-
}
/**
* Defines a mechanism for communicating identities between the Shibboleth Handle
- * Service and Attribute Authority.
+ * Service and Attribute Authority. Implementations must be thread-safe.
*
* @author Walter Hoehn (wassa@columbia.edu)
*/
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package edu.internet2.middleware.shibboleth.hs;
+
+/**
+ * Indicates an error occurred while manipulating an instance of <code>HandleRepository</code>
+ *
+ * @author Walter Hoehn (wassa@columbia.edu)
+ */
+public class HandleRepositoryException extends Exception {
+
+ public HandleRepositoryException(String message) {
+ super(message);
+ }
+}
package edu.internet2.middleware.shibboleth.hs;
-import javax.servlet.http.*;
-import edu.internet2.middleware.shibboleth.*;
-import edu.internet2.middleware.shibboleth.common.*;
+import java.lang.reflect.Constructor;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
/**
- * Used by Shibboleth Handle Service and Attribute Authority to build a repository object
+ * Factory for generating instances of <code>HandleRepository</code>. Configuration
+ * is delegated to the Handle Repository. Runtime options are passed to concrete constructors
+ * via a <code>Properties</code> object.
+ *
+ * @author Walter Hoehn (wassa@columbia.edu)
*/
-public abstract class HandleRepositoryFactory
-{
- /** Array of policy URI(s) (HS and SHIRE) */
- protected String[] policies;
- protected String SQL = "SQL";
- protected String MEMORY = "MEMORY";
- public HandleRepositoryFactory()
- {
- }
+public class HandleRepositoryFactory {
- public static HandleRepositoryFactory getInstance(String policy,
- String repository,
- HttpServlet HS)
- throws HandleException {
+ private static Logger log = Logger.getLogger(HandleRepositoryFactory.class.getName());
- if (policy.equalsIgnoreCase( Constants.POLICY_CLUBSHIB )) {
- if (repository.equalsIgnoreCase( "SQL" )) {
- return new ClubShibSQLHandleRepository(HS);
- } else if (repository.equalsIgnoreCase( "MEMORY" )) {
- return new ClubShibInMemoryHandleRepository(HS);
- } else {
- throw new HandleException("Unspecified repository type.");
- }
- }else{
- throw new HandleException("Unsupported policy found.");
- }
- }
+ public static HandleRepository getInstance(Properties props) throws HandleRepositoryException {
- public abstract HandleEntry getHandleEntry(String handle)
- throws HandleException;
+ if (props.getProperty("edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation") == null) {
+ throw new HandleRepositoryException("No Handle Repository implementaiton specified.");
+ }
+ try {
+ Class implementorClass =
+ Class.forName(
+ props.getProperty("edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation"));
+ Class[] params = new Class[1];
+ params[0] = Class.forName("java.util.Properties");
+ Constructor implementorConstructor = implementorClass.getConstructor(params);
+ Object[] args = new Object[1];
+ args[0] = props;
+ log.debug("Initializing Handle Repository of type (" + implementorClass.getName() + ").");
+ return (HandleRepository) implementorConstructor.newInstance(args);
- public abstract void insertHandleEntry(HandleEntry he)
- throws HandleException;
-
- /* for debugging purposes only */
- public abstract String toHTMLString()
- throws HandleException;
+ } catch (NoSuchMethodException nsme) {
+ log.error(
+ "Failed to instantiate an Handle Repository: HandleRepository "
+ + "implementation must contain a constructor that accepts a Properties bundle for "
+ + "configuration data.");
+ throw new HandleRepositoryException("Failed to instantiate an Handle Repository.");
+ } catch (Exception e) {
+ log.error("Failed to instantiate an Handle Repository: " + e);
+ throw new HandleRepositoryException("Failed to instantiate an Handle Repository: " + e.getMessage());
+ }
+ }
}
-
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
+
+import edu.internet2.middleware.shibboleth.aa.arp.AAPrincipal;
import edu.internet2.middleware.shibboleth.common.*;
import org.opensaml.*;
import sun.misc.BASE64Decoder;
public class HandleServlet extends HttpServlet {
- private HandleRepositoryFactory hrf;
- private long ticketExp;
- private String username=null;
- private HandleServiceSAML hsSAML;
- private String rep;
- private static Logger log = Logger.getLogger(HandleServlet.class.getName());;
-
- public void init()
- throws ServletException
- {
-
- MDC.put("serviceId", "[HS Core]");
-
- ServletConfig sc = getServletConfig();
- ServletContext sctx = sc.getServletContext();
-
- getInitParams();
- log.info("HS: Loading init params");
-
- try {
- edu.internet2.middleware.eduPerson.Init.init();
- InputStream is = sctx.getResourceAsStream(getInitParameter("KSpath"));
- hsSAML = new HandleServiceSAML( getInitParameter("domain"),
- getInitParameter("AAurl"),
- getInitParameter("HSname"),
- getInitParameter("KSpass"),
- getInitParameter("KSkeyalias"),
- getInitParameter("KSkeypass"),
- getInitParameter("certalias"),
- is );
-
- log.info("HS: Initializing Handle Repository with "+rep+" repository type.");
- hrf = getHandleRepository();
- }
- catch (SAMLException ex) {
- log.fatal("Error initializing SAML libraries: "+ ex);
- throw new ServletException( "Error initializing SAML libraries: " + ex );
- }
- catch (java.security.KeyStoreException ex) {
- log.fatal("Error initializing private KeyStore: "+ex);
- throw new ServletException( "Error initializing private KeyStore: " + ex );
- }
- catch (RuntimeException ex) {
- log.fatal("Error initializing eduPerson.Init: "+ ex);
- throw new ServletException( "Error initializing eduPerson.Init: "+ ex);
- }
- catch (HandleException ex) {
- log.fatal("Error initializing Handle Service: " +ex );
- throw new ServletException( "Error initializing Handle Service: " +ex );
- }
- catch (Exception ex) {
- log.fatal("Error in initialization: " +ex );
- throw new ServletException( "Error in initialization: " +ex );
+ protected Properties configuration;
+ protected HandleRepository handleRepository;
+ private HandleServiceSAML hsSAML;
+ private String username;
+ private String rep;
+ private static Logger log = Logger.getLogger(HandleServlet.class.getName());
+ ;
+
+ protected Properties loadConfiguration() throws HandleException {
+
+ //Set defaults
+ Properties defaultProps = new Properties();
+ defaultProps.setProperty(
+ "edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation",
+ "edu.internet2.middleware.shibboleth.hs.provider.MemoryHandleRepository");
+ defaultProps.setProperty("edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL", "1800000");
+ defaultProps.setProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.issuer", "shib2.internet2.edu");
+
+ //Load from file
+ Properties properties = new Properties(defaultProps);
+ String propertiesFileLocation = getInitParameter("OriginPropertiesFile");
+ if (propertiesFileLocation == null) {
+ propertiesFileLocation = "/WEB-INF/conf/origin.properties";
+ }
+ try {
+ log.debug("Loading Configuration from (" + propertiesFileLocation + ").");
+ properties.load(getServletContext().getResourceAsStream(propertiesFileLocation));
+ } catch (IOException e) {
+ log.error("Could not load HS servlet configuration: " + e);
+ throw new HandleException("Could not load HS servlet configuration.");
+ }
+
+ if (log.isDebugEnabled()) {
+ ByteArrayOutputStream debugStream = new ByteArrayOutputStream();
+ PrintStream debugPrinter = new PrintStream(debugStream);
+ properties.list(debugPrinter);
+ log.debug(
+ "Runtime configuration parameters: " + System.getProperty("line.separator") + debugStream.toString());
+ }
+
+ return properties;
}
- if (hsSAML == null) {
- log.fatal("Error initializing SAML libraries: No Profile created." );
- throw new ServletException( "Error initializing SAML libraries: No Profile created." );
- }
+ public void init() throws ServletException {
+
+ MDC.put("serviceId", "[HS Core]");
+ try {
+ configuration = loadConfiguration();
+
+ ServletConfig sc = getServletConfig();
+ ServletContext sctx = sc.getServletContext();
+
+ getInitParams();
+ log.info("HS: Loading init params");
+
+ edu.internet2.middleware.eduPerson.Init.init();
+ InputStream is = sctx.getResourceAsStream(getInitParameter("KSpath"));
+ hsSAML =
+ new HandleServiceSAML(
+ getInitParameter("domain"),
+ getInitParameter("AAurl"),
+ configuration.getProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.issuer"),
+ getInitParameter("KSpass"),
+ getInitParameter("KSkeyalias"),
+ getInitParameter("KSkeypass"),
+ getInitParameter("certalias"),
+ is);
+
+ log.info("HS: Initializing Handle Repository with " + rep + " repository type.");
+ handleRepository = HandleRepositoryFactory.getInstance(configuration);
+
+ } catch (SAMLException ex) {
+ log.fatal("Error initializing SAML libraries: " + ex);
+ throw new ServletException("Error initializing SAML libraries: " + ex);
+ } catch (java.security.KeyStoreException ex) {
+ log.fatal("Error initializing private KeyStore: " + ex);
+ throw new ServletException("Error initializing private KeyStore: " + ex);
+ } catch (RuntimeException ex) {
+ log.fatal("Error initializing eduPerson.Init: " + ex);
+ throw new ServletException("Error initializing eduPerson.Init: " + ex);
+ } catch (HandleException ex) {
+ log.fatal("Error initializing Handle Service: " + ex);
+ throw new ServletException("Error initializing Handle Service: " + ex);
+ } catch (Exception ex) {
+ log.fatal("Error in initialization: " + ex);
+ throw new ServletException("Error in initialization: " + ex);
+ }
+
+ if (hsSAML == null) {
+ log.fatal("Error initializing SAML libraries: No Profile created.");
+ throw new ServletException("Error initializing SAML libraries: No Profile created.");
+ }
- }
-
-
- private void getInitParams() throws ServletException {
-
- String ticket = getInitParameter("ticket");
- if (ticket == null) {
- ticket = "1400000";
}
- ticketExp = Long.parseLong(ticket);
-
- username=getInitParameter("username");
- if ( getInitParameter("domain") == null ||
- getInitParameter("domain").equals("")) {
- throw new ServletException("Cannot find host domain in init parameters");
- }
- if ( getInitParameter("AAurl") == null ||
- getInitParameter("AAurl").equals("")) {
- throw new ServletException("Cannot find host Attribute Authority location in init parameters");
- }
- if ( getInitParameter("HSname") == null ||
- getInitParameter("HSname").equals("")) {
- throw new ServletException("Cannot find Handle Service name in init parameters");
- }
- if ( getInitParameter("KSpath") == null ||
- getInitParameter("KSpath").equals("")) {
- throw new ServletException("Cannot find path to KeyStore file in init parameters");
- }
- if ( getInitParameter("KSpass") == null ||
- getInitParameter("KSpass").equals("")) {
- throw new ServletException("Cannot find password to KeyStore in init parameters");
+ private void getInitParams() throws ServletException {
+
+ username = getInitParameter("username");
+
+ if (getInitParameter("domain") == null || getInitParameter("domain").equals("")) {
+ throw new ServletException("Cannot find host domain in init parameters");
+ }
+ if (getInitParameter("AAurl") == null || getInitParameter("AAurl").equals("")) {
+ throw new ServletException("Cannot find host Attribute Authority location in init parameters");
+ }
+ if (getInitParameter("KSpath") == null || getInitParameter("KSpath").equals("")) {
+ throw new ServletException("Cannot find path to KeyStore file in init parameters");
+ }
+ if (getInitParameter("KSpass") == null || getInitParameter("KSpass").equals("")) {
+ throw new ServletException("Cannot find password to KeyStore in init parameters");
+ }
+ if (getInitParameter("KSkeyalias") == null || getInitParameter("KSkeyalias").equals("")) {
+ throw new ServletException("Cannot find private key alias to KeyStore in init parameters");
+ }
+ if (getInitParameter("KSkeypass") == null || getInitParameter("KSkeypass").equals("")) {
+ throw new ServletException("Cannot find private key password to Keystore in init parameters");
+ }
+ if (getInitParameter("certalias") == null || getInitParameter("certalias").equals("")) {
+ throw new ServletException("Cannot find certificate alias in init parameters");
+ }
+ rep = getInitParameter("repository");
+ if (rep == null || rep.equals("")) {
+ rep = "MEMORY";
+ }
}
- if ( getInitParameter("KSkeyalias") == null ||
- getInitParameter("KSkeyalias").equals("")) {
- throw new ServletException("Cannot find private key alias to KeyStore in init parameters");
- }
- if ( getInitParameter("KSkeypass") == null ||
- getInitParameter("KSkeypass").equals("")) {
- throw new ServletException("Cannot find private key password to Keystore in init parameters");
- }
- if ( getInitParameter("certalias") == null ||
- getInitParameter("certalias").equals("")) {
- throw new ServletException("Cannot find certificate alias in init parameters");
- }
- rep = getInitParameter("repository");
- if ( rep == null || rep.equals("")) {
- rep = "MEMORY";
- }
- }
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
- public void doGet(HttpServletRequest req,
- HttpServletResponse res)
- throws ServletException, IOException
- {
+ log.debug("Recieved a request.");
+ MDC.put("serviceId", UUIDGenerator.getInstance().generateRandomBasedUUID());
+ MDC.put("remoteAddr", req.getRemoteAddr());
+ log.info("Handling request.");
- log.debug("Recieved a request.");
- MDC.put("serviceId", UUIDGenerator.getInstance().generateRandomBasedUUID());
- MDC.put("remoteAddr", req.getRemoteAddr());
- log.info("Handling request.");
+ try {
+ checkRequestParams(req);
- HandleEntry he = null;
+ req.setAttribute("shire", req.getParameter("shire"));
+ req.setAttribute("target", req.getParameter("target"));
- try {
- checkRequestParams(req);
+ String localUsername =
+ (username == null || username.equalsIgnoreCase("REMOTE_USER"))
+ ? req.getRemoteUser()
+ : req.getHeader(username);
+ String handle = handleRepository.getHandle(new AAPrincipal(localUsername));
+ log.info("Issued Handle (" + handle + ") to (" + localUsername + ")");
- req.setAttribute("shire", req.getParameter("shire"));
- req.setAttribute("target", req.getParameter("target"));
+ byte[] buf =
+ hsSAML.prepare(
+ handle,
+ req.getParameter("shire"),
+ req.getRemoteAddr(),
+ req.getAuthType(),
+ new Date(System.currentTimeMillis()));
- he = new HandleEntry(
- (username==null || username.equalsIgnoreCase("REMOTE_USER")) ? req.getRemoteUser() : req.getHeader(username),
- req.getAuthType(),
- ticketExp );
- log.info("Issued Handle (" + he.getHandle() + ") to (" + he.getUsername() + ")");
- hrf.insertHandleEntry( he );
-
- byte[] buf = hsSAML.prepare
- ( he.getHandle(), req.getParameter("shire"),
- req.getRemoteAddr(), he.getAuthType(),
- new Date(he.getAuthInstant()));
+ createForm(req, res, buf);
+ } catch (HandleException ex) {
+ log.error(ex);
+ handleError(req, res, ex);
+ }
- createForm( req, res, buf );
- }
- catch (HandleException ex) {
- log.error(ex);
- handleError( req, res, ex );
}
- }
-
- private void createForm( HttpServletRequest req,
- HttpServletResponse res,
- byte[] buf )
- throws HandleException
- {
- try {
- /**
- * forwarding to hs.jsp for submission
- */
- //Hardcoded to ASCII to ensure Base64 encoding compatibility
- req.setAttribute("assertion", new String(buf, "ASCII"));
-
- if (log.isDebugEnabled()) {
+ private void createForm(HttpServletRequest req, HttpServletResponse res, byte[] buf) throws HandleException {
+ try {
+ /**
+ * forwarding to hs.jsp for submission
+ */
+ //Hardcoded to ASCII to ensure Base64 encoding compatibility
+ req.setAttribute("assertion", new String(buf, "ASCII"));
+
+ if (log.isDebugEnabled()) {
try {
log.debug(
"Dumping generated SAML Response:"
+ System.getProperty("line.separator")
- + new String(
- new BASE64Decoder().decodeBuffer(new String(buf, "ASCII")),
- "UTF8"));
+ + new String(new BASE64Decoder().decodeBuffer(new String(buf, "ASCII")), "UTF8"));
} catch (IOException e) {
log.error("Encountered an error while decoding SAMLReponse for logging purposes.");
}
}
-
-
- RequestDispatcher rd = req.getRequestDispatcher("/hs.jsp");
- rd.forward(req, res);
-
- } catch (IOException ex) {
- throw new HandleException
- ("IO interruption while displaying Handle Service UI." + ex);
- }
-
- catch (ServletException ex) {
- throw new HandleException
- ("Problem displaying Handle Service UI." + ex);
- }
- }
+ RequestDispatcher rd = req.getRequestDispatcher("/hs.jsp");
+ rd.forward(req, res);
- private void handleError( HttpServletRequest req,
- HttpServletResponse res,
- Exception e )
- throws ServletException, IOException {
+ } catch (IOException ex) {
+ throw new HandleException("IO interruption while displaying Handle Service UI." + ex);
+ } catch (ServletException ex) {
+ throw new HandleException("Problem displaying Handle Service UI." + ex);
+ }
- req.setAttribute("errorText", e.toString());
- req.setAttribute("requestURL", req.getRequestURI().toString());
- RequestDispatcher rd = req.getRequestDispatcher("/hserror.jsp");
-
- rd.forward(req, res);
-
- }
+ }
-
- private void checkRequestParams( HttpServletRequest req )
- throws HandleException {
+ private void handleError(HttpServletRequest req, HttpServletResponse res, Exception e)
+ throws ServletException, IOException {
+
+ req.setAttribute("errorText", e.toString());
+ req.setAttribute("requestURL", req.getRequestURI().toString());
+ RequestDispatcher rd = req.getRequestDispatcher("/hserror.jsp");
+
+ rd.forward(req, res);
- if ( req.getParameter("target") == null
- || req.getParameter("target").equals("")) {
- throw new HandleException("Invalid data from SHIRE: no target URL received.");
- }
- if ((req.getParameter("shire") == null)
- || (req.getParameter("shire").equals(""))) {
- throw new HandleException("Invalid data from SHIRE: No acceptance URL received.");
- }
- if ((req.getRemoteUser() == null)
- || (req.getRemoteUser().equals(""))) {
- throw new HandleException("Unable to authenticate remote user");
}
- if ((req.getRemoteAddr() == null)
- || (req.getRemoteAddr().equals(""))) {
- throw new HandleException("Unable to obtain client address.");
- }
- }
-
-
- private synchronized HandleRepositoryFactory getHandleRepository()
- throws HandleException{
-
- ServletConfig sc = getServletConfig();
- ServletContext sctx = sc.getServletContext();
- HandleRepositoryFactory hrf = (HandleRepositoryFactory)sctx.getAttribute("HandleRepository");
-
- log.debug("Context attribute for HandleRepository: "+hrf);
-
- if(hrf == null){
- // make one
- String repositoryType = this.getServletContext().getInitParameter("repository");
- hrf = HandleRepositoryFactory.getInstance(Constants.POLICY_CLUBSHIB,
- repositoryType,
- this );
- sctx.setAttribute("HandleRepository", hrf);
- log.info("A new HandleRepository created by HS: "+hrf);
+
+ private void checkRequestParams(HttpServletRequest req) throws HandleException {
+
+ if (req.getParameter("target") == null || req.getParameter("target").equals("")) {
+ throw new HandleException("Invalid data from SHIRE: no target URL received.");
+ }
+ if ((req.getParameter("shire") == null) || (req.getParameter("shire").equals(""))) {
+ throw new HandleException("Invalid data from SHIRE: No acceptance URL received.");
+ }
+ if ((req.getRemoteUser() == null) || (req.getRemoteUser().equals(""))) {
+ throw new HandleException("Unable to authenticate remote user");
+ }
+ if ((req.getRemoteAddr() == null) || (req.getRemoteAddr().equals(""))) {
+ throw new HandleException("Unable to obtain client address.");
+ }
}
- return hrf;
- }
+
}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package edu.internet2.middleware.shibboleth.hs.provider;
+
+import java.security.Principal;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+import edu.internet2.middleware.shibboleth.hs.HandleRepository;
+import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
+
+/**
+ * <code>HandleRepository</code> shared implementation code.
+ *
+ * @author Walter Hoehn (wassa@columbia.edu)
+ */
+public abstract class BaseHandleRepository implements HandleRepository {
+
+ protected long handleTTL = 1800000;
+ private static Logger log = Logger.getLogger(BaseHandleRepository.class.getName());
+
+ protected BaseHandleRepository(Properties properties) throws HandleRepositoryException {
+ try {
+ if (properties.getProperty("edu.internet2.middleware.shibboleth.hs.HandleRepository.handleTTL", null)
+ != null) {
+
+ handleTTL =
+ Long.parseLong(
+ properties.getProperty(
+ "edu.internet2.middleware.shibboleth.hs.HandleRepository.handleTTL",
+ null));
+ if (handleTTL < 30000) {
+ log.warn(
+ "You have set the Attribute Query Handle \"Time To Live\' to a very low "
+ + "value. It is recommended that you increase it.");
+ }
+ }
+ } catch (NumberFormatException nfe) {
+ log.error(
+ "Value for (edu.internet2.middleware.shibboleth.hs.HandleRepository.handleTTL) must be a long integer.");
+ throw new HandleRepositoryException("Value for (edu.internet2.middleware.shibboleth.hs.HandleRepository.handleTTL) must be a long integer.");
+ }
+
+ }
+
+ protected class HandleEntry {
+ protected Principal principal;
+ protected long creationTime;
+
+ protected HandleEntry(Principal principal) {
+ this.principal = principal;
+ creationTime = System.currentTimeMillis();
+ }
+
+ protected boolean isExpired() {
+ return ((System.currentTimeMillis() - creationTime) > handleTTL);
+ }
+ }
+}
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
+
package edu.internet2.middleware.shibboleth.hs.provider;
import java.security.Principal;
+import java.util.Properties;
import edu.internet2.middleware.shibboleth.hs.HandleRepository;
+import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
/**
* <code>HandleRepository</code> implementation that employs the use of a shard secret
*
* @author Walter Hoehn (wassa@columbia.edu)
*/
-public class CryptoHandleRepository implements HandleRepository {
+public class CryptoHandleRepository extends BaseHandleRepository implements HandleRepository {
+
+ protected CryptoHandleRepository(Properties properties) throws HandleRepositoryException {
+ super(properties);
+ }
/**
* @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getHandle(Principal)
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package edu.internet2.middleware.shibboleth.hs.provider;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.doomdark.uuid.UUIDGenerator;
+
+import edu.internet2.middleware.shibboleth.hs.HandleRepository;
+import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
+
+/**
+ * <code>HandleRepository</code> implementation that uses a static cache. This requires
+ * that the HS and AA run in the same JVM.
+ *
+ * @author Walter Hoehn (wassa@columbia.edu)
+ */
+public class MemoryHandleRepository extends BaseHandleRepository implements HandleRepository {
+
+ protected static Map handleEntries = new HashMap();
+
+ public MemoryHandleRepository(Properties properties) throws HandleRepositoryException {
+ super(properties);
+ }
+
+ /**
+ * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getHandle(Principal)
+ */
+ public String getHandle(Principal principal) {
+ String handle = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
+ synchronized (handleEntries) {
+ handleEntries.put(handle, new HandleEntry(principal));
+ }
+ return handle;
+ }
+
+ /**
+ * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getPrincipal(String)
+ */
+ public Principal getPrincipal(String handle) {
+ synchronized (handleEntries) {
+ if (!handleEntries.containsKey(handle)) {
+ return null;
+ }
+ }
+ HandleEntry handleEntry;
+ synchronized (handleEntries) {
+ handleEntry = (HandleEntry) handleEntries.get(handle);
+ }
+ if (handleEntry.isExpired()) {
+ synchronized (handleEntries) {
+ handleEntries.remove(handle);
+ }
+ return null;
+ } else {
+ return handleEntry.principal;
+ }
+ }
+
+}
<param-value>shibdev.edu</param-value>
</init-param>
<init-param>
- <param-name>HSname</param-name>
- <param-value>shib2.internet2.edu</param-value>
- </init-param>
- <init-param>
- <param-name>ticket</param-name>
- <param-value>1400000</param-value>
- </init-param>
- <init-param>
<param-name>AAurl</param-name>
<param-value>https://shib2.internet2.edu/shibboleth-origin/servlet/AA</param-value>
</init-param>
#Full Path to ARP repository
#edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository.Path = \
- /opt/local/tomcat/webapps/shibboleth/WEB-INF/conf/arps/
+# /opt/local/tomcat/webapps/shibboleth/WEB-INF/conf/arps/
edu.internet2.middleware.shibboleth.aa.arp.ArpRepository.implementation = \
edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository
edu.internet2.middleware.shibboleth.aa.AAServlet.authorityName = shib2.internet2.edu
edu.internet2.middleware.shibboleth.aa.AAServlet.ldapUserDnPhrase = uid=
-
+#edu.internet2.middleware.shibboleth.aa.arp.BaseArpRepository.ArpTTL = 300000
java.naming.factory.initial=edu.internet2.middleware.shibboleth.aaLocal.EchoCtxFactory
+#java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
#java.naming.provider.url = ldap://shib2.internet2.edu/ou=People,dc=internet2,dc=edu
#java.naming.security.principal =
#java.naming.security.credentials =
+#edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation = \
+# edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository
+
+edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation = \
+ edu.internet2.middleware.shibboleth.hs.provider.MemoryHandleRepository
+
+edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL = 1800000
+edu.internet2.middleware.shibboleth.hs.HandleServlet.issuer = shib2.internet2.edu
\ No newline at end of file