You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ow...@apache.org on 2013/06/21 19:23:33 UTC

svn commit: r1495512 - in /cxf/fediz/trunk/plugins: ./ core/src/main/java/org/apache/cxf/fediz/core/servlet/ websphere/ websphere/src/ websphere/src/main/ websphere/src/main/java/ websphere/src/main/java/org/ websphere/src/main/java/org/apache/ websphe...

Author: owulff
Date: Fri Jun 21 17:23:32 2013
New Revision: 1495512

URL: http://svn.apache.org/r1495512
Log:
[FEDIZ-61] Support for Websphere WAS 7 / 8

Added:
    cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/
    cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/FederationFilter.java
    cxf/fediz/trunk/plugins/websphere/
    cxf/fediz/trunk/plugins/websphere/pom.xml
    cxf/fediz/trunk/plugins/websphere/src/
    cxf/fediz/trunk/plugins/websphere/src/main/
    cxf/fediz/trunk/plugins/websphere/src/main/java/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/DefaultRoleToGroupMapper.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/FileBasedRoleToGroupMapper.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/RoleToGroupMapper.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/SecurityContextTTLChecker.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/
    cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/TAIConfigurationException.java
    cxf/fediz/trunk/plugins/websphere/src/main/resources/
    cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/
    cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/MappingSchema.xsd
    cxf/fediz/trunk/plugins/websphere/src/test/
    cxf/fediz/trunk/plugins/websphere/src/test/resources/
    cxf/fediz/trunk/plugins/websphere/src/test/resources/mappingSample.xml
Modified:
    cxf/fediz/trunk/plugins/pom.xml

Added: cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/FederationFilter.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/FederationFilter.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/FederationFilter.java (added)
+++ cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/servlet/FederationFilter.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,78 @@
+/**
+ * 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 org.apache.cxf.fediz.core.servlet;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.fediz.core.FederationPrincipal;
+import org.apache.cxf.fediz.core.SecurityTokenThreadLocal;
+
+
+
+/**
+ * Add security token to thread local
+ */
+public class FederationFilter implements Filter {
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response,
+                         FilterChain chain) throws IOException, ServletException {
+
+        if (request instanceof HttpServletRequest) {
+            HttpServletRequest hrequest = (HttpServletRequest)request;
+            Principal p = hrequest.getUserPrincipal();
+            FederationPrincipal fedPrinc = (FederationPrincipal)p;
+            Element el = (Element)fedPrinc.getLoginToken();
+            if (el != null) {
+                try {
+                    SecurityTokenThreadLocal.setToken(el);
+                    chain.doFilter(request, response);
+                } finally {
+                    SecurityTokenThreadLocal.setToken(null);
+                }
+            } else {
+                chain.doFilter(request, response);
+            }
+
+        } else {
+            chain.doFilter(request, response);
+        }
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+}

Modified: cxf/fediz/trunk/plugins/pom.xml
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/pom.xml?rev=1495512&r1=1495511&r2=1495512&view=diff
==============================================================================
--- cxf/fediz/trunk/plugins/pom.xml (original)
+++ cxf/fediz/trunk/plugins/pom.xml Fri Jun 21 17:23:32 2013
@@ -56,4 +56,12 @@
          </plugin>
       </plugins>
    </build>
+   <profiles>
+     <profile>
+       <id>websphere</id>
+       <modules>
+         <module>websphere</module>
+       </modules>
+     </profile>
+   </profiles>
 </project>

