flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cd...@apache.org
Subject [1/3] flex-blazeds git commit: - Cleaned up the structure of the optional container modules
Date Tue, 04 Aug 2015 12:07:04 GMT
Repository: flex-blazeds
Updated Branches:
  refs/heads/4.8.0 012fad7c7 -> 2f72a6378


http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/2f72a637/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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/2f72a637/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginHolder.java
----------------------------------------------------------------------
diff --git a/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginHolder.java
b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginHolder.java
new file mode 100755
index 0000000..d3a0449
--- /dev/null
+++ b/opt/tomcat/tomcat-base/src/main/java/flex/messaging/security/TomcatLoginHolder.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+/**
+ * Contains the last good TomcatLogin for use by the TomcatLoginCommand.
+ */
+public class TomcatLoginHolder
+{
+    private static ThreadLocal logins = new ThreadLocal();
+    
+    // We should really make this one as a singleton instead of resetting it every time we
call setLogin()
+    private static TomcatLogin nioBasedLogin;
+
+    private TomcatLoginHolder()
+    {
+        // No-op.
+    }
+
+    /**
+     * Saves the last valid login.
+     * 
+     * @param login last valid login
+     */
+    public static void setLogin(TomcatLogin login)
+    {
+        logins.set(login);
+    }
+
+    /**
+     * Retrieves the last valid login.
+     * 
+     * @return last valid login.
+     */
+    public static TomcatLogin getLogin()
+    {
+        return logins.get() != null? (TomcatLogin)logins.get() : nioBasedLogin;
+    }
+    
+    /**
+     * Saves the nio based login.
+     * 
+     * @param login the valid login that nio based endpoints should use
+     */
+    public static void setNioBasedLogin(TomcatLogin login)
+    {
+        nioBasedLogin = login;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/2f72a637/opt/weblogic/pom.xml
----------------------------------------------------------------------
diff --git a/opt/weblogic/pom.xml b/opt/weblogic/pom.xml
new file mode 100755
index 0000000..aa9e42a
--- /dev/null
+++ b/opt/weblogic/pom.xml
@@ -0,0 +1,61 @@
+<!--
+
+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.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>flex-messaging-opt-weblogic</artifactId>
+
+	<distributionManagement>
+		<site>
+			<id>blazeds_mvn_site</id>
+			<url>${maven.site.local.url}/flex-messaging-opt/${project.artifactId}</url>
+		</site>
+	</distributionManagement>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.weblogic</groupId>
+			<artifactId>wsexception</artifactId>
+			<version>7.0.5.0</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/../../lib/wsexception.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.weblogic</groupId>
+			<artifactId>weblogic</artifactId>
+			<version>7.0.5.0</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/../../lib/weblogic.jar</systemPath>
+		</dependency>
+	</dependencies>
+
+    <properties>
+		<appserver>weblogic</appserver>
+		<source.dir>src/weblogic</source.dir>
+		<exclude.pattern>none</exclude.pattern>
+	</properties>
+
+</project>

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/2f72a637/opt/weblogic/src/main/java/flex/messaging/security/WeblogicLoginCommand.java
----------------------------------------------------------------------
diff --git a/opt/weblogic/src/main/java/flex/messaging/security/WeblogicLoginCommand.java
b/opt/weblogic/src/main/java/flex/messaging/security/WeblogicLoginCommand.java
new file mode 100755
index 0000000..0f698c8
--- /dev/null
+++ b/opt/weblogic/src/main/java/flex/messaging/security/WeblogicLoginCommand.java
@@ -0,0 +1,239 @@
+/*
+ * 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/2f72a637/opt/websphere/pom.xml
----------------------------------------------------------------------
diff --git a/opt/websphere/pom.xml b/opt/websphere/pom.xml
new file mode 100755
index 0000000..af06737
--- /dev/null
+++ b/opt/websphere/pom.xml
@@ -0,0 +1,55 @@
+<!--
+
+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.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>flex-messaging-opt-webpshere</artifactId>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.ibm.websphere</groupId>
+			<artifactId>wsexception</artifactId>
+			<version>7.0 SP5</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/../../lib/wsexception.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.ibm.websphere</groupId>
+			<artifactId>asynchbeans</artifactId>
+			<version>7.0 SP5</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/../../lib/asynchbeans.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.ibm.websphere</groupId>
+			<artifactId>sas</artifactId>
+			<version>7.0 SP5</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/../../lib/sas.jar</systemPath>
+		</dependency>
+	</dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/2f72a637/opt/websphere/src/main/java/flex/management/WebSphereMBeanServerLocator.java
----------------------------------------------------------------------
diff --git a/opt/websphere/src/main/java/flex/management/WebSphereMBeanServerLocator.java
b/opt/websphere/src/main/java/flex/management/WebSphereMBeanServerLocator.java
new file mode 100755
index 0000000..533f258
--- /dev/null
+++ b/opt/websphere/src/main/java/flex/management/WebSphereMBeanServerLocator.java
@@ -0,0 +1,86 @@
+/*
+ * 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/2f72a637/opt/websphere/src/main/java/flex/messaging/security/WebSphereLoginCommand.java
----------------------------------------------------------------------
diff --git a/opt/websphere/src/main/java/flex/messaging/security/WebSphereLoginCommand.java
b/opt/websphere/src/main/java/flex/messaging/security/WebSphereLoginCommand.java
new file mode 100755
index 0000000..cf02d26
--- /dev/null
+++ b/opt/websphere/src/main/java/flex/messaging/security/WebSphereLoginCommand.java
@@ -0,0 +1,273 @@
+/*
+ * 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/2f72a637/opt/websphere/src/main/java/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
----------------------------------------------------------------------
diff --git a/opt/websphere/src/main/java/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
b/opt/websphere/src/main/java/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
new file mode 100755
index 0000000..a35c0e9
--- /dev/null
+++ b/opt/websphere/src/main/java/flex/messaging/util/concurrent/AsynchBeansWorkManagerExecutor.java
@@ -0,0 +1,231 @@
+/*
+ * 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.
+        }
+    }
+}


Mime
View raw message