|
From: <mol...@us...> - 2008-12-03 16:07:10
|
Revision: 931
http://openutils.svn.sourceforge.net/openutils/?rev=931&view=rev
Author: molaschi
Date: 2008-12-03 16:06:59 +0000 (Wed, 03 Dec 2008)
Log Message:
-----------
add openutils mgnlcas module
Modified Paths:
--------------
trunk/pom.xml
Added Paths:
-----------
trunk/openutils-mgnlcas/
trunk/openutils-mgnlcas/pom.xml
trunk/openutils-mgnlcas/src/
trunk/openutils-mgnlcas/src/main/
trunk/openutils-mgnlcas/src/main/java/
trunk/openutils-mgnlcas/src/main/java/info/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/callback/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/callback/CompositeCallback.java
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/PatternDelegate.java
trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/UrlPatternDelegate.java
trunk/openutils-mgnlcas/src/main/java/net/
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CASAuthenticationModule.java
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasClientCallback.java
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasLogin.java
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasMagnoliaUser.java
trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/RequestUtils.java
trunk/openutils-mgnlcas/src/main/resources/
trunk/openutils-mgnlcas/src/site/
Added: trunk/openutils-mgnlcas/pom.xml
===================================================================
--- trunk/openutils-mgnlcas/pom.xml (rev 0)
+++ trunk/openutils-mgnlcas/pom.xml 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,79 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>net.sourceforge.openutils</groupId>
+ <artifactId>openutils</artifactId>
+ <version>10</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>jar</packaging>
+ <artifactId>openutils-cas</artifactId>
+ <name>openutils-cas</name>
+ <version>1.0-SNAPSHOT</version>
+ <licenses>
+ <license>
+ <name>GPLv3</name>
+ <url>http://www.gnu.org/licenses/gpl-3.0.txt</url>
+ </license>
+ </licenses>
+ <build>
+ <resources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>META-INF/magnolia/*</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>info.magnolia</groupId>
+ <artifactId>magnolia-jaas</artifactId>
+ <version>3.6.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jasig.cas</groupId>
+ <artifactId>cas-client-core</artifactId>
+ <version>3.1.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ <repositories>
+ <repository>
+ <id>repository.magnolia.info</id>
+ <name>magnolia repository</name>
+ <url>http://svn.magnolia.info/maven/m2</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>jasig-repository</id>
+ <name>JA-SIG Maven2 Repository</name>
+ <url>http://developer.ja-sig.org/maven2</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+</project>
Added: trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/callback/CompositeCallback.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/callback/CompositeCallback.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/security/auth/callback/CompositeCallback.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,115 @@
+// DONE in magnolia 3.6.2
+/**
+ * This file Copyright (c) 2003-2008 Magnolia International
+ * Ltd. (http://www.magnolia.info). All rights reserved.
+ *
+ *
+ * This file is dual-licensed under both the Magnolia
+ * Network Agreement and the GNU General Public License.
+ * You may elect to use one or the other of these licenses.
+ *
+ * This file is distributed in the hope that it will be
+ * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * Redistribution, except as permitted by whichever of the GPL
+ * or MNA you select, is prohibited.
+ *
+ * 1. For the GPL license (GPL), you can redistribute and/or
+ * modify this file under the terms of the GNU General
+ * Public License, Version 3, as published by the Free Software
+ * Foundation. You should have received a copy of the GNU
+ * General Public License, Version 3 along with this program;
+ * if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 2. For the Magnolia Network Agreement (MNA), this file
+ * and the accompanying materials are made available under the
+ * terms of the MNA which accompanies this distribution, and
+ * is available at http://www.magnolia.info/mna.html
+ *
+ * Any modifications to this file must keep this entire header
+ * intact.
+ *
+ */
+package info.magnolia.cms.security.auth.callback;
+
+import info.magnolia.cms.util.PatternDelegate;
+import info.magnolia.cms.util.UrlPatternDelegate;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.ArrayUtils;
+
+
+/**
+ * <p>
+ * A simple "composite" callback that delegates to other callbacks based on rules (a list of {@link PatternDelegate}).
+ * </p>
+ * <p>
+ * It can be used to configured different callbacks for different urls, see this sample configuration for an example:
+ * </p>
+ *
+ * <pre>
+ * + clientCallback
+ * + patterns
+ * + admin
+ * + delegate
+ * - class info.magnolia.cms.security.auth.callback.FormClientCallback
+ * - loginForm /mgnl-resources/loginForm/login.html
+ * - realmName Magnolia
+ * - class info.magnolia.cms.util.UrlPatternDelegate
+ * - url ./magnolia*
+ * + public
+ * + delegate
+ * - class info.magnolia.cms.security.auth.callback.FormClientCallback
+ * - loginForm /mgnl-resources/public-login.html
+ * - realmName Magnolia
+ * - class info.magnolia.cms.util.UrlPatternDelegate
+ * - url /*
+ * - class info.magnolia.cms.security.auth.callback.CompositeCallback
+ * </pre>
+ * @author fgiust
+ * @version $Id: CompositeCallback.java 4124 2008-09-22 14:56:46Z fgiust $
+ */
+public class CompositeCallback implements HttpClientCallback
+{
+
+ private PatternDelegate[] patterns = new UrlPatternDelegate[0];
+
+ /**
+ * Delegates the processing to the first matching Callback in patterns.
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ */
+ public void handle(HttpServletRequest request, HttpServletResponse response)
+ {
+ for (int i = 0; i < patterns.length; i++)
+ {
+ PatternDelegate currentPattern = patterns[i];
+ if (currentPattern.match(request))
+ {
+ ((HttpClientCallback) currentPattern.getDelegate()).handle(request, response);
+ break;
+ }
+ }
+ }
+
+ /**
+ * @return array of configured PatternDelegate.
+ */
+ public PatternDelegate[] getPatterns()
+ {
+ return this.patterns;
+ }
+
+ /**
+ * Adds a new PatternDelegate. Used by Content2Bean .
+ * @param pattern PatternDelegate instance
+ */
+ public void addPattern(PatternDelegate pattern)
+ {
+ this.patterns = (PatternDelegate[]) ArrayUtils.add(this.patterns, pattern);
+ }
+}
\ No newline at end of file
Added: trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/PatternDelegate.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/PatternDelegate.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/PatternDelegate.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,62 @@
+// DONE in magnolia 3.6.2
+/**
+ * This file Copyright (c) 2003-2008 Magnolia International
+ * Ltd. (http://www.magnolia.info). All rights reserved.
+ *
+ *
+ * This file is dual-licensed under both the Magnolia
+ * Network Agreement and the GNU General Public License.
+ * You may elect to use one or the other of these licenses.
+ *
+ * This file is distributed in the hope that it will be
+ * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * Redistribution, except as permitted by whichever of the GPL
+ * or MNA you select, is prohibited.
+ *
+ * 1. For the GPL license (GPL), you can redistribute and/or
+ * modify this file under the terms of the GNU General
+ * Public License, Version 3, as published by the Free Software
+ * Foundation. You should have received a copy of the GNU
+ * General Public License, Version 3 along with this program;
+ * if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 2. For the Magnolia Network Agreement (MNA), this file
+ * and the accompanying materials are made available under the
+ * terms of the MNA which accompanies this distribution, and
+ * is available at http://www.magnolia.info/mna.html
+ *
+ * Any modifications to this file must keep this entire header
+ * intact.
+ *
+ */
+package info.magnolia.cms.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * A simple generic interface that can be used to configure anything that can be selected based on some conditions (i.e.
+ * a different login page based on the request URI or host).
+ * @author fgiust
+ * @version $Id: PatternDelegate.java 4124 2008-09-22 14:56:46Z fgiust $
+ */
+public interface PatternDelegate
+{
+
+ /**
+ * Does the current request match the expected condition?
+ * @param request HttpServletRequest
+ * @return <code>true</code> if the current request matches the expected conditions
+ */
+ boolean match(HttpServletRequest request);
+
+ /**
+ * Returns the delegate that this bean holds. This method is usually called to retrieve the delegate object after
+ * match() returns true.
+ * @return delegate object
+ */
+ Object getDelegate();
+}
Added: trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/UrlPatternDelegate.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/UrlPatternDelegate.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/info/magnolia/cms/util/UrlPatternDelegate.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,153 @@
+// DONE in magnolia 3.6.2
+/**
+ * This file Copyright (c) 2003-2008 Magnolia International
+ * Ltd. (http://www.magnolia.info). All rights reserved.
+ *
+ *
+ * This file is dual-licensed under both the Magnolia
+ * Network Agreement and the GNU General Public License.
+ * You may elect to use one or the other of these licenses.
+ *
+ * This file is distributed in the hope that it will be
+ * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * Redistribution, except as permitted by whichever of the GPL
+ * or MNA you select, is prohibited.
+ *
+ * 1. For the GPL license (GPL), you can redistribute and/or
+ * modify this file under the terms of the GNU General
+ * Public License, Version 3, as published by the Free Software
+ * Foundation. You should have received a copy of the GNU
+ * General Public License, Version 3 along with this program;
+ * if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 2. For the Magnolia Network Agreement (MNA), this file
+ * and the accompanying materials are made available under the
+ * terms of the MNA which accompanies this distribution, and
+ * is available at http://www.magnolia.info/mna.html
+ *
+ * Any modifications to this file must keep this entire header
+ * intact.
+ *
+ */
+package info.magnolia.cms.util;
+
+import info.magnolia.context.MgnlContext;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+
+/**
+ * An implementation of {@link PatternDelegate} that evaluates as condition a request uri patter or a hostname pattern.
+ * @author fgiust
+ * @version $Id: UrlPatternDelegate.java 4124 2008-09-22 14:56:46Z fgiust $
+ */
+public class UrlPatternDelegate implements PatternDelegate
+{
+
+ private String url;
+
+ private SimpleUrlPattern urlPattern;
+
+ private String host;
+
+ private SimpleUrlPattern hostPattern;
+
+ private Object delegate;
+
+ /**
+ * The configured Url
+ * @return the configured Url
+ */
+ public String getUrl()
+ {
+ return url;
+ }
+
+ /**
+ * Sets the Url pattern (using {@link SimpleUrlPattern} internally)
+ * @param pattern url pattern
+ */
+ public void setUrl(String pattern)
+ {
+ this.url = pattern;
+ this.urlPattern = new SimpleUrlPattern(pattern);
+ }
+
+ /**
+ * The configured host
+ * @return the configured host
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Sets the host pattern (using {@link SimpleUrlPattern} internally)
+ * @param host host pattern
+ */
+ public void setHost(String host)
+ {
+ this.host = host;
+ this.hostPattern = new SimpleUrlPattern(host);
+ }
+
+ /**
+ * Compares the reques with the url and host patterns
+ * @param request HttpServletRequest
+ * @return <code>true</code> if the pattern matches the configured host (if set) and url (if set)
+ */
+ public boolean match(HttpServletRequest request)
+ {
+
+ boolean match = true;
+
+ if (hostPattern != null)
+ {
+ match = hostPattern.match(request.getServerName());
+ }
+
+ if (urlPattern != null)
+ {
+ match = urlPattern.match(MgnlContext.getAggregationState().getCurrentURI());
+ }
+
+ return match;
+ }
+
+ /**
+ * Sets the delegate.
+ * @param delegate the delegate to set
+ */
+ public void setDelegate(Object delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ /**
+ * Returns the delegate.
+ * @return the delegate
+ */
+ public Object getDelegate()
+ {
+ return delegate;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("url", this.url).append(
+ "host",
+ this.host).toString();
+ }
+
+}
\ No newline at end of file
Added: trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CASAuthenticationModule.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CASAuthenticationModule.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CASAuthenticationModule.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,412 @@
+/**
+ * Copyright Openmind http://www.openmindonline.it
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package net.sourceforge.openutils.mgnlcas;
+
+import info.magnolia.cms.security.User;
+import info.magnolia.cms.security.auth.Entity;
+import info.magnolia.cms.security.auth.GroupList;
+import info.magnolia.cms.security.auth.RoleList;
+import info.magnolia.cms.security.auth.callback.RealmCallback;
+import info.magnolia.cms.util.BooleanUtil;
+import info.magnolia.jaas.principal.EntityImpl;
+import info.magnolia.jaas.principal.GroupListImpl;
+import info.magnolia.jaas.principal.RoleListImpl;
+import info.magnolia.jaas.sp.AbstractLoginModule;
+import info.magnolia.jaas.sp.UserAwareLoginModule;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.TextInputCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.jasig.cas.client.authentication.AttributePrincipal;
+import org.jasig.cas.client.validation.Assertion;
+import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
+import org.jasig.cas.client.validation.TicketValidationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class implements a JAAS <code>LoginModule</code> that defers authentication to CAS. See the <a
+ * href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html"> JAAS documentation</a> for details
+ * about configuration and architecture.
+ * <p>
+ * The calling application's <code>CallbackHandler</code> MUST return the <strong>ticket</strong> for a
+ * <code>TextInputCallback</code> whose prompt is "ticket".
+ * <p>
+ * The CAS <strong>service</strong> MAY be hard-coded into the configuration; if it is not, the calling application's
+ * <code>CallbackHandler</code> MAY return the <strong>service</strong> in a <code>TextInputCallback</code> whose prompt
+ * is "service".
+ * <p>
+ * The <strong>cas_validate_url</strong> MUST be hard-coded in the configuration
+ * <p>
+ * Sample jaas.config configuration:
+ * </p>
+ *
+ * <pre>
+ * magnolia {
+ * net.sourceforge.openutils.mgnlcas.CASAuthenticationModule
+ * requisite
+ * realm=cas;
+ * info.magnolia.jaas.sp.jcr.JCRAuthenticationModule
+ * requisite
+ * skip_on_previous_success=true;
+ * info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required;
+ * };
+ *
+ *
+ * </pre>
+ * @author fgiust
+ * @version $Id: CASAuthenticationModule.java 4124 2008-09-22 14:56:46Z fgiust $
+ */
+public class CASAuthenticationModule extends AbstractLoginModule implements LoginModule, UserAwareLoginModule
+{
+
+ protected Subject subject;
+
+ protected CallbackHandler callbackHandler;
+
+ protected String casValidateUrl;
+
+ protected String service;
+
+ protected AttributePrincipal principal;
+
+ protected User user;
+
+ private boolean skipOnPreviousSuccess;
+
+ private String defaultGroup;
+
+ private String defaultRole;
+
+ private String rolesAttribute = "roles";
+
+ private String groupsAttribute = "groups";
+
+ protected Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * @param subject
+ * @param callbackHandler
+ * @param sharedState
+ * @param options can contain
+ * <ul>
+ * <li><strong>cas_validate_url</strong> (required)</li>
+ * <li><strong>service</strong> (optional)</li>
+ * </ul>
+ */
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
+ {
+ super.initialize(subject, callbackHandler, sharedState, options);
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.casValidateUrl = (String) options.get("cas_validate_url");
+ this.service = (String) options.get("service");
+ this.defaultGroup = (String) options.get("default_group");
+ this.defaultRole = (String) options.get("default_role");
+
+ if (options.get("roles_attribute") != null)
+ {
+ rolesAttribute = (String) options.get("roles_attribute");
+ }
+
+ if (options.get("groups_attribute") != null)
+ {
+ groupsAttribute = (String) options.get("groups_attribute");
+ }
+
+ // private on AbstractLoginModule
+ this.skipOnPreviousSuccess = BooleanUtil
+ .toBoolean((String) options.get(OPTION_SKIP_ON_PREVIOUS_SUCCESS), false);
+ }
+
+ @Override
+ public boolean login() throws LoginException
+ {
+ if (skipOnPreviousSuccess && this.getSharedStatus() == STATUS_SUCCEEDED)
+ {
+ return true;
+ }
+
+ if (this.callbackHandler == null)
+ {
+ throw new LoginException("Error: no CallbackHandler available");
+ }
+
+ List<Callback> callbacksList = new ArrayList<Callback>();
+
+ TextInputCallback ticketCallback = new TextInputCallback("ticket");
+ TextInputCallback serviceCallback = null;
+ TextInputCallback casValidateUrlCallback = null;
+ RealmCallback realmCallback = null;
+
+ callbacksList.add(ticketCallback);
+
+ if (StringUtils.isBlank(service))
+ {
+ // the service has not been hardcoded, so give the application
+ // a callback which can be used to specify it
+ serviceCallback = new TextInputCallback("service");
+ callbacksList.add(serviceCallback);
+ }
+
+ if (StringUtils.isBlank(service))
+ {
+ // the casValidateUrl has not been hardcoded, so give the application
+ // a callback which can be used to specify it
+ casValidateUrlCallback = new TextInputCallback("casValidateUrl");
+ callbacksList.add(casValidateUrlCallback);
+ }
+
+ // if the realm is not defined in the jaas configuration
+ // we ask use a callback to get the value
+ if (this.useRealmCallback)
+ {
+ realmCallback = new RealmCallback();
+ callbacksList.add(realmCallback);
+ }
+
+ this.success = false;
+
+ Callback[] callbacks = callbacksList.toArray(new Callback[callbacksList.size()]);
+
+ try
+ {
+ this.callbackHandler.handle(callbacks);
+
+ }
+ catch (IOException e)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Exception caught", e);
+ }
+ throw new LoginException(e.toString());
+ }
+ catch (UnsupportedCallbackException e)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug(e.getMessage(), e);
+ }
+ throw new LoginException(e.getCallback().toString() + " not available");
+ }
+
+ // this.name = ((NameCallback) callbacks[0]).getName();
+ // this.pswd = ((PasswordCallback) callbacks[1]).getPassword();
+ if (this.useRealmCallback)
+ {
+ this.realm = StringUtils.defaultIfEmpty(realmCallback.getRealm(), this.realm);
+ }
+
+ String ticket = ticketCallback.getText();
+ if (StringUtils.isNotEmpty(ticket))
+ {
+ if (serviceCallback != null)
+ {
+ service = serviceCallback.getText();
+ }
+
+ if (casValidateUrlCallback != null)
+ {
+ casValidateUrl = casValidateUrlCallback.getText();
+ }
+
+ Cas20ProxyTicketValidator pv = new Cas20ProxyTicketValidator(casValidateUrl);
+
+ Assertion assertion;
+ try
+ {
+ assertion = pv.validate(ticket, service);
+ }
+ catch (TicketValidationException e)
+ {
+ throw new LoginException(e.getMessage());
+ }
+
+ if (assertion.getPrincipal() != null)
+ {
+
+ principal = assertion.getPrincipal();
+ subject.getPrincipals().add(principal);
+
+ setEntity();
+
+ user = new CasMagnoliaUser(subject);
+
+ this.success = true;
+ this.setSharedStatus(STATUS_SUCCEEDED);
+ }
+
+ }
+
+ return this.success;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void validateUser() throws LoginException
+ {
+
+ }
+
+ @Override
+ public boolean commit() throws LoginException
+ {
+ if (principal != null)
+ {
+ subject.getPrincipals().add(principal);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public User getUser()
+ {
+ return user;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean release()
+ {
+ if (principal != null)
+ {
+ principal = null;
+ user = null;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setACL()
+ {
+ // delegate to the Authorization module
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setEntity()
+ {
+ EntityImpl entity = new EntityImpl();
+ entity.addProperty(Entity.NAME, this.principal.getName());
+
+ Map<String, String> attributes = this.principal.getAttributes();
+
+ String fullName = attributes.get("title");
+ if (fullName != null)
+ {
+ entity.addProperty(Entity.FULL_NAME, fullName);
+ }
+
+ entity.addProperty(Entity.LANGUAGE, "en");
+
+ this.subject.getPrincipals().add(entity);
+
+ String[] roles = StringUtils.split(attributes.get(rolesAttribute));
+ String[] groups = StringUtils.split(attributes.get(groupsAttribute));
+
+ if (roles == null)
+ {
+ roles = new String[0];
+ }
+ if (groups == null)
+ {
+ groups = new String[0];
+ }
+
+ if (defaultGroup != null)
+ {
+ groups = (String[]) ArrayUtils.add(groups, defaultGroup);
+ }
+
+ if (defaultRole != null)
+ {
+ roles = (String[]) ArrayUtils.add(roles, defaultRole);
+ }
+
+ addGroups(groups);
+ addRoles(roles);
+
+ }
+
+ /**
+ * Set the list of groups, info.magnolia.jaas.principal.GroupList.
+ * @param groups array of group names
+ */
+ protected void addGroups(String[] groups)
+ {
+ GroupList groupList = new GroupListImpl();
+
+ for (int j = 0; j < groups.length; j++)
+ {
+ String group = groups[j];
+ groupList.add(group);
+ addGroupName(group);
+ }
+
+ this.subject.getPrincipals().add(groupList);
+ }
+
+ /**
+ * Set the list of roles, info.magnolia.jaas.principal.RoleList.
+ * @param roles array of role names
+ */
+ protected void addRoles(String[] roles)
+ {
+ RoleList roleList = new RoleListImpl();
+
+ for (int j = 0; j < roles.length; j++)
+ {
+ String role = roles[j];
+ roleList.add(role);
+ addRoleName(role);
+ }
+
+ this.subject.getPrincipals().add(roleList);
+ }
+
+}
\ No newline at end of file
Added: trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasClientCallback.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasClientCallback.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasClientCallback.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,216 @@
+/**
+ * Copyright Openmind http://www.openmindonline.it
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package net.sourceforge.openutils.mgnlcas;
+
+import info.magnolia.cms.security.auth.callback.AbstractHttpClientCallback;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.jasig.cas.client.util.CommonUtils;
+import org.jasig.cas.client.validation.Assertion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Magnolia CAS Callback, based on CAS org.jasig.cas.client.authentication.AuthenticationFilter
+ * @author fgiust
+ * @version $Id: CasClientCallback.java 4896 2008-10-08 16:23:10Z manuel $
+ */
+public class CasClientCallback extends AbstractHttpClientCallback
+{
+
+ /**
+ * Represents the constant for where the gateway flag will be located in session.
+ */
+ public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";
+
+ /**
+ * Represents the constant for where the assertion will be located in session.
+ */
+ public static final String CONST_CAS_ASSERTION = "_const_cas_assertion_";
+
+ private Logger log = LoggerFactory.getLogger(CasClientCallback.class);
+
+ /**
+ * Defines the parameter to look for for the artifact.
+ */
+ private String artifactParameterName = "ticket";
+
+ /**
+ * Defines the parameter to look for for the service.
+ */
+ private String serviceParameterName = "service";
+
+ /**
+ * Sets where response.encodeUrl should be called on service urls when constructed.
+ */
+ private boolean encodeServiceUrl = true;
+
+ /**
+ * The URL to the CAS Server login.
+ */
+ private String casServerLoginUrl;
+
+ /**
+ * Whether to send the renew request or not.
+ */
+ private boolean renew;
+
+ /**
+ * Whether to send the gateway request or not.
+ */
+ private boolean gateway;
+
+ public final void setRenew(final boolean renew)
+ {
+ this.renew = renew;
+ }
+
+ public final void setGateway(final boolean gateway)
+ {
+ this.gateway = gateway;
+ }
+
+ public final void setCasServerLoginUrl(final String casServerLoginUrl)
+ {
+ this.casServerLoginUrl = casServerLoginUrl;
+ }
+
+ /**
+ * Sets the artifactParameterName.
+ * @param artifactParameterName the artifactParameterName to set
+ */
+ public void setArtifactParameterName(String artifactParameterName)
+ {
+ this.artifactParameterName = artifactParameterName;
+ }
+
+ /**
+ * Sets the serviceParameterName.
+ * @param serviceParameterName the serviceParameterName to set
+ */
+ public void setServiceParameterName(String serviceParameterName)
+ {
+ this.serviceParameterName = serviceParameterName;
+ }
+
+ /**
+ * Sets the encodeServiceUrl.
+ * @param encodeServiceUrl the encodeServiceUrl to set
+ */
+ public void setEncodeServiceUrl(boolean encodeServiceUrl)
+ {
+ this.encodeServiceUrl = encodeServiceUrl;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void doCallback(HttpServletRequest request, HttpServletResponse response)
+ {
+
+ final HttpSession session = request.getSession(false);
+
+ if (session != null)
+ {
+ // don't redirect to cas if user is already logged in
+ if (session.getAttribute("info.magnolia.context.UserContextImpl.user") != null)
+ {
+ try
+ {
+ request.getRequestDispatcher("/errors/401.html").forward(request, response);
+ }
+ catch (ServletException e)
+ {
+ // ignore
+ }
+ catch (IOException e)
+ {
+ // ignore
+ }
+ return;
+ }
+ }
+ final String ticket = request.getParameter(this.artifactParameterName);
+ final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
+ final boolean wasGatewayed = session != null && session.getAttribute(CONST_CAS_GATEWAY) != null;
+
+ if (CommonUtils.isBlank(ticket) && assertion == null && !wasGatewayed)
+ {
+
+ String service = RequestUtils.absoluteUrl(request);
+ log.debug("no ticket and no assertion found");
+ if (this.gateway)
+ {
+ log.debug("setting gateway attribute in session");
+ request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");
+ }
+
+ final String serviceUrl = CommonUtils.constructServiceUrl(
+ request,
+ response,
+ service,
+ null,
+ this.artifactParameterName,
+ this.encodeServiceUrl);
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Constructed service url: " + serviceUrl);
+ }
+
+ String urlToRedirectTo = CommonUtils.constructRedirectUrl(
+ this.casServerLoginUrl,
+ this.serviceParameterName,
+ serviceUrl,
+ this.renew,
+ this.gateway);
+
+ urlToRedirectTo = urlToRedirectTo + "&locale=" + request.getLocale().toString();
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("redirecting to \"" + urlToRedirectTo + "\"");
+ }
+
+ try
+ {
+ response.sendRedirect(urlToRedirectTo);
+ }
+ catch (IOException e)
+ {
+ log.error(e.getMessage(), e);
+ }
+ return;
+ }
+
+ if (session != null)
+ {
+ log.debug("removing gateway attribute from session");
+ session.setAttribute(CONST_CAS_GATEWAY, null);
+ }
+ }
+
+}
Added: trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasLogin.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasLogin.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasLogin.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,242 @@
+/**
+ * Copyright Openmind http://www.openmindonline.it
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package net.sourceforge.openutils.mgnlcas;
+
+import info.magnolia.cms.security.SecuritySupport;
+import info.magnolia.cms.security.User;
+import info.magnolia.cms.security.auth.callback.RealmCallback;
+import info.magnolia.cms.security.auth.login.LoginHandler;
+import info.magnolia.cms.security.auth.login.LoginHandlerBase;
+import info.magnolia.cms.security.auth.login.LoginResult;
+
+import java.io.IOException;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.TextInputCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @author fgiust
+ * @version $Id: CasLogin.java 4266 2008-09-25 08:18:30Z daniela $
+ */
+public class CasLogin extends LoginHandlerBase implements LoginHandler
+{
+
+ private static final Logger log = LoggerFactory.getLogger(CasLogin.class);
+
+ /**
+ * Defines the parameter to look for for the artifact.
+ */
+ private String artifactParameterName = "ticket";
+
+ /**
+ * The JAAS chain/module to use.
+ */
+ private String jaasChain = "magnolia";
+
+ private String realm;
+
+ private String casValidateUrl;
+
+ /**
+ * Sets the artifactParameterName.
+ * @param artifactParameterName the artifactParameterName to set
+ */
+ public void setArtifactParameterName(String artifactParameterName)
+ {
+ this.artifactParameterName = artifactParameterName;
+ }
+
+ public String getJaasChain()
+ {
+ return this.jaasChain;
+ }
+
+ public void setJaasChain(String jaasChain)
+ {
+ this.jaasChain = jaasChain;
+ }
+
+ /**
+ * Returns the realm.
+ * @return the realm
+ */
+ public String getRealm()
+ {
+ return realm;
+ }
+
+ /**
+ * Sets the realm.
+ * @param realm the realm to set
+ */
+ public void setRealm(String realm)
+ {
+ this.realm = realm;
+ }
+
+ /**
+ * Returns the casValidateUrl.
+ * @return the casValidateUrl
+ */
+ public String getCasValidateUrl()
+ {
+ return casValidateUrl;
+ }
+
+ /**
+ * Sets the casValidateUrl.
+ * @param casValidateUrl the casValidateUrl to set
+ */
+ public void setCasValidateUrl(String casValidateUrl)
+ {
+ this.casValidateUrl = casValidateUrl;
+ }
+
+ public LoginResult handle(HttpServletRequest request, HttpServletResponse response)
+ {
+
+ final String ticket = request.getParameter(this.artifactParameterName);
+
+ if (StringUtils.isNotEmpty(ticket))
+ {
+ String service = RequestUtils.absoluteUrl(request);
+ // solo se è l'ultimo carattere
+ if (service.lastIndexOf("/") == (service.length() - 1))
+ {
+ service = service.substring(0, service.lastIndexOf("/"));
+ }
+ CasCallBackHandler handler = new CasCallBackHandler(service, ticket, realm);
+
+ return authenticateCas(handler, getJaasChain());
+ }
+
+ return LoginResult.NOT_HANDLED;
+ }
+
+ protected LoginResult authenticateCas(CasCallBackHandler callbackHandler, String customLoginModule)
+ {
+ Subject subject;
+ try
+ {
+ LoginContext loginContext = new LoginContext(
+ StringUtils.defaultString(customLoginModule, "magnolia"),
+ callbackHandler);
+
+ loginContext.login();
+ subject = loginContext.getSubject();
+ User user = SecuritySupport.Factory.getInstance().getUserManager().getUser(subject);
+
+ if (user != null)
+ {
+ user.setSubject(subject);
+ }
+ else
+ {
+ log
+ .error("Unable to obtain a user from userManager, maybe the external user manager is not configured for the cas realm?");
+ }
+
+ return new LoginResult(LoginResult.STATUS_SUCCEEDED, user);
+ }
+ catch (LoginException e)
+ {
+ log.info("Can't login due to:", e);
+ return new LoginResult(LoginResult.STATUS_FAILED, e);
+ }
+ }
+
+ public class CasCallBackHandler implements CallbackHandler
+ {
+
+ private String service;
+
+ private String ticket;
+
+ private String realm;
+
+ public CasCallBackHandler(String service, String ticket, String realm)
+ {
+ this.service = service;
+ this.ticket = ticket;
+ this.realm = realm;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof TextInputCallback)
+ {
+ TextInputCallback text = (TextInputCallback) callbacks[i];
+ if ("ticket".equals(text.getPrompt()))
+ {
+ log.info(getTicket());
+ text.setText(getTicket());
+ }
+ else if ("service".equals(text.getPrompt()))
+ {
+ log.info(getService());
+ text.setText(getService());
+ }
+ else if ("casValidateUrl".equals(text.getPrompt()))
+ {
+ log.info(casValidateUrl);
+ text.setText(casValidateUrl);
+ }
+ }
+ else if (callbacks[i] instanceof RealmCallback)
+ {
+ log.info(this.realm);
+ ((RealmCallback) callbacks[i]).setRealm(this.realm);
+ }
+ else
+ {
+ throw (new UnsupportedCallbackException(callbacks[i], "Callback class not supported"));
+ }
+ }
+ }
+
+ public String getTicket()
+ {
+ return ticket;
+ }
+
+ public String getService()
+ {
+ return service;
+ }
+
+ public String getRealm()
+ {
+ return realm;
+ }
+
+ }
+}
Added: trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasMagnoliaUser.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasMagnoliaUser.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/CasMagnoliaUser.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,45 @@
+/**
+ * Copyright Openmind http://www.openmindonline.it
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package net.sourceforge.openutils.mgnlcas;
+
+import info.magnolia.cms.security.ExternalUser;
+
+import javax.security.auth.Subject;
+
+
+/**
+ * @author fgiust
+ * @version $Id: CasMagnoliaUser.java 2244 2008-08-11 19:31:53Z fgiust $
+ */
+public class CasMagnoliaUser extends ExternalUser
+{
+
+ /**
+ * Stable serialVersionUID.
+ */
+ private static final long serialVersionUID = 42L;
+
+ /**
+ * @param subject
+ */
+ protected CasMagnoliaUser(Subject subject)
+ {
+ super(subject);
+ }
+
+}
Added: trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/RequestUtils.java
===================================================================
--- trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/RequestUtils.java (rev 0)
+++ trunk/openutils-mgnlcas/src/main/java/net/sourceforge/openutils/mgnlcas/RequestUtils.java 2008-12-03 16:06:59 UTC (rev 931)
@@ -0,0 +1,55 @@
+/**
+ * Copyright Openmind http://www.openmindonline.it
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package net.sourceforge.openutils.mgnlcas;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * @author fgiust
+ * @version $Id: RequestUtils.java 4124 2008-09-22 14:56:46Z fgiust $
+ */
+public final class RequestUtils
+{
+
+ private RequestUtils()
+ {
+ // don't instantiate
+ }
+
+ public static String absoluteUrl(HttpServletRequest request)
+ {
+
+ String host = request.getServerName();
+ int port = request.getServerPort();
+ String scheme = request.getScheme();
+ StringBuilder sb = new StringBuilder();
+ sb.append(scheme);
+ sb.append("://");
+ sb.append(host);
+ if (port != 0 && port != 80 && port != 443)
+ {
+ sb.append(":");
+ sb.append(port);
+ }
+ sb.append(request.getRequestURI());
+
+ return sb.toString();
+
+ }
+}
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2008-12-03 15:14:24 UTC (rev 930)
+++ trunk/pom.xml 2008-12-03 16:06:59 UTC (rev 931)
@@ -242,6 +242,7 @@
<module>openutils-mgnlcontrols</module>
<module>openutils-spring-rmibernate</module>
<module>openutils-mgnlmessages</module>
+ <module>openutils-mgnlcas</module>
<!--
<module>openutils-elfunctions</module>
<module>openutils-mgnlmessages</module>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|