Added: cxf/fediz/trunk/plugins/websphere/pom.xml
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/pom.xml?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/pom.xml (added)
+++ cxf/fediz/trunk/plugins/websphere/pom.xml Fri Jun 21 17:23:32 2013
@@ -0,0 +1,81 @@
+<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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.cxf.fediz</groupId>
+        <artifactId>plugin</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>fediz-websphere</artifactId>
+    <name>Apache Fediz Plugin Websphere 7/8</name>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+	
+	<dependencies>
+
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<version>2.5</version>
+			<type>jar</type>
+			<scope>compile</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cxf.fediz</groupId>
+			<artifactId>fediz-core</artifactId>
+			<version>1.1.0-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+<!-- 
+		<dependency>
+			<groupId>com.ibm.ws</groupId>
+			<artifactId>runtime</artifactId>
+			<version>8</version>
+			<type>jar</type>
+			<scope>provided</scope>
+		</dependency>
+ -->
+		<dependency>
+			<groupId>com.ibm.ws</groupId>
+			<artifactId>runtime</artifactId>
+			<version>7</version>
+			<scope>compile</scope>
+		</dependency>
+
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>com.sun.tools.xjc.maven2</groupId>
+				<artifactId>maven-jaxb-plugin</artifactId>
+                                <version>1.1.1</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>generate</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<schemaDirectory>${basedir}/src/main/resources</schemaDirectory>
+					<generatePackage>org.apache.cxf.fediz.was.mapping.config</generatePackage>
+					<includeSchemas>
+						<includeSchema>**/MappingSchema.xsd</includeSchema>
+					</includeSchemas>
+					<excludeSchemas>
+						<excludeSchema>test*.xsd</excludeSchema>
+					</excludeSchemas>
+					<includeBindings>
+						<includeBinding>*.xjb</includeBinding>
+					</includeBindings>
+					<strict>true</strict>
+					<verbose>true</verbose>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/Constants.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,42 @@
+/**
+ * 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 org.apache.cxf.fediz.was;
+
+
+/**
+ * Constants used by the FedizInterceptor or SecurityContextTTLChecker classes
+ */
+//CHECKSTYLE:OFF
+public interface Constants {
+    
+    String HTTP_POST_METHOD = "POST";
+    //String UTF_8_ENCODING_SCHEME = "UTF-8";
+    String VERSION = "1.0.0";
+    String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+    
+    String USER_REGISTRY_JNDI_NAME = "UserRegistry";
+
+    String SUBJECT_TOKEN_KEY = "_security.token";
+    String SUBJECT_SESSION_ATTRIBUTE_KEY = "_tai.subject";
+    String SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY = "fediz.security.token";
+
+    String CONFIGURATION_FILE_PARAMETER = "config.file.location";
+    String ROLE_GROUP_MAPPER = "role.group.mapper";
+
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/DefaultRoleToGroupMapper.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/DefaultRoleToGroupMapper.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/DefaultRoleToGroupMapper.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/DefaultRoleToGroupMapper.java Fri Jun 21 17:23:32 2013
@@ -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.
+ */
+
+package org.apache.cxf.fediz.was.mapper;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ *
+ */
+public class DefaultRoleToGroupMapper implements RoleToGroupMapper {
+
+    
+    @Override
+    public void cleanup() {
+    }
+
+   
+    @Override
+    public List<String> groupsFromRoles(List<String> roles) {
+        return roles;
+    }
+
+    
+    @Override
+    public void initialize(Properties properties) {
+    }
+
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/FileBasedRoleToGroupMapper.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/FileBasedRoleToGroupMapper.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/FileBasedRoleToGroupMapper.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/FileBasedRoleToGroupMapper.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,196 @@
+/**
+ * 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 org.apache.cxf.fediz.was.mapper;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+import org.xml.sax.InputSource;
+
+import org.apache.cxf.fediz.was.mapping.config.Mapping;
+import org.apache.cxf.fediz.was.mapping.config.SamlToJ2EE;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Reference implementation for a Federation Claim to local WAS Group Mapper
+ */
+public class FileBasedRoleToGroupMapper implements RoleToGroupMapper {
+    
+    private static final String INITIALIZATION_THREAD_NAME = "ClaimGroupMapper";
+    private static final String REFRESH_TIMEOUT_PARAMETER = "groups.mapping.refresh.timeout";
+    private static final String MAPPING_FILE_PARAMETER = "groups.mapping.file";
+
+    private static final Logger LOG = LoggerFactory.getLogger(FileBasedRoleToGroupMapper.class);
+    
+    private String groupMappingFilename = "./mapping.xml";
+    private int refreshRateMillisec = 30 * 1000;
+    private boolean doLoop = true;
+    private Map<String, List<String>> mappings = new HashMap<String, List<String>>(10);
+    private long mappingFileLastModificationDate = -1;
+
+    @Override
+    public List<String> groupsFromRoles(List<String> roles) {
+        List<String> groups = new ArrayList<String>(20);
+        for (String key : roles) {
+            List<String> groupList = mappings.get(key);
+            if (groupList != null) {
+                groups.addAll(groupList);
+            } else {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("missing group for role: " + key);
+                }
+            }
+        }
+        return groups;
+    }
+
+    @Override
+    public void initialize(Properties props) {
+        if (props != null) {
+
+            for (Entry<Object, Object> entry : props.entrySet()) {
+                if (MAPPING_FILE_PARAMETER.equals(entry.getKey())) {
+                    String propertyValue = (String)entry.getValue();
+                    if (propertyValue != null) {
+                        groupMappingFilename = propertyValue;
+                        if (LOG.isInfoEnabled()) {
+                            LOG.info("Mapping file set to " + propertyValue);
+                        }
+                    }
+                }
+                if (REFRESH_TIMEOUT_PARAMETER.equals(entry.getKey())) {
+                    String propertyValue = (String)entry.getValue();
+                    if (propertyValue != null) {
+                        refreshRateMillisec = Integer.parseInt(propertyValue) * 1000;
+                        if (LOG.isInfoEnabled()) {
+                            LOG.info("Mapping file refresh timeout (sec) set to " + propertyValue);
+                        }
+                    }
+                }
+
+            }
+
+        }
+        // start the internal initialization thread
+        Thread initializationThread = new Thread() {
+            @Override
+            public void run() {
+                while (doLoop) {
+                    internalInit();
+                    try {
+                        sleep(refreshRateMillisec);
+                    } catch (InterruptedException e) {
+                        // nothing we can do here
+                    }
+                }
+            }
+        };
+        initializationThread.setName(INITIALIZATION_THREAD_NAME);
+        initializationThread.setPriority(Thread.MIN_PRIORITY);
+        initializationThread.start();
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Mapping file refresher thread started");
+        }
+    }
+
+    private void internalInit() {
+        synchronized (mappings) {
+            try {
+                File mappingFile = new File(groupMappingFilename);
+                if (!mappingFile.exists()) {
+                    throw new FileNotFoundException(groupMappingFilename);
+                }
+                boolean update = false;
+                if (mappings.size() == 0) {
+                    mappingFileLastModificationDate = mappingFile.lastModified();
+                    update = true;
+                } else {
+                    long currentFileModificationDate = mappingFile.lastModified();
+                    if (currentFileModificationDate > mappingFileLastModificationDate) {
+                        update = true;
+                        mappingFileLastModificationDate = currentFileModificationDate;
+                    }
+                }
+                if (update) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.info("Mapping file has changed. Reloading...");
+                    }
+                    Map<String, List<String>> newMap = loadMappingFile();
+
+                    mappings.clear();
+                    mappings.putAll(newMap);
+                    if (LOG.isDebugEnabled()) {
+                        LOG.info("Mapping file reloaded.");
+                    }
+                    
+                    
+                }
+            } catch (FileNotFoundException e) {
+                LOG.warn("Unable to load mappings due to: " + e.getMessage());
+            } catch (JAXBException e) {
+                LOG.warn("Unable to parse mappings due to: " + e.getMessage());
+            }
+        }
+    }
+
+    private Map<String, List<String>> loadMappingFile() throws FileNotFoundException, JAXBException {
+        InputSource input = new InputSource(new FileInputStream(groupMappingFilename));
+        JAXBContext context = JAXBContext.newInstance(Mapping.class);
+        Mapping localmappings = (Mapping)context.createUnmarshaller().unmarshal(input);
+
+        Map<String, List<String>> map = new HashMap<String, List<String>>(10);
+
+        Iterator<SamlToJ2EE> i = localmappings.getSamlToJ2EE().iterator();
+        while (i.hasNext()) {
+            SamlToJ2EE mapping = i.next();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(mapping.getClaim() + " mapped to "
+                    + mapping.getGroups().getJ2EeGroup().size() + " entries");
+                
+            }
+            map.put(mapping.getClaim(), mapping.getGroups().getJ2EeGroup());
+        }
+
+        
+        return map;
+    }
+
+    @Override
+    public void cleanup() {
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Stopping the mapping file refresher loop");
+        }
+        doLoop = false;
+    }
+
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/RoleToGroupMapper.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/RoleToGroupMapper.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/RoleToGroupMapper.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/mapper/RoleToGroupMapper.java Fri Jun 21 17:23:32 2013
@@ -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.
+ */
+package org.apache.cxf.fediz.was.mapper;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Interface for a WS-Federation Role to registry Group mapper delegate
+ */
+public interface RoleToGroupMapper {
+    /**
+     * Convenience Method to allow initialization of a GroupMapper 
+     * from the Properties defined in the WAS Server configuration
+     * 
+     */
+    void initialize(Properties properties);
+
+    /**
+     * Map the SAML Roles to locally defined WAS Groups
+     */
+    List<String> groupsFromRoles(List<String> roles);
+
+    /**
+     * Convenience Method to allow cleanup of allocated resources
+     * 
+     */ 
+    
+    void cleanup();
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/SecurityContextTTLChecker.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/SecurityContextTTLChecker.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/SecurityContextTTLChecker.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/servlet/filter/SecurityContextTTLChecker.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,152 @@
+/**
+ * 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 org.apache.cxf.fediz.was.servlet.filter;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+
+import org.w3c.dom.Element;
+
+import com.ibm.websphere.security.WSSecurityException;
+import com.ibm.websphere.security.auth.WSSubject;
+
+import org.apache.cxf.fediz.core.FederationResponse;
+import org.apache.cxf.fediz.core.SecurityTokenThreadLocal;
+import org.apache.cxf.fediz.was.Constants;
+import org.apache.cxf.fediz.was.tai.FedizInterceptor;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * A Servlet Filter that MUST be configured to match the '/*' request scheme on each Web Application
+ * to enforce SAML assertion TimeToLive checking 
+ */
+public class SecurityContextTTLChecker extends HttpServlet implements Filter {
+    private static final Logger LOG = LoggerFactory.getLogger(SecurityContextTTLChecker.class);
+    private static final long serialVersionUID = 5732969339258858728L;
+
+    private String contextPath;
+
+    /*
+     * (non-Java-doc)
+     * @see java.lang.Object#Object()
+     */
+    public SecurityContextTTLChecker() {
+        super();
+    }
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        contextPath = config.getServletContext().getContextPath();
+        FedizInterceptor.registerContext(contextPath);
+    }
+
+    /*
+     * (non-Java-doc)
+     * @see javax.servlet.Filter#doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+     */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+        throws IOException, ServletException {
+
+        try {
+            FederationResponse fedResponse = null;
+            Subject subject = WSSubject.getCallerSubject();
+            boolean validSecurityTokenFound = false;
+            if (subject != null) {
+                fedResponse = getCachedFederationResponse(subject);
+                validSecurityTokenFound = checkSecurityToken(fedResponse);
+            }
+            if (!validSecurityTokenFound) {
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("Security token not found or WS-Federation session has expired");
+                }
+                // delete the session
+                if (request instanceof HttpServletRequest) {
+                    HttpServletRequest req = (HttpServletRequest)request;
+                    req.getSession().invalidate();
+                }
+            } else {
+                Element el = (Element)fedResponse.getToken();
+                if (el != null) {
+                    SecurityTokenThreadLocal.setToken(el);
+                }
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Security token is still valid. Forwarding request");
+                }
+            }
+            chain.doFilter(request, response);
+        } catch (WSSecurityException e) {
+            throw new ServletException("Unable to get a valid Subject instance in Filter chain context", e);
+        } catch (Exception e) {
+            LOG.error("Failed validating cached security token", e);
+            throw new ServletException("Failed validating cached security token", e);
+        } finally {
+            SecurityTokenThreadLocal.setToken(null);
+        }
+    }
+
+    private boolean checkSecurityToken(FederationResponse response) {
+        long currentTime = System.currentTimeMillis();
+        return response.getTokenExpires().getTime() > currentTime;
+    }
+    
+    private FederationResponse getCachedFederationResponse(Subject subject) {
+        Iterator<?> i = subject.getPublicCredentials().iterator();
+        
+        while (i.hasNext()) {
+            Object o = i.next();
+            if (o instanceof Hashtable) {
+                @SuppressWarnings("unchecked")
+                Map<Object, Object> table = (Hashtable<Object, Object>)o;
+                return (FederationResponse)table.get(Constants.SUBJECT_TOKEN_KEY);
+            }
+        }
+        return null;
+    }
+    
+
+    /*
+     * (non-Java-doc)
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy() {
+        FedizInterceptor.deRegisterContext(contextPath);
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/FedizInterceptor.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,496 @@
+/**
+ * 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 org.apache.cxf.fediz.was.tai;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import com.ibm.websphere.security.CustomRegistryException;
+import com.ibm.websphere.security.EntryNotFoundException;
+import com.ibm.websphere.security.UserRegistry;
+import com.ibm.websphere.security.WebTrustAssociationException;
+import com.ibm.websphere.security.WebTrustAssociationFailedException;
+import com.ibm.wsspi.security.tai.TAIResult;
+import com.ibm.wsspi.security.tai.TrustAssociationInterceptor;
+import com.ibm.wsspi.security.token.AttributeNameConstants;
+
+import org.apache.cxf.fediz.core.FederationConstants;
+import org.apache.cxf.fediz.core.FederationProcessor;
+import org.apache.cxf.fediz.core.FederationProcessorImpl;
+import org.apache.cxf.fediz.core.FederationRequest;
+import org.apache.cxf.fediz.core.FederationResponse;
+import org.apache.cxf.fediz.core.config.FederationConfigurator;
+import org.apache.cxf.fediz.core.config.FederationContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.was.Constants;
+import org.apache.cxf.fediz.was.mapper.DefaultRoleToGroupMapper;
+import org.apache.cxf.fediz.was.mapper.RoleToGroupMapper;
+import org.apache.cxf.fediz.was.tai.exception.TAIConfigurationException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Trust Authentication Interceptor (TAI) that trusts a Sign-In-Response  
+ * provided from a configured IP/STS and instantiates
+ * the corresponding WAS Subject
+ */
+public class FedizInterceptor implements TrustAssociationInterceptor {
+    private static final Logger LOG = LoggerFactory.getLogger(FedizInterceptor.class);
+    private static List<String> authorizedWebApps = new ArrayList<String>(15);
+    
+    private String configFile;
+    private FederationConfigurator configurator;
+    private RoleToGroupMapper mapper;
+
+    public String getConfigFile() {
+        return configFile;
+    }
+
+    public void setConfigFile(String configFile) {
+        this.configFile = configFile;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#cleanup()
+     */
+    @Override
+    public void cleanup() {
+        configurator = null;
+        mapper = null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#getType()
+     */
+    @Override
+    public String getType() {
+        return this.getClass().getName();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#getVersion()
+     */
+    @Override
+    public String getVersion() {
+        return Constants.VERSION;
+    }
+
+    /**
+     * Registers a WebApplication using its contextPath as a key. 
+     * This method must be called by the associated
+     * security ServletFilter instance of a secured application at initialization time
+     * 
+     * @param contextPath
+     */
+    public static void registerContext(String contextPath) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Registering secured context-path: " + contextPath);
+        }
+        authorizedWebApps.add(contextPath);
+    }
+
+    /**
+     * Deregister a WebApplication using its contextPath as a key. 
+     * This method must be called by the associated
+     * security ServletFilter instance of a secured application 
+     * in the #destroy() method
+     * 
+     * @param contextPath
+     */
+    public static void deRegisterContext(String contextPath) {
+        if (authorizedWebApps.contains(contextPath)) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("De-registering secured context-path " + contextPath);
+            }
+            synchronized (authorizedWebApps) {
+                authorizedWebApps.remove(contextPath);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#initialize(java.util.Properties)
+     */
+    @Override
+    public int initialize(Properties props) throws WebTrustAssociationFailedException {
+        if (props != null) {
+            try {
+                String roleGroupMapper = props.getProperty(Constants.ROLE_GROUP_MAPPER);
+                if (roleGroupMapper != null && !roleGroupMapper.isEmpty()) {
+                    try {
+                        mapper = (RoleToGroupMapper)Class.forName(roleGroupMapper).newInstance();
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Using the " + roleGroupMapper + " mapper class");
+                        }
+
+                        mapper.initialize(props);
+                    } catch (Exception e) {
+                        throw new TAIConfigurationException(
+                                                            "Invalid TAI configuration for idpRoleToGroupMapper: "
+                                                                + e.getClass().getName() + " "
+                                                                + e.getMessage());
+                    }
+                } else {
+                    mapper = new DefaultRoleToGroupMapper();
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Using the DefaultRoleToGroupMapper mapper class");
+                    }
+                }
+
+                String configFileLocation = props.getProperty(Constants.CONFIGURATION_FILE_PARAMETER);
+                if (configFileLocation != null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Configuration file location set to " + configFileLocation);
+                    }
+                    File f = new File(configFileLocation);
+
+                    configurator = new FederationConfigurator();
+                    configurator.loadConfig(f);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Federation config loaded from path : " + configFileLocation);
+                    }
+                } else {
+                    throw new WebTrustAssociationFailedException("Missing required initialization parameter "
+                                                                 + Constants.CONFIGURATION_FILE_PARAMETER);
+                }
+            } catch (Throwable t) {
+                LOG.warn("Failed initializing TAI", t);
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    private FederationContext getFederationContext(HttpServletRequest req) {
+        String contextPath = req.getContextPath();
+        if (contextPath == null || contextPath.isEmpty()) {
+            contextPath = "/";
+        }
+        return configurator.getFederationContext(contextPath);
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.ibm.wsspi.security.tai.TrustAssociationInterceptor#isTargetInterceptor(javax.servlet.http.
+     * HttpServletRequest)
+     */
+    @Override
+    public boolean isTargetInterceptor(HttpServletRequest req) throws WebTrustAssociationException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Request URI: " + req.getRequestURI());
+        }
+        FederationContext context = getFederationContext(req);
+
+        if (context != null) {
+            return true;
+        } else {
+            LOG.warn("No Federation Context configured for context-path " + req.getContextPath());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * com.ibm.wsspi.security.tai.TrustAssociationInterceptor#negotiateValidateandEstablishTrust(javax.servlet
+     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public TAIResult negotiateValidateandEstablishTrust(HttpServletRequest req, HttpServletResponse resp)
+        throws WebTrustAssociationFailedException {
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Request URI: " + req.getRequestURI());
+        }
+        FederationContext fedCtx = getFederationContext(req);
+
+        if (fedCtx == null) {
+            LOG.warn("No Federation Context configured for context-path " + req.getContextPath());
+            return TAIResult.create(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+
+        try {
+            // looks for the wa parameter as a way to determine the current step
+            String wa = req.getParameter(FederationConstants.PARAM_ACTION);
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("WS-Federation action: " + (wa == null ? "<not set>" : wa));
+            }
+            if (wa == null) {
+                return handleNoWA(req, resp);
+            } else {
+                if (FederationConstants.ACTION_SIGNIN.equals(wa)) {
+                    return handleSignIn(req, resp);
+                } else {
+                    throw new Exception("Unsupported WS-Federation action [" + wa + "]");
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Exception occured validating request", e);
+            throw new WebTrustAssociationFailedException(e.getMessage());
+        }
+    }
+
+    private TAIResult handleSignIn(HttpServletRequest req, HttpServletResponse resp)
+        throws ProcessingException, IOException, WebTrustAssociationFailedException, Exception {
+        if (req.getMethod().equals(Constants.HTTP_POST_METHOD)) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Sign-In-Response received");
+            }
+            String wresult = req.getParameter(FederationConstants.PARAM_RESULT);
+            String wctx = req.getParameter(FederationConstants.PARAM_CONTEXT);
+            if (wresult != null && wctx != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Validating RSTR...");
+                }
+                // process and validate the token
+                FederationResponse federationResponse = processSigninRequest(req, resp);
+                
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("RSTR validated successfully");
+                }
+                
+                HttpSession session = req.getSession(true);
+                session.setAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY, federationResponse);
+
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("Redirecting request to " + wctx);
+                }
+                resp.sendRedirect(wctx);
+                return TAIResult.create(HttpServletResponse.SC_FOUND);
+            } else {
+                throw new Exception("Missing required parameter [wctx or wresult]");
+            }
+        } else {
+            throw new Exception("Incorrect method GET for Sign-In-Response");
+        }
+    }
+
+    private TAIResult handleNoWA(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+        WebTrustAssociationFailedException, Exception {
+        HttpSession session = req.getSession(false);
+        if (session == null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("No session found. Sending a token request");
+            }
+            redirectToIdp(req, resp);
+            return TAIResult.create(HttpServletResponse.SC_FOUND);
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Session ID is " + session.getId());
+            }
+            
+            FederationResponse federationResponse = (FederationResponse)session
+                .getAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY);
+            if (federationResponse != null) {
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("Security Token found in session: " + federationResponse.getUsername());
+                }
+                
+                TAIResult result = null;
+                // check that the target WebApp is properly configured for Token TTL enforcement
+                if (authorizedWebApps.contains(req.getContextPath())) {
+                    
+                    if (LOG.isDebugEnabled()) {
+                        LOG.info("Security Filter properly configured - forwarding subject");
+                    }
+                    
+                    // proceed creating the JAAS Subject
+                    List<String> groupsIds = groupIdsFromTokenRoles(federationResponse);
+                    Subject subject = createSubject(federationResponse, groupsIds, session.getId());
+
+                    result = TAIResult.create(HttpServletResponse.SC_OK, "ignore", subject);
+                } else {
+                    result = TAIResult.create(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                    LOG.warn("No Security Filter configured for " + req.getContextPath());
+                }
+                // leave the Session untouched
+                session.removeAttribute(Constants.SECURITY_TOKEN_SESSION_ATTRIBUTE_KEY);
+                return result;
+            } else {
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("No Subject found in existing session. Redirecting to IDP");
+                }
+                redirectToIdp(req, resp);
+                return TAIResult.create(HttpServletResponse.SC_FOUND);
+            }
+        }
+    }
+
+    protected void redirectToIdp(HttpServletRequest request, HttpServletResponse response)
+        throws IOException, WebTrustAssociationFailedException {
+        FederationProcessor processor = new FederationProcessorImpl();
+
+        String contextName = request.getContextPath();
+        if (contextName == null || contextName.isEmpty()) {
+            contextName = "/";
+        }
+        FederationContext fedCtx = getFederationContext(request);
+
+        String redirectURL = null;
+        StringBuilder sb = new StringBuilder();
+
+        try {
+            redirectURL = processor.createSignInRequest(request, fedCtx);
+            if (redirectURL != null) {
+                sb.append(redirectURL);
+
+            }
+            request.getQueryString();
+            if (request.getRequestURI() != null && request.getRequestURI().length() > 0) {
+                sb.append('&').append(FederationConstants.PARAM_CONTEXT).append('=')
+                    .append(URLEncoder.encode(request.getRequestURI(), "UTF-8"));
+            }
+            if (request.getQueryString() != null && !request.getQueryString().isEmpty()) {
+                sb.append('?');
+                sb.append(URLEncoder.encode(request.getQueryString(), "UTF-8"));
+            }
+
+            if (redirectURL != null) {
+                response.sendRedirect(sb.toString());
+            } else {
+                LOG.error("RedirectUrl is null. Failed to create SignInRequest.");
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                   "Failed to create SignInRequest.");
+            }
+        } catch (ProcessingException ex) {
+            LOG.error("Failed to create SignInRequest", ex);
+            throw new WebTrustAssociationFailedException(ex.getMessage());
+        }
+
+    }
+
+    private List<String> groupIdsFromTokenRoles(FederationResponse federationResponse) throws Exception {
+        InitialContext ctx = new InitialContext();
+        UserRegistry reg = (UserRegistry)ctx.lookup(Constants.USER_REGISTRY_JNDI_NAME);
+
+        List<String> localGroups = mapper.groupsFromRoles(federationResponse.getRoles());
+
+        List<String> groupIds = new ArrayList<String>(1);
+        if (localGroups != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Converting " + localGroups.size() + " group names to uids");
+            }
+            for (String localGroup : localGroups) {
+                String guid = convertGroupNameToUniqueId(reg, localGroup);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Group '" + localGroup + "' maps to guid: " + guid);
+                }
+                groupIds.add(guid);
+            }
+        }
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Group list: " + groupIds.toString());
+        }
+        return groupIds;
+    }
+
+    /**
+     * Creates the JAAS Subject so that WAS Runtime will not check the local registry
+     * 
+     * @param securityName
+     * @param uniqueid
+     * @param groups
+     * @param token
+     * @return
+     */
+
+    private Subject createSubject(FederationResponse federationResponse, List<String> groups, String cacheKey) {
+        String uniqueId = "user:defaultWIMFileBasedRealm/cn=" + federationResponse.getUsername()
+                          + ",o=defaultWIMFileBasedRealm";
+        String completeCacheKey = uniqueId + ':' + cacheKey;
+
+        // creating the JAAS Subject so that WAS won't do a lookup in the registry
+        Subject subject = new Subject();
+
+        Map<String, Object> map = new Hashtable<String, Object>();
+        map.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueId);
+        map.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, federationResponse.getUsername());
+        map.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups);
+        map.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, completeCacheKey);
+        // caching the WS-Federation security token for further reuse by the application
+        map.put(Constants.SUBJECT_TOKEN_KEY, federationResponse);
+
+        subject.getPublicCredentials().add(map);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Subject credentials: " + map.toString());
+        }
+        return subject;
+    }
+
+    public FederationResponse processSigninRequest(HttpServletRequest req, HttpServletResponse resp)
+        throws ProcessingException {
+        FederationRequest federationRequest = new FederationRequest();
+
+        String wa = req.getParameter(FederationConstants.PARAM_ACTION);
+        String wct = req.getParameter(FederationConstants.PARAM_CURRENT_TIME);
+        String wresult = req.getParameter(FederationConstants.PARAM_RESULT);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("wa=" + wa);
+            LOG.debug("wct=" + wct);
+            LOG.debug("wresult=" + wresult);
+        }
+
+        federationRequest.setWa(wa);
+        federationRequest.setWct(wct);
+        federationRequest.setWresult(wresult);
+
+        FederationContext fedCtx = getFederationContext(req);
+
+        FederationProcessor processor = new FederationProcessorImpl();
+        return processor.processRequest(federationRequest, fedCtx);
+    }
+
+    /**
+     * Convenience method for converting a list of group names to their unique group IDs
+     * 
+     * @param reg
+     * @param group
+     * @return
+     * @throws EntryNotFoundException
+     * @throws CustomRegistryException
+     * @throws RemoteException
+     */
+    private String convertGroupNameToUniqueId(UserRegistry reg, String group) throws EntryNotFoundException,
+        CustomRegistryException, RemoteException {
+        return reg.getUniqueGroupId(group);
+    }
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/TAIConfigurationException.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/TAIConfigurationException.java?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/TAIConfigurationException.java (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/java/org/apache/cxf/fediz/was/tai/exception/TAIConfigurationException.java Fri Jun 21 17:23:32 2013
@@ -0,0 +1,31 @@
+/**
+ * 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 org.apache.cxf.fediz.was.tai.exception;
+
+/**
+ *
+ */
+public class TAIConfigurationException extends Exception {
+
+    private static final long serialVersionUID = -8552829326107853555L;
+
+    public TAIConfigurationException(String msg) {
+        super(msg);
+    }
+}

Added: cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/MappingSchema.xsd
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/MappingSchema.xsd?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/MappingSchema.xsd (added)
+++ cxf/fediz/trunk/plugins/websphere/src/main/resources/schemas/MappingSchema.xsd Fri Jun 21 17:23:32 2013
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:element name="samlToJ2EE">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="claim"/>
+        <xsd:element ref="groups"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="groups">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element maxOccurs="unbounded" ref="j2eeGroup"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="j2eeGroup" type="xsd:string"/>
+  <xsd:element name="claim" type="xsd:string"/>
+  <xsd:element name="mapping">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element maxOccurs="unbounded" ref="samlToJ2EE"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
\ No newline at end of file

Added: cxf/fediz/trunk/plugins/websphere/src/test/resources/mappingSample.xml
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/websphere/src/test/resources/mappingSample.xml?rev=1495512&view=auto
==============================================================================
--- cxf/fediz/trunk/plugins/websphere/src/test/resources/mappingSample.xml (added)
+++ cxf/fediz/trunk/plugins/websphere/src/test/resources/mappingSample.xml Fri Jun 21 17:23:32 2013
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<mapping>
+	<samlToJ2EE>
+		<claim>gold</claim>
+		<groups>
+			<j2eeGroup>goldUsers</j2eeGroup>
+		</groups>
+	</samlToJ2EE>
+	<samlToJ2EE>
+		<claim>silver</claim>
+		<groups>
+			<j2eeGroup>silverUsers</j2eeGroup>
+		</groups>
+	</samlToJ2EE>
+	<samlToJ2EE>
+		<claim>bronze</claim>
+		<groups>
+			<j2eeGroup>bronzeUsers</j2eeGroup>
+		</groups>
+	</samlToJ2EE>
+	<samlToJ2EE>
+		<claim>vip</claim>
+		<groups>
+			<j2eeGroup>goldUsers</j2eeGroup>
+			<j2eeGroup>silverUsers</j2eeGroup>
+		</groups>
+	</samlToJ2EE>
+</mapping>