You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/03/13 19:12:57 UTC
[2/3] flex-blazeds git commit: - Cleaned up the structure of the
optional container modules
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/src/weblogic/flex/messaging/security/WeblogicLoginCommand.java
----------------------------------------------------------------------
diff --git a/opt/src/weblogic/flex/messaging/security/WeblogicLoginCommand.java b/opt/src/weblogic/flex/messaging/security/WeblogicLoginCommand.java
deleted file mode 100755
index 0f698c8..0000000
--- a/opt/src/weblogic/flex/messaging/security/WeblogicLoginCommand.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.security;
-
-import java.security.Principal;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import weblogic.security.SimpleCallbackHandler;
-import weblogic.security.SubjectUtils;
-import weblogic.security.services.Authentication;
-import weblogic.servlet.security.ServletAuthentication;
-import weblogic.security.Security;
-import flex.messaging.FlexContext;
-
-/**
- * Authenticates against WebLogic and if using an HttpServlet will store
- * the authenticated user in the request.
- */
-public class WeblogicLoginCommand extends AppServerLoginCommand implements PrincipalConverter
-{
- /** {@inheritDoc} */
- public Principal doAuthentication(String username, Object credentials)
- {
- Principal principal = null;
-
- String password = extractPassword(credentials);
-
- if (password != null)
- {
- // Test for the presence of a response here (rather than request) because NIO
- // endpoints require the alternate code path and they don't populate the response
- // in FlexContext.
- HttpServletResponse response = FlexContext.getHttpResponse();
- if (response != null)
- {
- HttpServletRequest request = FlexContext.getHttpRequest();
- int result = ServletAuthentication.FAILED_AUTHENTICATION;
- try
- {
- result = ServletAuthentication.login(username, password,
- request);
- }
- catch (LoginException e)
- {
- }
- catch (NoSuchMethodError noSuchMethodError)
- {
- //even though we're not supporting WebLogic 7 anymore...
- // Weblogic 7.0.4 didn't have login(), so try weak().
- result = ServletAuthentication.weak(username, password,
- request);
- }
-
- if (result != ServletAuthentication.FAILED_AUTHENTICATION)
- {
- // To authorize against the Groups defined via the WL console, we need
- // to have a SubjectPrincipal. Because we do not need a principal to authorize
- // against web.xml / weblogic.xml, always save the SubjectPrincipal
- principal = getSubjectPrincipal(username, password);
- }
- }
- else // Code path for NIO endpoints.
- {
- principal = getSubjectPrincipal(username, password);
- }
- }
-
- return principal;
- }
-
- /**
- * Get a SubjectPrincipal for the current user.
- * @return the generated SubjectPrincipal
- */
- private Principal getSubjectPrincipal(String username, String password)
- {
- Principal principal=null;
-
- SimpleCallbackHandler handler =
- new SimpleCallbackHandler(username, password);
- try
- {
- Subject subject = Authentication.login(handler);
- principal = new SubjectPrincipal(subject);
- }
- catch (LoginException e)
- {
- // let authentication fail if this fails
- }
-
- return principal;
- }
-
- /**
- * Authorize a user against the Groups defined in the WL console.
- * @param principal - Current user principal
- * @param roles - Set of roles that allow a succesfull authorization
- * @return true if the authorization were succesfull
- */
- private boolean doSubjectGroupAuthorization(Principal principal, List roles)
- {
- boolean authorized = false;
-
- Subject subject = null;
- if (principal instanceof SubjectPrincipal)
- {
- subject = ((SubjectPrincipal)principal).getSubject();
- }
- else
- {
- subject = Security.getCurrentSubject();
- }
- if (subject == null)
- {
- return false;
- }
- Iterator iter = roles.iterator();
- while (iter.hasNext())
- {
- String role = (String)iter.next();
- if (SubjectUtils.isUserInGroup(subject, role))
- {
- authorized = true;
- break;
- }
- }
-
- return authorized;
- }
-
- /** {@inheritDoc} */
- public boolean doAuthorization(Principal principal, List roles)
- {
- if (principal == null)
- return false; // Avoid NPEs.
-
- //NOTE: I believe that both HttpServletRequest.isUserInRole and
- //SubjectUtils.isUserInGroup returns if the user is in a Weblogic Group,
- //not necessarily the Weblogic role construct
-
- boolean authorized = false;
-
- // Test for the presence of a response here (rather than request) because NIO
- // endpoints require the alternate code path and they don't populate the response
- // in FlexContext.
- HttpServletResponse response = FlexContext.getHttpResponse();
- if (response != null)
- {
- HttpServletRequest request = FlexContext.getHttpRequest();
-
- // This will attempt to authorize the user against roles configured
- // in web.xml and weblogic.xml.
- authorized = doAuthorization(principal, roles, request);
-
- // We also want to support roles defined via the WL console
- // attempt this authorization here
- if (!authorized)
- {
- authorized = doSubjectGroupAuthorization(principal, roles);
- }
- }
- else // Code path for NIO endpoints.
- {
- authorized = doSubjectGroupAuthorization(principal, roles);
- }
-
- return authorized;
- }
-
- /** {@inheritDoc} */
- public boolean logout(Principal principal)
- {
- HttpServletResponse response = FlexContext.getHttpResponse();
- if (response != null)
- {
- // Destroy the Principal maintained by the app server.
- HttpServletRequest request = FlexContext.getHttpRequest();
- ServletAuthentication.logout(request);
- }
- // else, current non-servlet session will be automatically invalidated, destroying any active Principal.
-
- return true;
- }
-
- private class SubjectPrincipal implements Principal
- {
- private Subject subject;
-
- public SubjectPrincipal(Subject subject)
- {
- this.subject = subject;
- }
-
- public String getName()
- {
- return SubjectUtils.getUserPrincipal(subject).getName();
- }
-
- public Subject getSubject()
- {
- return subject;
- }
- }
-
- /** {@inheritDoc} */
- public Principal convertPrincipal(Principal principal)
- {
- if (principal instanceof SubjectPrincipal)
- {
- return principal;
- }
- else
- {
- // We need to do the converting
- Subject subject = Security.getCurrentSubject();
- return new SubjectPrincipal(subject);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/src/websphere/flex/management/WebSphereMBeanServerLocator.java
----------------------------------------------------------------------
diff --git a/opt/src/websphere/flex/management/WebSphereMBeanServerLocator.java b/opt/src/websphere/flex/management/WebSphereMBeanServerLocator.java
deleted file mode 100755
index 533f258..0000000
--- a/opt/src/websphere/flex/management/WebSphereMBeanServerLocator.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.management;
-
-import java.lang.reflect.Method;
-
-import javax.management.MBeanServer;
-
-import flex.messaging.log.Log;
-import flex.messaging.log.LogCategories;
-import flex.messaging.util.ClassUtil;
-
-/**
- * Custom MBeanServerLocator for use with WebSphere.
- * This class locates a MBean server instance via WebSphere's administration APIs.
- */
-public class WebSphereMBeanServerLocator implements MBeanServerLocator
-{
- //--------------------------------------------------------------------------
- //
- // Private Static Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * Localized error constant.
- */
- private static final int FAILED_TO_LOCATE_MBEAN_SERVER = 10427;
-
- //--------------------------------------------------------------------------
- //
- // Private Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * Reference to MBeanServer this locator found.
- */
- private MBeanServer server;
-
- //--------------------------------------------------------------------------
- //
- // Public Methods
- //
- //--------------------------------------------------------------------------
-
- /** {@inheritDoc} */
- public synchronized MBeanServer getMBeanServer()
- {
- if (server == null)
- {
- Class adminServiceClass = ClassUtil.createClass("com.ibm.websphere.management.AdminServiceFactory");
- try
- {
- Method getMBeanFactoryMethod = adminServiceClass.getMethod("getMBeanFactory", new Class[0]);
- Object mbeanFactory = getMBeanFactoryMethod.invoke(null, new Object[0]);
- Method getMBeanServerMethod = mbeanFactory.getClass().getMethod("getMBeanServer", new Class[0]);
- server = (MBeanServer)getMBeanServerMethod.invoke(mbeanFactory, new Object[0]);
- }
- catch (Exception e)
- {
- ManagementException me = new ManagementException();
- me.setMessage(FAILED_TO_LOCATE_MBEAN_SERVER, new Object[] {getClass().getName()});
- me.setRootCause(e);
- throw me;
- }
- if (Log.isDebug())
- Log.getLogger(LogCategories.MANAGEMENT_MBEANSERVER).debug("Using MBeanServer: " + server);
- }
- return server;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/src/websphere/flex/messaging/security/WebSphereLoginCommand.java
----------------------------------------------------------------------
diff --git a/opt/src/websphere/flex/messaging/security/WebSphereLoginCommand.java b/opt/src/websphere/flex/messaging/security/WebSphereLoginCommand.java
deleted file mode 100755
index cf02d26..0000000
--- a/opt/src/websphere/flex/messaging/security/WebSphereLoginCommand.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.security;
-
-import com.ibm.websphere.security.UserRegistry;
-import com.ibm.websphere.security.WSSecurityException;
-import com.ibm.websphere.security.auth.WSLoginFailedException;
-import com.ibm.ws.security.core.ContextManager;
-import com.ibm.ws.security.core.ContextManagerFactory;
-import flex.messaging.FlexContext;
-import flex.messaging.log.Log;
-import flex.messaging.log.LogCategories;
-
-import javax.security.auth.Subject;
-import javax.servlet.http.HttpServletRequest;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/*
- * To setup WebSphere 5.1 for authentication testing:
- *
- * 1) Install WebSphere 5.1
- * 2) Create two files, users.props and groups.props
- * (examples in resources/security/websphere) and place them in a directory
- * under your WS install.
- * 3) Using the Admin webapp:
- *
- * Security > Global Security
- * Check Enabled
- * Check Enforce Java 2 Security
- * Set Active User Registry to Custom
- * Click OK
- *
- * Either the admin app will tell you to setup your Custom or you should
- * go to Security > User Registries > Custom
- *
- * Server User ID should be one of your users from your users.props
- * Server User Password should be the matching password from users.props
- * Customer Registry Classname by default is com.ibm.websphere.security.FileRegistrySample
- * Go to Custom Properties
- * Add a prop "groupsFile" that points to your groups.props: e.g., c:/websphere5.1/AppServer/security/groups.props
- * Add a prop "usersFile" that points to your users.props: e.g., c:/websphere5.1/AppServer/security/users.props
- *
- * Click OK
- *
- * 4) Install your Flex EAR. You may need to go into its Session Settings
- * page and enable session security there?
- *
- * 5) In <websphere_dir>/java/jre/lib/security edit java.policy and add something
- * like the following:
- *
-grant codeBase "file:${was.install.root}/installedApps/MCHOTIN03/Flex2Ear.ear/secure.war/-" {
- permission java.security.AllPermission;
-};
-
- * This gives your webapp all the permissions it needs (possible that it could have
- * been narrowed down further).
- *
- * 6) Edit java.security in teh same directory to add the following entries
-security.provider.1=com.sun.net.ssl.internal.ssl.Provider
-security.provider.2=sun.security.provider.Sun
- * Update the entries below it so they're ordered right.
- * Copy jsse.jar and jcert.jar into java/jre/lib/ext (I think)
- * This will get the Flex Proxy to start correctly
- *
- * Restart your WebSphere, cross your fingers!!!
- *
- */
-
-/**
- * Authenticates against WebSphere but does not store the authenticated
- * user in the HttpServletRequest for http attempts due to the container
- * not providing a mechanism for access.
- */
-public class WebSphereLoginCommand extends AppServerLoginCommand implements PrincipalConverter
-{
-
- /** {@inheritDoc} */
- public Principal doAuthentication(String username, Object credentials)
- {
- Principal principal = null;
- try
- {
- String password = extractPassword(credentials);
-
- if (password != null)
- {
- ContextManager contextManager = ContextManagerFactory.getInstance();
-
- Subject subject =
- contextManager.login(contextManager.getDefaultRealm(),
- username, password);
-
- if (subject != null)
- {
- //setting the caller subject really doesn't apply for long
- //it appears to be removed later as each call to
- //ContextManagerFactory.getInstance()
- //returns a new instance and we cannot get the real context
- //and assign values that will be re-used.
- //this also means that the HttpServletRequest will not have the
- //information that we've assigned, hence we store this contextManager
- //in the Principal for later use
-
- contextManager.setCallerSubject(subject);
- principal = new WSLCPrincipal(username, contextManager, subject);
- }
- }
- }
- catch (WSLoginFailedException wsLoginFailedException)
- {
- if (Log.isDebug())
- {
- Log.getLogger(LogCategories.SECURITY).debug("WebSphereLoginCommand#doAuthentication() failed: " + wsLoginFailedException.toString(), wsLoginFailedException);
- }
- }
- catch (WSSecurityException wsSecurityException)
- {
- if (Log.isDebug())
- {
- Log.getLogger(LogCategories.SECURITY).debug("WebSphereLoginCommand#doAuthentication() failed: " + wsSecurityException.toString(), wsSecurityException);
- }
- }
-
- if (Log.isDebug() && principal != null)
- {
- Log.getLogger(LogCategories.SECURITY).debug("WebSphereLoginCommand#doAuthentication(). Principal: " + principal + ", Principal class: " + principal.getClass().getName()
- + ", Principal identity: " + System.identityHashCode(principal));
- }
-
- return principal;
- }
-
- /** {@inheritDoc} */
- public boolean doAuthorization(Principal principal, List roles)
- {
- //unfortunately we cannot seem to get the user stored
- //in the context so the request will never have the information
- //that we've assigned, therefore we have to do this
- //every time
-
- if (principal == null)
- return false;
-
- if (Log.isDebug())
- Log.getLogger(LogCategories.SECURITY).debug("WebSphereLoginCommand#doAuthorization(). Principal: " + principal + ", Principal class: " + principal.getClass().getName()
- + ", Principal identity: " + System.identityHashCode(principal));
-
- if (principal instanceof WSLCPrincipal) // This code path is hit if this login command handled authentication.
- {
- ContextManager contextManager = ((WSLCPrincipal)principal).getContextManager();
- UserRegistry registry = contextManager.getRegistry(contextManager.getDefaultRealm());
-
- try
- {
- List groups = new ArrayList(registry.getGroupsForUser(principal.getName()));
-
- groups.retainAll(roles);
-
- // if authorization succeeds, set the user's Subject on this invocation context
- // so that the rest of the Thread is executed in the context of the appropriate Subject
- if (groups.size() > 0)
- ContextManagerFactory.getInstance().setCallerSubject(((WSLCPrincipal)principal).getSubject());
-
- return groups.size() > 0;
- }
- catch (Exception e)
- {
- }
- }
- else // This code path is hit if this login command didn't handle authentication.
- {
- // The Principal was not null, meaning we have a WAS Principal in the current HttpServletRequest.
- // Use that for the authorization check.
- HttpServletRequest request = FlexContext.getHttpRequest();
- for (Iterator iter = roles.iterator(); iter.hasNext(); )
- {
- if (request.isUserInRole((String)iter.next()))
- return true;
- }
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- public boolean logout(Principal principal)
- {
- //as long as credentials are nulled since we can't store
- //the authenticated user there's nothing to do
- return true;
- }
-
- private class WSLCPrincipal implements Principal
- {
- private String username;
- private ContextManager contextManager;
- private Subject subject;
-
- public WSLCPrincipal(String username, ContextManager contextManager, Subject subject)
- {
- this.username = username;
- this.contextManager = contextManager;
- this.subject = subject;
- }
-
- public String getName()
- {
- return username;
- }
-
- public ContextManager getContextManager()
- {
- return contextManager;
- }
-
- public Subject getSubject()
- {
- return subject;
- }
- }
-
- /** {@inheritDoc} */
- public Principal convertPrincipal(Principal principal)
- {
- if (principal instanceof WSLCPrincipal)
- {
- // We are good
- return principal;
- }
- else
- {
- // we need the converting
-
- ContextManager contextManager = ContextManagerFactory.getInstance();
-
- Subject subject = null;
- try
- {
- subject = contextManager.getCallerSubject();
- }
- catch (WSSecurityException e)
- {
-
- }
-
- if (subject != null)
- {
- return new WSLCPrincipal(principal.getName(), contextManager, subject);
- }
- else
- // Just return the old one
- return principal;
-
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/src/websphere/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
----------------------------------------------------------------------
diff --git a/opt/src/websphere/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java b/opt/src/websphere/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
deleted file mode 100755
index a35c0e9..0000000
--- a/opt/src/websphere/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.util.concurrent;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import com.ibm.websphere.asynchbeans.Work;
-import com.ibm.websphere.asynchbeans.WorkEvent;
-import com.ibm.websphere.asynchbeans.WorkException;
-import com.ibm.websphere.asynchbeans.WorkListener;
-import com.ibm.websphere.asynchbeans.WorkManager;
-
-import flex.messaging.config.ConfigurationException;
-import flex.messaging.log.Log;
-import flex.messaging.log.LogCategories;
-
-/**
- * Implements {@link Executor} by delegating command execution to a WAS asynchbeans <code>WorkManager</code>.
- * For more information on the asynchbeans API, refer to the WAS Javadoc for
- * <a href="http://publib.boulder.ibm.com/infocenter/wasinfo/v5r0/index.jsp?topic=/com.ibm.wasee.doc/info/ee/javadoc/ee/com/ibm/websphere/asynchbeans/WorkManager.html">WorkManager</a>.
- *
- *
- */
-public class AsynchBeansWorkManagerExecutor implements Executor
-{
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructs an <code>AsynchBeansWorkManagerExecutor</code> that will delegate command execution
- * to the specified <code>WorkManager</code> instance that is registered in JNDI.
- *
- * @param workManagerJNDIName The JNDI resource ref name for the <code>WorkManager</code>.
- * @see com.ibm.websphere.asynchbeans.WorkManager
- */
- public AsynchBeansWorkManagerExecutor(String workManagerJNDIName)
- {
- try
- {
- InitialContext ic = new InitialContext();
- workManager = (WorkManager)ic.lookup(workManagerJNDIName);
- }
- catch(NamingException ne)
- {
- ConfigurationException ce = new ConfigurationException();
- ce.setMessage(13600, new Object[] {workManagerJNDIName});
- ce.setRootCause(ne);
- throw ce;
- }
-
- workListener = new WorkListener() {
- public void workAccepted(WorkEvent event)
- {
- /* No-op */
- }
- public void workCompleted(WorkEvent event)
- {
- // This only needs to be handled if execution of the Runnable failed.
- WorkException e = event.getException();
- if (e != null)
- {
- if (Log.isDebug())
- Log.getLogger(LogCategories.EXECUTOR).error("AsynchBeansWorkManager's WorkListener.workCompleted() callback invoked for failed execution.", e);
-
- handleFailedExecution(((WorkCommandWrapper)event.getWork()).command, e);
- }
- }
- public void workRejected(WorkEvent event)
- {
- WorkException e = event.getException();
- if (Log.isDebug())
- Log.getLogger(LogCategories.EXECUTOR).error("AsynchBeansWorkManager's WorkListener.workRejected() callback invoked. WorkException? " + e);
-
- handleFailedExecution(((WorkCommandWrapper)event.getWork()).command, e);
- }
- public void workStarted(WorkEvent event)
- {
- /* No-op */
- }
- };
- }
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * Instance level lock for thread-safe state changes.
- */
- private final Object lock = new Object();
-
- /**
- * Reference to the WorkManager instance configured in WAS that this executor instance delegates to.
- */
- private final WorkManager workManager;
-
- /**
- * Listener that monitors scheduled work for errors and notifies the FailedExecutionHandler if one has been set.
- */
- private final WorkListener workListener;
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // failedExecutionHandler
- //----------------------------------
-
- private FailedExecutionHandler failedExecutionHandler;
-
- /** {@inheritDoc} */
- public FailedExecutionHandler getFailedExecutionHandler()
- {
- synchronized (lock)
- {
- return failedExecutionHandler;
- }
- }
-
- /** {@inheritDoc} */
- public void setFailedExecutionHandler(FailedExecutionHandler value)
- {
- synchronized (lock)
- {
- failedExecutionHandler = value;
- }
- }
-
- //--------------------------------------------------------------------------
- //
- // Public Methods
- //
- //--------------------------------------------------------------------------
-
- /** {@inheritDoc} */
- public void execute(Runnable command)
- {
- try
- {
- // Register our listener to monitor each scheduled work, and set the start timeout for the work to indefinite (no queue timeout).
- workManager.startWork(new WorkCommandWrapper(command), WorkManager.INDEFINITE, workListener);
- }
- catch (WorkException e)
- {
- handleFailedExecution(command, e);
- }
- }
-
- //--------------------------------------------------------------------------
- //
- // Private Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * Handles command execution problems by notifying the FailedExecutionHandler if one has been set
- * and otherwise logging the failure.
- *
- * @param command The command that failed to execute successfully.
- * @param e The exception generated by the failed command.
- */
- private void handleFailedExecution(Runnable command, Exception e)
- {
- FailedExecutionHandler handler = getFailedExecutionHandler();
- if (handler != null)
- {
- handler.failedExecution(command, this, e);
- }
- else if (Log.isError())
- {
- Log.getLogger(LogCategories.EXECUTOR).error("AsynchBeansWorkManager hit an Exception but no FailedExecutionHandler is registered to handle the error.", e);
- }
- }
-
- //--------------------------------------------------------------------------
- //
- // Inner Classes
- //
- //--------------------------------------------------------------------------
-
- /**
- * Helper class that wraps Runnable commands in the WAS Work interface.
- */
- class WorkCommandWrapper implements Work
- {
- public WorkCommandWrapper(Runnable command)
- {
- this.command = command;
- }
-
- private final Runnable command;
-
- public void run()
- {
- command.run();
- }
-
- /**
- * This is invoked by WAS when the server is shutting down to signal long-running daemon threads spawned by the WorkManager
- * to exit from their run() method. Our works are all short lived so this is a no-op; in this case WAS will force any
- * works that are executing at server shutdown to terminate.
- */
- public void release()
- {
- // No-op.
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/pom.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/pom.xml b/opt/tomcat/pom.xml
new file mode 100644
index 0000000..78b33d6
--- /dev/null
+++ b/opt/tomcat/pom.xml
@@ -0,0 +1,38 @@
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt</artifactId>
+ <version>4.7.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flex-messaging-opt-tomcat</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>tomcat-base</module>
+ <module>tomcat-4</module>
+ <module>tomcat-6</module>
+ <module>tomcat-7</module>
+ </modules>
+
+</project>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-4/pom.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-4/pom.xml b/opt/tomcat/tomcat-4/pom.xml
new file mode 100644
index 0000000..df46834
--- /dev/null
+++ b/opt/tomcat/tomcat-4/pom.xml
@@ -0,0 +1,46 @@
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat</artifactId>
+ <version>4.7.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flex-messaging-opt-tomcat-4</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>tomcat</groupId>
+ <artifactId>catalina</artifactId>
+ <version>4.0.6</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-4/src/main/java/flex/messaging/security/TomcatValve4150.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-4/src/main/java/flex/messaging/security/TomcatValve4150.java b/opt/tomcat/tomcat-4/src/main/java/flex/messaging/security/TomcatValve4150.java
new file mode 100755
index 0000000..182bce4
--- /dev/null
+++ b/opt/tomcat/tomcat-4/src/main/java/flex/messaging/security/TomcatValve4150.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.security;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.LogCategories;
+import flex.messaging.util.ExceptionUtil;
+
+import org.apache.catalina.valves.ValveBase;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Realm;
+import org.apache.catalina.Request;
+import org.apache.catalina.Response;
+import org.apache.catalina.ValveContext;
+import org.apache.catalina.Container;
+import org.apache.catalina.Session;
+import org.apache.catalina.HttpRequest;
+import org.apache.catalina.Manager;
+import org.apache.catalina.authenticator.Constants;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A Tomcat valve for allowing programmatic login. This valve saves the container, something not available
+ * normally to a servlet, and allows login to the current realm. The pieces interacting with Tomcat are taken from
+ * org.apache.catalina.authenticator.AuthenticatorBase. It would be nice if we could just extend that class or
+ * call some of its methods, but things aren't set up in that class in such a way that this is possible
+ *
+ * FIXME: doesn't support Tomcat's SingleSignOn idea. This is a way to write custom valves that associate
+ * the principal to different web apps or locations. See AuthenticatorBase for details
+ *
+ * JAR NOTE: this class is not in flex-messaging.jar but rather flex-tomcat-server.jar
+ *
+ *
+ */
+public class TomcatValve4150 extends ValveBase implements Lifecycle
+{
+
+ private static String AMF_MATCH = "/amfgateway";
+ private static String GATEWAY_MATCH = "/flashgateway";
+ private static String MESSAGEBROKER_MATCH = "/messagebroker";
+ private static String CUSTOM_MATCH = System.getProperty("flex.tomcatValveMatch");
+
+ public void addLifecycleListener(LifecycleListener listener)
+ {
+ // ignore
+ }
+
+ public LifecycleListener[] findLifecycleListeners()
+ {
+ // ignore
+ return null;
+ }
+
+ public void removeLifecycleListener(LifecycleListener listener)
+ {
+ // ignore
+ }
+
+ public void start() throws LifecycleException
+ {
+
+ // RTMP may not go through invoke so we need to put at least one TomcatLoginImpl in the holder.
+ TomcatLogin login = new TomcatLoginImpl(getContainer(), null);
+ TomcatLoginHolder.setLogin(login);
+ // To avoid the thread processes the nio based endpoints does not match the thread start the valve (which is quite possible in Tomcat)
+ // We set the singleton
+ TomcatLoginHolder.setNioBasedLogin(login);
+ }
+
+ public void stop() throws LifecycleException
+ {
+ // ignore
+ }
+
+ public void invoke(Request request, Response response, ValveContext context)
+ throws IOException, ServletException
+ {
+ ServletRequest servRequest = request.getRequest();
+ if (servRequest instanceof HttpServletRequest)
+ {
+ // we only set the TomcatLoginImpl for gateway paths
+
+ HttpServletRequest hrequest = ((HttpServletRequest)servRequest);
+ String path = hrequest.getServletPath();
+ boolean match = false;
+ if (path == null)
+ {
+ // We need to use a slighly-weaker uri match for 4.1
+ String uri = hrequest.getRequestURI();
+ match = (uri != null &&
+ (uri.indexOf(MESSAGEBROKER_MATCH) != -1 ||
+ uri.indexOf(AMF_MATCH) != -1 ||
+ uri.indexOf(GATEWAY_MATCH) != -1 ||
+ (CUSTOM_MATCH != null && uri.indexOf(CUSTOM_MATCH) != -1)));
+ }
+ else
+ {
+ match = (path.startsWith(MESSAGEBROKER_MATCH) ||
+ path.startsWith(AMF_MATCH) ||
+ path.startsWith(GATEWAY_MATCH) ||
+ (CUSTOM_MATCH != null && path.startsWith(CUSTOM_MATCH)));
+ }
+
+ if (match)
+ {
+ HttpRequest httpRequest = (HttpRequest)request;
+ TomcatLoginHolder.setLogin(new TomcatLoginImpl(getContainer(), httpRequest));
+
+ // copy over user princicpal and auth type values, just like in AuthenticatorBase.invoke()
+ Principal principal = hrequest.getUserPrincipal();
+ if (principal == null)
+ {
+ Session session = getSession(httpRequest, false);
+ if (session != null)
+ {
+ principal = session.getPrincipal();
+ if (principal != null)
+ {
+ httpRequest.setAuthType(session.getAuthType());
+ httpRequest.setUserPrincipal(principal);
+ }
+ }
+ }
+ }
+ }
+ context.invokeNext(request, response);
+ }
+
+ // from AuthenticatorBase.getSession()
+ static Session getSession(HttpRequest request, boolean create)
+ {
+
+ HttpServletRequest hreq =
+ (HttpServletRequest) request.getRequest();
+
+ HttpSession hses = hreq.getSession(create);
+
+ if (hses == null)
+ return (null);
+ Manager manager = request.getContext().getManager();
+
+ if (manager == null)
+ return (null);
+ else
+ {
+ try
+ {
+ return (manager.findSession(hses.getId()));
+ } catch (IOException e)
+ {
+ Log.getLogger(LogCategories.SECURITY).error("Error in TomcatValve getting session id " + hses.getId() + " : " + ExceptionUtil.toString(e));
+ return (null);
+ }
+ }
+ }
+
+ class TomcatLoginImpl implements TomcatLogin
+ {
+ private Container container;
+ private HttpRequest request;
+
+ TomcatLoginImpl(Container container, HttpRequest request)
+ {
+ this.container = container;
+ this.request = request;
+ }
+
+ // authenticate the user and associate with the current session. This is taken
+ // from AuthenticatorBase.register()
+ public Principal login(String username, String password, HttpServletRequest servletRequest)
+ {
+ Realm realm = container.getRealm();
+ if (realm == null)
+ return null;
+ Principal principal = realm.authenticate(username, password);
+
+ if (principal != null)
+ {
+ if (this.request != null && this.request.getRequest() == servletRequest)
+ {
+ request.setAuthType("flexmessaging"); //was "flashgateway"
+ request.setUserPrincipal(principal);
+
+ Session session = getSession(request, true);
+
+ // Cache the authentication information in our session, if any
+ if (session != null)
+ {
+ session.setAuthType("flexmessaging"); //was "flashgateway"
+ 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);
+ }
+ }
+ }
+
+ return principal;
+ }
+
+ public boolean authorize(Principal principal, List roles)
+ {
+
+ Realm realm = container.getRealm();
+ Iterator iter = roles.iterator();
+ while (iter.hasNext())
+ {
+ String role = (String)iter.next();
+ if (realm.hasRole(principal, role))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean logout(HttpServletRequest request)
+ {
+ if (this.request != null && this.request.getRequest() == request)
+ {
+ Session session = getSession(this.request, false);
+ if (session != null)
+ {
+ session.setPrincipal(null);
+ session.setAuthType(null);
+ session.removeNote(Constants.SESS_USERNAME_NOTE);
+ session.removeNote(Constants.SESS_PASSWORD_NOTE);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public Principal convertPrincipal(Principal principal)
+ {
+ return principal;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-6/pom.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-6/pom.xml b/opt/tomcat/tomcat-6/pom.xml
new file mode 100644
index 0000000..c614e6a
--- /dev/null
+++ b/opt/tomcat/tomcat-6/pom.xml
@@ -0,0 +1,50 @@
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat</artifactId>
+ <version>4.7.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flex-messaging-opt-tomcat-6</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>6.0.26</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>catalina</artifactId>
+ <version>6.0.26</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-6/src/main/java/flex/messaging/security/TomcatValve.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-6/src/main/java/flex/messaging/security/TomcatValve.java b/opt/tomcat/tomcat-6/src/main/java/flex/messaging/security/TomcatValve.java
new file mode 100755
index 0000000..02a5b31
--- /dev/null
+++ b/opt/tomcat/tomcat-6/src/main/java/flex/messaging/security/TomcatValve.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.security;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.LogCategories;
+import flex.messaging.util.ExceptionUtil;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Realm;
+import org.apache.catalina.Session;
+import org.apache.catalina.Valve;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+
+/**
+ *
+ * A Tomcat valve for allowing programmatic login. This valve saves the container,
+ * something not available normally to a servlet, and allows login to the current realm.
+ * The pieces interacting with Tomcat are taken from org.apache.catalina.authenticator.AuthenticatorBase.
+ * It would be nice if we could just extend that class or call some of its methods,
+ * but things aren't set up in that class in such a way that this is possible
+ *
+ * FIXME: Doesn't support Tomcat's SingleSignOn which is a way to write custom valves that associate
+ * the principal to different web apps or locations. See AuthenticatorBase for details
+ */
+public class TomcatValve extends ValveBase implements Lifecycle
+{
+ private static final String AUTH_TYPE = "flexmessaging"; // was "flashgateway"
+ private static final String AMF_MATCH = "/amfgateway";
+ private static final String GATEWAY_MATCH = "/flashgateway";
+ private static final String MESSAGEBROKER_MATCH = "/messagebroker";
+ private static String CUSTOM_MATCH = System.getProperty("flex.tomcatValveMatch");
+
+ public void invoke(Request request, Response response) throws IOException, ServletException
+ {
+ invokeServletRequest(request);
+
+ Valve next = getNext();
+ if (next != null)
+ next.invoke(request, response);
+ }
+
+ private void invokeServletRequest(Request request)
+ {
+ ServletRequest servRequest = request.getRequest();
+ if (!(servRequest instanceof HttpServletRequest))
+ return;
+
+ // We only set the TomcatLoginImpl for gateway paths
+ HttpServletRequest hrequest = (HttpServletRequest)servRequest;
+ boolean match = checkIfPathMatches(hrequest.getServletPath(), hrequest.getRequestURI());
+ if (match)
+ handleMatch(request, hrequest.getUserPrincipal());
+ }
+
+ private void handleMatch(Request request, Principal principal)
+ {
+ TomcatLoginHolder.setLogin(new TomcatLoginImpl(getContainer(), request));
+
+ // Copy over user principal and auth type values, just like in AuthenticatorBase.invoke()
+ if (principal != null)
+ return;
+
+ Session session = getSession(request, false);
+ if (session == null)
+ return;
+
+ principal = session.getPrincipal();
+ if (principal != null)
+ {
+ request.setAuthType(session.getAuthType());
+ request.setUserPrincipal(principal);
+ }
+ }
+
+ private boolean checkIfPathMatches(String path, String uri)
+ {
+ if (path == null)
+ {
+ // We need to use a slighly-weaker uri match for 4.1
+ return (uri != null &&
+ (uri.indexOf(MESSAGEBROKER_MATCH) != -1 ||
+ uri.indexOf(AMF_MATCH) != -1 ||
+ uri.indexOf(GATEWAY_MATCH) != -1 ||
+ (CUSTOM_MATCH != null && uri.indexOf(CUSTOM_MATCH) != -1)));
+ }
+ else
+ {
+ return (path.startsWith(MESSAGEBROKER_MATCH) ||
+ path.startsWith(AMF_MATCH) ||
+ path.startsWith(GATEWAY_MATCH) ||
+ (CUSTOM_MATCH != null && path.startsWith(CUSTOM_MATCH)));
+ }
+ }
+
+ public void addLifecycleListener(LifecycleListener listener)
+ {
+ // No-op.
+ }
+
+ public LifecycleListener[] findLifecycleListeners()
+ {
+ return null;
+ }
+
+ public void removeLifecycleListener(LifecycleListener listener)
+ {
+ // No-op.
+ }
+
+ public void start() throws LifecycleException
+ {
+ // RTMP may not go through invoke so we need to put at least one TomcatLoginImpl in the holder.
+ TomcatLogin login = new TomcatLoginImpl(getContainer(), null);
+ TomcatLoginHolder.setLogin(login);
+ // To avoid the thread processes the nio based endpoints does not match the thread start the valve (which is quite possible in Tomcat)
+ // We set the singleton
+ TomcatLoginHolder.setNioBasedLogin(login);
+ }
+
+ public void stop() throws LifecycleException
+ {
+ // No-op.
+ }
+
+ // from AuthenticatorBase.getSession()
+ static Session getSession(Request request, boolean create)
+ {
+
+ HttpServletRequest hreq = (HttpServletRequest)request.getRequest();
+ HttpSession hses = hreq.getSession(create);
+
+ if (hses == null)
+ return null;
+
+ Manager manager = request.getContext().getManager();
+ if (manager == null)
+ return null;
+
+ try
+ {
+ return manager.findSession(hses.getId());
+ }
+ catch (IOException e)
+ {
+ Log.getLogger(LogCategories.SECURITY).error("Error in TomcatValve getting session id " + hses.getId() + " : " + ExceptionUtil.toString(e));
+ return null;
+ }
+ }
+
+ class TomcatLoginImpl implements TomcatLogin
+ {
+ private Container container;
+ private Request request;
+
+ TomcatLoginImpl(Container container, Request request)
+ {
+ this.container = container;
+ this.request = request;
+ }
+
+ // Authenticate the user and associate with the current session.
+ // This is taken from AuthenticatorBase.register()
+ public Principal login(String username, String password, HttpServletRequest servletRequest)
+ {
+ Realm realm = container.getRealm();
+ if (realm == null)
+ return null;
+
+ Principal principal = realm.authenticate(username, password);
+ if (principal == null)
+ return null;
+
+ if (servletRequestMatches(servletRequest))
+ {
+ request.setAuthType(AUTH_TYPE);
+ request.setUserPrincipal(principal);
+
+ Session session = getSession(request, true);
+
+ // Cache the authentication information in our session.
+ if (session != null)
+ {
+ session.setAuthType(AUTH_TYPE);
+ 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);
+ }
+ }
+
+ return principal;
+ }
+
+ public boolean authorize(Principal principal, List roles)
+ {
+ Realm realm = container.getRealm();
+ Iterator iter = roles.iterator();
+ while (iter.hasNext())
+ {
+ String role = (String)iter.next();
+ if (realm.hasRole(principal, role))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean logout(HttpServletRequest servletRequest)
+ {
+ if (servletRequestMatches(servletRequest))
+ {
+ Session session = getSession(request, false);
+ if (session != null)
+ {
+ session.setPrincipal(null);
+ session.setAuthType(null);
+ session.removeNote(Constants.SESS_USERNAME_NOTE);
+ session.removeNote(Constants.SESS_PASSWORD_NOTE);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private boolean servletRequestMatches(HttpServletRequest servletRequest)
+ {
+ return request != null && request.getRequest() == servletRequest;
+ }
+
+ /** {@inheritDoc} */
+ public Principal convertPrincipal(Principal principal)
+ {
+ return principal;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-7/pom.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-7/pom.xml b/opt/tomcat/tomcat-7/pom.xml
new file mode 100644
index 0000000..82d0ab8
--- /dev/null
+++ b/opt/tomcat/tomcat-7/pom.xml
@@ -0,0 +1,45 @@
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat</artifactId>
+ <version>4.7.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flex-messaging-opt-tomcat-7</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-catalina</artifactId>
+ <version>7.0.8</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-7/src/main/java/flex/messaging/security/Tomcat7Valve.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-7/src/main/java/flex/messaging/security/Tomcat7Valve.java b/opt/tomcat/tomcat-7/src/main/java/flex/messaging/security/Tomcat7Valve.java
new file mode 100755
index 0000000..19eeec8
--- /dev/null
+++ b/opt/tomcat/tomcat-7/src/main/java/flex/messaging/security/Tomcat7Valve.java
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.security;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.LogCategories;
+import flex.messaging.util.ExceptionUtil;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletConfig;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Realm;
+import org.apache.catalina.Role;
+import org.apache.catalina.Session;
+import org.apache.catalina.Valve;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.catalina.users.AbstractUser;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.catalina .Wrapper;
+
+/**
+ *
+ * A Tomcat valve for allowing programmatic login. This valve saves the container,
+ * something not available normally to a servlet, and allows login to the current realm.
+ * The pieces interacting with Tomcat are taken from org.apache.catalina.authenticator.AuthenticatorBase.
+ * It would be nice if we could just extend that class or call some of its methods,
+ * but things aren't set up in that class in such a way that this is possible
+ *
+ * FIXME: Doesn't support Tomcat's SingleSignOn which is a way to write custom valves that associate
+ * the principal to different web apps or locations. See AuthenticatorBase for details
+ */
+public class Tomcat7Valve extends ValveBase implements Lifecycle
+{
+ private static final String AUTH_TYPE = "flexmessaging"; // was "flashgateway"
+ private static final String AMF_MATCH = "/amfgateway";
+ private static final String GATEWAY_MATCH = "/flashgateway";
+ private static final String MESSAGEBROKER_MATCH = "/messagebroker";
+ private static String CUSTOM_MATCH = System.getProperty("flex.tomcatValveMatch");
+
+ public Tomcat7Valve()
+ {
+ super();
+
+ // RTMP may not go through invoke so we need to put at least one TomcatLoginImpl in the holder.
+ TomcatLogin login = new TomcatLoginImpl(this, null);
+ TomcatLoginHolder.setLogin(login);
+ // To avoid the thread processes the nio based endpoints does not match the thread start the valve (which is quite possible in Tomcat)
+ // We set the singleton
+ TomcatLoginHolder.setNioBasedLogin(login);
+ }
+
+ public void invoke(Request request, Response response) throws IOException, ServletException
+ {
+ invokeServletRequest(request);
+
+ Valve next = getNext();
+ if (next != null)
+ next.invoke(request, response);
+ }
+
+ private void invokeServletRequest(Request request)
+ {
+ ServletRequest servRequest = request.getRequest();
+ if (!(servRequest instanceof HttpServletRequest))
+ return;
+
+ // We only set the TomcatLoginImpl for gateway paths
+ HttpServletRequest hrequest = (HttpServletRequest)servRequest;
+ boolean match = checkIfPathMatches(hrequest.getServletPath(), hrequest.getRequestURI());
+ if (match)
+ handleMatch(request, hrequest.getUserPrincipal());
+ }
+
+ private void handleMatch(Request request, Principal principal)
+ {
+ TomcatLoginHolder.setLogin(new TomcatLoginImpl(this, request));
+
+ // Copy over user principal and auth type values, just like in AuthenticatorBase.invoke()
+ if (principal != null)
+ return;
+
+ Session session = getSession(request, false);
+ if (session == null)
+ return;
+
+ principal = session.getPrincipal();
+ if (principal != null)
+ {
+ request.setAuthType(session.getAuthType());
+ request.setUserPrincipal(principal);
+ }
+ }
+
+ private boolean checkIfPathMatches(String path, String uri)
+ {
+ if (path == null)
+ {
+ // We need to use a slighly-weaker uri match for 4.1
+ return (uri != null &&
+ (uri.indexOf(MESSAGEBROKER_MATCH) != -1 ||
+ uri.indexOf(AMF_MATCH) != -1 ||
+ uri.indexOf(GATEWAY_MATCH) != -1 ||
+ (CUSTOM_MATCH != null && uri.indexOf(CUSTOM_MATCH) != -1)));
+ }
+ else
+ {
+ return (path.startsWith(MESSAGEBROKER_MATCH) ||
+ path.startsWith(AMF_MATCH) ||
+ path.startsWith(GATEWAY_MATCH) ||
+ (CUSTOM_MATCH != null && path.startsWith(CUSTOM_MATCH)));
+ }
+ }
+
+ public void addLifecycleListener(LifecycleListener listener)
+ {
+ // No-op.
+ }
+
+ public LifecycleListener[] findLifecycleListeners()
+ {
+ return null;
+ }
+
+ public void removeLifecycleListener(LifecycleListener listener)
+ {
+ // No-op.
+ }
+
+ // from AuthenticatorBase.getSession()
+ static Session getSession(Request request, boolean create)
+ {
+
+ HttpServletRequest hreq = (HttpServletRequest)request.getRequest();
+ HttpSession hses = hreq.getSession(create);
+
+ if (hses == null)
+ return null;
+
+ Manager manager = request.getContext().getManager();
+ if (manager == null)
+ return null;
+
+ try
+ {
+ return manager.findSession(hses.getId());
+ }
+ catch (IOException e)
+ {
+ Log.getLogger(LogCategories.SECURITY).error("Error in TomcatValve getting session id " + hses.getId() + " : " + ExceptionUtil.toString(e));
+ return null;
+ }
+ }
+
+ class TomcatLoginImpl implements TomcatLogin
+ {
+ private ValveBase valve;
+ private Request request;
+
+ TomcatLoginImpl(ValveBase valve, Request request)
+ {
+ this.valve = valve;
+ this.request = request;
+ }
+
+ // Authenticate the user and associate with the current session.
+ // This is taken from AuthenticatorBase.register()
+ public Principal login(String username, String password, HttpServletRequest servletRequest)
+ {
+ Realm realm = valve.getContainer().getRealm();
+ if (realm == null)
+ return null;
+
+ Principal principal = realm.authenticate(username, password);
+ if (principal == null)
+ return null;
+
+ if (servletRequestMatches(servletRequest))
+ {
+ request.setAuthType(AUTH_TYPE);
+ request.setUserPrincipal(principal);
+
+ Session session = getSession(request, true);
+
+ // Cache the authentication information in our session.
+ if (session != null)
+ {
+ session.setAuthType(AUTH_TYPE);
+ 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);
+ }
+ }
+
+ return principal;
+ }
+
+ public boolean authorize(Principal principal, List roles)
+ {
+ Realm realm = valve.getContainer().getRealm();
+ Iterator iter = roles.iterator();
+ while (iter.hasNext())
+ {
+ String role = (String)iter.next();
+ // For Tomcat 7, we need to get the wrapper from the request to support role mapping in the web.xml.
+ // This is only supported for servlet endpoints. For NIO endpoints, the wrapper will be null.
+ Wrapper wrapper = null;
+ if (request != null)
+ {
+ // in the servlet case get the wrapper
+ wrapper = request.getWrapper();
+ }
+ // for nio the wrapper will be null
+ if (realm.hasRole(wrapper, principal, role))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean logout(HttpServletRequest servletRequest)
+ {
+ if (servletRequestMatches(servletRequest))
+ {
+ Session session = getSession(request, false);
+ if (session != null)
+ {
+ session.setPrincipal(null);
+ session.setAuthType(null);
+ session.removeNote(Constants.SESS_USERNAME_NOTE);
+ session.removeNote(Constants.SESS_PASSWORD_NOTE);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private boolean servletRequestMatches(HttpServletRequest servletRequest)
+ {
+ return request != null && request.getRequest() == servletRequest;
+ }
+ /** {@inheritDoc} */
+ public Principal convertPrincipal(Principal principal)
+ {
+ if (principal instanceof GenericPrincipal)
+ {
+ return principal;
+ }
+ else
+ {
+ // We need to do the converting
+ if (principal instanceof AbstractUser)
+ {
+ AbstractUser abstractUser = (AbstractUser) principal;
+ List<String> roles = new ArrayList<String> ();
+ Iterator roleIterator = abstractUser.getRoles();
+ while (roleIterator.hasNext())
+ {
+ Role role = (Role) roleIterator.next();
+ roles.add(role.getName());
+ }
+ String userName = abstractUser.getUsername();
+ String password = abstractUser.getPassword();
+ return new GenericPrincipal(userName, password, roles);
+
+ }
+ else
+ {
+ // no
+ return principal;
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-7/src/main/resources/flex/messaging/security/tomcat-descriptor.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-7/src/main/resources/flex/messaging/security/tomcat-descriptor.xml b/opt/tomcat/tomcat-7/src/main/resources/flex/messaging/security/tomcat-descriptor.xml
new file mode 100755
index 0000000..8aef29f
--- /dev/null
+++ b/opt/tomcat/tomcat-7/src/main/resources/flex/messaging/security/tomcat-descriptor.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!DOCTYPE mbeans-descriptors PUBLIC
+ "-//Apache Software Foundation//DTD Model MBeans Configuration File"
+ "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">
+
+<!--
+ Descriptions of JMX MBeans for Catalina
+ -->
+
+<mbeans-descriptors>
+
+ <mbean name="TomcatValve4150"
+ className="org.apache.catalina.mbeans.ClassNameMBean"
+ description="Valve that allows Flex to programmatically log in"
+ domain="Catalina"
+ group="Valve"
+ type="flex.messaging.security.TomcatValve4150">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="debug"
+ description="The debugging detail level for this component"
+ type="int"/>
+
+
+ </mbean>
+
+ <mbean name="TomcatValve"
+ className="org.apache.catalina.mbeans.ClassNameMBean"
+ description="Valve that allows Flex to programmatically log in"
+ domain="Catalina"
+ group="Valve"
+ type="flex.messaging.security.TomcatValve">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="debug"
+ description="The debugging detail level for this component"
+ type="int"/>
+
+
+ </mbean>
+</mbeans-descriptors>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-base/pom.xml
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-base/pom.xml b/opt/tomcat/tomcat-base/pom.xml
new file mode 100644
index 0000000..96b6337
--- /dev/null
+++ b/opt/tomcat/tomcat-base/pom.xml
@@ -0,0 +1,30 @@
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.flex.blazeds</groupId>
+ <artifactId>flex-messaging-opt-tomcat</artifactId>
+ <version>4.7.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flex-messaging-opt-tomcat-base</artifactId>
+
+</project>
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLogin.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLogin.java b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLogin.java
new file mode 100755
index 0000000..e681461
--- /dev/null
+++ b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLogin.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.security;
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Interface to code in the Tomcat valve. This is needed because Tomcat has a classloader system
+ * where code in a valve does not appear in the classloader that is used for servlets.
+ * There is a commons area that both valves and servlets share and this interface
+ * needs to be placed there.
+ */
+public interface TomcatLogin
+{
+ /**
+ * Attempt to login user with the specified credentials. Return a generated
+ * Principal object if login were successful
+ *
+ * @param username username.
+ * @param password credentials.
+ * @param request request via which this login attempt was made
+ * @return Principal generated for user if login were successful
+ */
+ Principal login(String username, String password, HttpServletRequest request);
+
+ /**
+ * The gateway calls this method to perform programmatic authorization.
+ * <p>
+ * A typical implementation would simply iterate over the supplied roles and
+ * check that atleast one of the roles returned true from a call to
+ * HttpServletRequest.isUserInRole(String role).
+ * </p>
+ *
+ * @param principal The principal being checked for authorization
+ * @param roles A List of role names to check, all members should be strings
+ * @return true if the principal is authorized given the list of roles
+ */
+ boolean authorize(Principal principal, List roles);
+
+ /**
+ * Logs out the user associated with the passed-in request.
+ *
+ * @param request whose associated user is to be loged-out
+ * @return true if logout were successful
+ */
+ boolean logout(HttpServletRequest request);
+
+ /**
+ * Classes that implement the flex.messaging.security.PrinciplaConverter interface, to convert a J2EE Principal to a
+ * Flex Principal impl. A Flex Principal impl is specific to different Application Servers and will be used by Flex to
+ * do security authorization check, which calls security framework API specific to Application Servers.
+ */
+ Principal convertPrincipal(Principal principal);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/fdbf19e4/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginCommand.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginCommand.java b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginCommand.java
new file mode 100755
index 0000000..9624a48
--- /dev/null
+++ b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginCommand.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.security;
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import flex.messaging.FlexContext;
+import flex.messaging.util.PropertyStringResourceLoader;
+
+/**
+ * A Tomcat specific implementation of LoginCommand.
+ */
+public class TomcatLoginCommand extends AppServerLoginCommand implements PrincipalConverter
+{
+ private static final int NO_VALVE = 20000;
+
+ /** {@inheritDoc} */
+ public Principal doAuthentication(String username, Object credentials) throws SecurityException
+ {
+ TomcatLogin login = TomcatLoginHolder.getLogin();
+ if (login == null)
+ {
+ SecurityException se = new SecurityException(new PropertyStringResourceLoader(PropertyStringResourceLoader.VENDORS_BUNDLE));
+ se.setMessage(NO_VALVE);
+ throw se;
+ }
+
+ String password = extractPassword(credentials);
+ if (password != null)
+ {
+ HttpServletRequest request = (HttpServletRequest)FlexContext.getHttpRequest();
+ return login.login(username, password, request);
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public boolean doAuthorization(Principal principal, List roles) throws SecurityException
+ {
+ boolean authorized = false;
+
+ HttpServletRequest request = FlexContext.getHttpRequest();
+ // Response is null for NIO endpoints.
+ HttpServletResponse response = FlexContext.getHttpResponse();
+
+ if (responseAndRequestNotNull(response, request)
+ && principalMatchesWithRequest(principal, request))
+ {
+ authorized = doAuthorization(principal, roles, request);
+ }
+ else
+ {
+ TomcatLogin login = TomcatLoginHolder.getLogin();
+ if (login == null)
+ {
+ SecurityException se =
+ new SecurityException(new PropertyStringResourceLoader(PropertyStringResourceLoader.VENDORS_BUNDLE));
+ se.setMessage(NO_VALVE);
+ throw se;
+ }
+ authorized = login.authorize(principal, roles);
+ }
+
+ return authorized;
+ }
+
+ /** {@inheritDoc} */
+ public boolean logout(Principal principal) throws SecurityException
+ {
+ HttpServletRequest request = FlexContext.getHttpRequest();
+ // Response is null for NIO endpoints.
+ HttpServletResponse response = FlexContext.getHttpResponse();
+ if (responseAndRequestNotNull(response, request))
+ {
+ TomcatLogin login = TomcatLoginHolder.getLogin();
+ if (login != null)
+ {
+ return login.logout(request);
+ }
+ else
+ {
+ //TODO should we do this?
+ //request.getSession(false).invalidate();
+ }
+ }
+ return true;
+ }
+
+ private boolean principalMatchesWithRequest(Principal principal, HttpServletRequest request)
+ {
+ return principal != null && principal.equals(request.getUserPrincipal());
+ }
+
+ private boolean responseAndRequestNotNull(HttpServletResponse response, HttpServletRequest request)
+ {
+ return response != null && request != null;
+ }
+
+ /** {@inheritDoc} */
+ public Principal convertPrincipal(Principal principal)
+ {
+ TomcatLogin login = TomcatLoginHolder.getLogin();
+ return login.convertPrincipal(principal);
+ }
+}