Adding spring3 plugin + tests back in
Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/5f752297 Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/5f752297 Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/5f752297 Branch: refs/heads/master Commit: 5f7522979aeee0f8bc0531519fa724aef56acbbe Parents: dc0efb8 Author: Colm O hEigeartaigh <[email protected]> Authored: Thu Apr 13 16:49:06 2017 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Thu Apr 13 16:49:06 2017 +0100 ---------------------------------------------------------------------- plugins/pom.xml | 1 + plugins/spring/README.txt | 2 +- plugins/spring3/README.txt | 20 +++ plugins/spring3/pom.xml | 122 ++++++++++++++ plugins/spring3/src/main/assembly/assembly.xml | 37 +++++ .../cxf/fediz/spring/FederationConfig.java | 33 ++++ .../cxf/fediz/spring/FederationConfigImpl.java | 104 ++++++++++++ .../apache/cxf/fediz/spring/FederationUser.java | 53 ++++++ .../fediz/spring/SpringFedizMessageSource.java | 45 ++++++ .../AbstractFederationUserDetailsService.java | 42 +++++ .../authentication/ExpiredTokenException.java | 35 ++++ .../FederationAuthenticationProvider.java | 153 ++++++++++++++++++ .../FederationAuthenticationToken.java | 109 +++++++++++++ .../FederationResponseAuthenticationToken.java | 54 +++++++ ...AuthoritiesUserDetailsFederationService.java | 65 ++++++++ ...erationPreAuthenticatedProcessingFilter.java | 72 +++++++++ ...AuthoritiesUserDetailsFederationService.java | 80 +++++++++ .../web/FederationAuthenticationEntryPoint.java | 144 +++++++++++++++++ .../FederationAuthenticationFailureHandler.java | 103 ++++++++++++ .../web/FederationAuthenticationFilter.java | 161 ++++++++++++++++++ .../spring/web/FederationLogoutFilter.java | 71 ++++++++ .../web/FederationLogoutSuccessHandler.java | 86 ++++++++++ .../web/FederationSignOutCleanupFilter.java | 67 ++++++++ .../apache/cxf/fediz/spring/messages.properties | 2 + systests/spring/pom.xml | 8 + .../cxf/fediz/integrationtests/Spring3Test.java | 162 +++++++++++++++++++ .../spring/src/test/resources/fediz_config.xml | 41 ++++- systests/webapps/pom.xml | 1 + systests/webapps/spring3Webapp/pom.xml | 101 ++++++++++++ .../cxf/fediz/example/FederationServlet.java | 108 +++++++++++++ .../src/main/resources/clienttrust.jks | Bin 0 -> 1512 bytes .../src/main/resources/log4j.properties | 16 ++ .../src/main/resources/logging.properties | 53 ++++++ .../WEB-INF/applicationContext-security.xml | 113 +++++++++++++ .../src/main/webapp/WEB-INF/web.xml | 83 ++++++++++ .../spring3Webapp/src/main/webapp/index.html | 25 +++ .../src/main/webapp/secure/test.html | 25 +++ 37 files changed, 2395 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/pom.xml b/plugins/pom.xml index 2ee96af..5d8e71d 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -38,6 +38,7 @@ <module>jetty9</module> <module>spring</module> <module>spring2</module> + <module>spring3</module> <module>cxf</module> </modules> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring/README.txt ---------------------------------------------------------------------- diff --git a/plugins/spring/README.txt b/plugins/spring/README.txt index 8c50905..077d9d6 100644 --- a/plugins/spring/README.txt +++ b/plugins/spring/README.txt @@ -1,4 +1,4 @@ -Fediz configuration for Spring Security +Fediz configuration for Spring Security 4 --------------------------------------- The Servlet Container installation doesn't have to be updated before a Web Application can be deployed. http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/README.txt ---------------------------------------------------------------------- diff --git a/plugins/spring3/README.txt b/plugins/spring3/README.txt new file mode 100644 index 0000000..59eabee --- /dev/null +++ b/plugins/spring3/README.txt @@ -0,0 +1,20 @@ +Fediz configuration for Spring Security 3 +--------------------------------------- + +The Servlet Container installation doesn't have to be updated before a Web Application can be deployed. + +It's recommended to use HTTPS to avoid sending tokens/cookies in clear text on the network. +Please check your Servlet Container documentation how to set it up. + +Please check the Spring Security example to get more information how to deploy a web application +using Spring Security 3. + +The following wiki page explains how to configure the Fediz Spring plugin in your application: +http://cxf.apache.org/fediz-spring.html + +The following wiki page explains the fediz configuration which is Container independent: +http://cxf.apache.org/fediz-configuration.html + +Note: The Fediz Spring plugin is packaged with your application. +Thus it's recommended to package it with the application +using Apache Maven. http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/spring3/pom.xml b/plugins/spring3/pom.xml new file mode 100644 index 0000000..a76688e --- /dev/null +++ b/plugins/spring3/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<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.cxf.fediz</groupId> + <artifactId>plugin</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>fediz-spring3</artifactId> + <name>Apache Fediz Plugin Spring3</name> + <packaging>bundle</packaging> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <spring.security.version>3.2.10.RELEASE</spring.security.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-web</artifactId> + <version>${spring.security.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-config</artifactId> + <version>${spring.security.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf.fediz</groupId> + <artifactId>fediz-core</artifactId> + <version>${project.version}</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>${servlet.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <version>${slf4j.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>zip-file</id> + <phase>package</phase> + <goals> + <goal>attached</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/assembly.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Implementation-Title>Apache CXF Fediz</Implementation-Title> + <Implementation-Vendor>The Apache Software Foundation</Implementation-Vendor> + <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id> + <Implementation-Version>${project.version}</Implementation-Version> + <Specification-Title>Apache CXF Fediz</Specification-Title> + <Specification-Vendor>The Apache Software Foundation</Specification-Vendor> + <Specification-Version>${project.version}</Specification-Version> + <Export-Package> + org.apache.cxf.fediz.spring.*;version="${project.version}" + </Export-Package> + <Import-Package> + !org.apache.cxf.fediz.spring*, + org.apache.cxf.fediz.core.*, + *;resolution:=optional + </Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/assembly/assembly.xml ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/assembly/assembly.xml b/plugins/spring3/src/main/assembly/assembly.xml new file mode 100644 index 0000000..99a74db --- /dev/null +++ b/plugins/spring3/src/main/assembly/assembly.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 +http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>zip-with-dependencies</id> + <formats> + <format>zip</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <useProjectArtifact>true</useProjectArtifact> + <unpack>false</unpack> + <scope>runtime</scope> + </dependencySet> + </dependencySets> +</assembly> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfig.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfig.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfig.java new file mode 100644 index 0000000..4c5ba20 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfig.java @@ -0,0 +1,33 @@ +/** + * 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.spring; + +import java.util.List; + +import org.apache.cxf.fediz.core.config.FedizContext; + +public interface FederationConfig { + + List<FedizContext> getFedizContextList(); + + FedizContext getFedizContext(String contextName); + + FedizContext getFedizContext(); +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfigImpl.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfigImpl.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfigImpl.java new file mode 100644 index 0000000..736d847 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationConfigImpl.java @@ -0,0 +1,104 @@ +/** + * 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.spring; + +import java.util.List; + +import javax.servlet.ServletContext; + +import org.apache.cxf.fediz.core.config.FedizConfigurator; +import org.apache.cxf.fediz.core.config.FedizContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.core.io.Resource; +import org.springframework.util.Assert; +import org.springframework.web.context.ServletContextAware; + +public class FederationConfigImpl implements FederationConfig, ServletContextAware { + + private static final Logger LOG = LoggerFactory.getLogger(FederationConfigImpl.class); + + private Resource configFile; + private String contextName; + + private ServletContext servletContext; + private FedizConfigurator configurator = new FedizConfigurator(); + + + public Resource getConfigFile() { + return configFile; + } + + public void setConfigFile(Resource configFile) { + this.configFile = configFile; + } + + public String getContextName() { + return contextName; + } + + public void setContextName(String contextName) { + this.contextName = contextName; + } + + public void init() { + Assert.notNull(this.configFile, "property 'configFile' mandatory"); + try { + configurator.loadConfig(this.configFile.getFile()); + } catch (Exception e) { + LOG.error("Failed to parse '" + configFile.getDescription() + "'", e); + throw new BeanCreationException("Failed to parse '" + configFile.getDescription() + "'", e); + } + } + + @Override + public List<FedizContext> getFedizContextList() { + return configurator.getFedizContextList(); + } + + @Override + public FedizContext getFedizContext(String context) { + FedizContext ctx = configurator.getFedizContext(context); + if (ctx == null) { + LOG.error("Federation context '" + context + "' not found."); + throw new IllegalStateException("Federation context '" + context + "' not found."); + } + return ctx; + } + + @Override + public FedizContext getFedizContext() { + if (servletContext != null) { + LOG.debug("Reading federation configuration for context '{}'", + servletContext.getContextPath()); + return getFedizContext(servletContext.getContextPath()); + } else { + Assert.notNull(contextName, "Property 'contextName' must be configured because ServletContext null"); + return getFedizContext(contextName); + } + } + + @Override + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationUser.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationUser.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationUser.java new file mode 100644 index 0000000..fdf5b6b --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/FederationUser.java @@ -0,0 +1,53 @@ +/** + * 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.spring; + +import java.util.Collection; + +import org.apache.cxf.fediz.core.ClaimCollection; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; + +public class FederationUser extends User { + + private static final long serialVersionUID = -2231762973730849416L; + + private ClaimCollection claims; + + public FederationUser(String username, String password, boolean enabled, boolean accountNonExpired, + boolean credentialsNonExpired, boolean accountNonLocked, + Collection<? extends GrantedAuthority> authorities) { + super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + } + + public FederationUser(String username, String password, + Collection<? extends GrantedAuthority> authorities, ClaimCollection claims) { + super(username, password, true, true, true, true, authorities); + this.claims = claims; + } + + public ClaimCollection getClaims() { + return this.claims; + } + + + + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/SpringFedizMessageSource.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/SpringFedizMessageSource.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/SpringFedizMessageSource.java new file mode 100644 index 0000000..976641a --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/SpringFedizMessageSource.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.fediz.spring; + +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.context.support.ResourceBundleMessageSource; + + +/** + * The default <code>MessageSource</code> used by Spring Security. + * <p>All Spring Security classes requiring messge localization will by default use this class. + * However, all such classes will also implement <code>MessageSourceAware</code> so that the application context can + * inject an alternative message source. Therefore this class is only used when the deployment environment has not + * specified an alternative message source.</p> + * + * @author Ben Alex + */ +public class SpringFedizMessageSource extends ResourceBundleMessageSource { + + public SpringFedizMessageSource() { + setBasename("org.apache.cxf.fediz.spring.messages"); + } + + + public static MessageSourceAccessor getAccessor() { + return new MessageSourceAccessor(new SpringFedizMessageSource()); + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/AbstractFederationUserDetailsService.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/AbstractFederationUserDetailsService.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/AbstractFederationUserDetailsService.java new file mode 100644 index 0000000..544ee18 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/AbstractFederationUserDetailsService.java @@ -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.spring.authentication; + +import org.apache.cxf.fediz.core.processor.FedizResponse; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; + +/** + * Abstract class to construct a new User object based on the provided FederationResponseAuthenticationToken. + */ +public abstract class AbstractFederationUserDetailsService + implements AuthenticationUserDetailsService<FederationResponseAuthenticationToken> { + + public final UserDetails loadUserDetails(final FederationResponseAuthenticationToken token) { + return loadUserDetails(token.getResponse()); + } + + /** + * Protected template method for construct a {@link org.springframework.security.core.userdetails.UserDetails} + * via the supplied FedizResponse + * + * @return the newly created UserDetails object. + */ + protected abstract UserDetails loadUserDetails(FedizResponse response); +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java new file mode 100644 index 0000000..1b986ea --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java @@ -0,0 +1,35 @@ +/** + * 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.spring.authentication; + +import org.springframework.security.core.AuthenticationException; + +/** + * To be called when a token has expired + */ +public class ExpiredTokenException extends AuthenticationException { + + private static final long serialVersionUID = 7639463618762010981L; + + public ExpiredTokenException(String errorMessage) { + super(errorMessage); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationProvider.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationProvider.java new file mode 100644 index 0000000..8b1a496 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationProvider.java @@ -0,0 +1,153 @@ +/** + * 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.spring.authentication; + +import org.apache.cxf.fediz.core.config.FedizContext; +import org.apache.cxf.fediz.core.processor.FedizProcessor; +import org.apache.cxf.fediz.core.processor.FedizProcessorFactory; +import org.apache.cxf.fediz.core.processor.FedizRequest; +import org.apache.cxf.fediz.core.processor.FedizResponse; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.apache.cxf.fediz.spring.SpringFedizMessageSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.security.authentication.AccountStatusUserDetailsChecker; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsChecker; +import org.springframework.util.Assert; + + +/** + * This {@link AuthenticationProvider} implements the integration with the Identity Provider + * based on the WS-Federation Passive Requestor Profile. + */ +public class FederationAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { + private static final Logger LOG = LoggerFactory.getLogger(FederationAuthenticationProvider.class); + + protected MessageSourceAccessor messages = SpringFedizMessageSource.getAccessor(); + + private AuthenticationUserDetailsService<FederationResponseAuthenticationToken> authenticationUserDetailsService; + private FederationConfig federationConfig; + + private final UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker(); + private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); + + public AuthenticationUserDetailsService<FederationResponseAuthenticationToken> + getAuthenticationUserDetailsService() { + return authenticationUserDetailsService; + } + + public void setAuthenticationUserDetailsService( + AuthenticationUserDetailsService<FederationResponseAuthenticationToken> authenticationUserDetailsService) { + this.authenticationUserDetailsService = authenticationUserDetailsService; + } + + public FederationConfig getFederationConfig() { + return federationConfig; + } + + public void setFederationConfig(FederationConfig federationConfig) { + this.federationConfig = federationConfig; + } + + + + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.authenticationUserDetailsService, "An authenticationUserDetailsService must be set"); + Assert.notNull(this.messages, "A message source must be set"); + Assert.notNull(this.federationConfig, "FederationConfig cannot be null."); + } + + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + if (!supports(authentication.getClass())) { + return null; + } + + if (!(authentication instanceof UsernamePasswordAuthenticationToken)) { + return null; + } + + // Ensure credentials are provided + if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) { + throw new BadCredentialsException(messages.getMessage("FederationAuthenticationProvider.noSignInRequest", + "Failed to get SignIn request")); + } + + FederationAuthenticationToken result = this.authenticateNow(authentication); + result.setDetails(authentication.getDetails()); + return result; + } + + private FederationAuthenticationToken authenticateNow(final Authentication authentication) + throws AuthenticationException { + try { + FedizRequest wfReq = (FedizRequest)authentication.getCredentials(); + + FedizContext fedContext = federationConfig.getFedizContext(); + FedizProcessor wfProc = + FedizProcessorFactory.newFedizProcessor(fedContext.getProtocol()); + FedizResponse wfRes = wfProc.processRequest(wfReq, fedContext); + + final UserDetails userDetails = loadUserByFederationResponse(wfRes); + userDetailsChecker.check(userDetails); + return new FederationAuthenticationToken(userDetails, authentication.getCredentials(), + authoritiesMapper.mapAuthorities(userDetails.getAuthorities()), userDetails, wfRes); + } catch (Exception e) { + LOG.error("Failed to validate SignIn request", e); + throw new BadCredentialsException(e.getMessage(), e); + } + } + + /** + * Template method for retrieving the UserDetails based on the federation response (wresult parameter). + * + * @param response The WS Federation response + * @return the UserDetails. + */ + protected UserDetails loadUserByFederationResponse(final FedizResponse response) { + final FederationResponseAuthenticationToken token = new FederationResponseAuthenticationToken(response); + return this.authenticationUserDetailsService.loadUserDetails(token); + } + + public void setMessageSource(final MessageSource messageSource) { + this.messages = new MessageSourceAccessor(messageSource); + } + + public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) { + this.authoritiesMapper = authoritiesMapper; + } + + public boolean supports(final Class<?> authentication) { + return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)) + || (FederationAuthenticationToken.class.isAssignableFrom(authentication)); + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationToken.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationToken.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationToken.java new file mode 100644 index 0000000..5ed8d57 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationAuthenticationToken.java @@ -0,0 +1,109 @@ +/** + * 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.spring.authentication; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.w3c.dom.Element; +import org.apache.cxf.fediz.core.ClaimCollection; +import org.apache.cxf.fediz.core.FedizPrincipal; +import org.apache.cxf.fediz.core.processor.FedizResponse; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; +import org.springframework.security.core.userdetails.UserDetails; + +/** + * Represents a successful WS-Federation based authentication. + */ +public class FederationAuthenticationToken extends AbstractAuthenticationToken + implements Serializable, FedizPrincipal { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + private final Object credentials; + private final Object principal; + private final UserDetails userDetails; + private final FedizResponse response; + private List<String> roles = Collections.emptyList(); + + + public FederationAuthenticationToken(final Object principal, final Object credentials, + final Collection<? extends GrantedAuthority> authorities, final UserDetails userDetails, + final FedizResponse response) { + super(authorities); + + if ((principal == null) || "".equals(principal) || (credentials == null) + || "".equals(credentials) || (authorities == null) || (userDetails == null) || (response == null)) { + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); + } + + this.principal = principal; + this.credentials = credentials; + this.userDetails = userDetails; + this.response = response; + setAuthenticated(true); + if (response.getRoles() != null) { + this.roles = response.getRoles(); + } + } + + public Object getCredentials() { + return this.credentials; + } + + public Object getPrincipal() { + return this.principal; + } + + public FedizResponse getResponse() { + return this.response; + } + + public UserDetails getUserDetails() { + return userDetails; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(super.toString()); + sb.append(" Response: ").append(this.response); + sb.append(" Credentials: ").append(this.credentials); + + return sb.toString(); + } + + @Override + public ClaimCollection getClaims() { + return new ClaimCollection(response.getClaims()); + } + + @Override + public Element getLoginToken() { + return response.getToken(); + } + + public List<String> getRoleClaims() { + return Collections.unmodifiableList(roles); + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationResponseAuthenticationToken.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationResponseAuthenticationToken.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationResponseAuthenticationToken.java new file mode 100644 index 0000000..c75dd09 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/FederationResponseAuthenticationToken.java @@ -0,0 +1,54 @@ +/** + * 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.spring.authentication; + +import java.util.ArrayList; + +import org.apache.cxf.fediz.core.processor.FedizResponse; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; + +public final class FederationResponseAuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + private final FedizResponse response; + + + public FederationResponseAuthenticationToken(final FedizResponse response) { + super(new ArrayList<GrantedAuthority>()); + + this.response = response; + } + + public Object getPrincipal() { + return this.response.getUsername(); + } + + public Object getCredentials() { + return this.response; + } + + public FedizResponse getResponse() { + return this.response; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/GrantedAuthoritiesUserDetailsFederationService.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/GrantedAuthoritiesUserDetailsFederationService.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/GrantedAuthoritiesUserDetailsFederationService.java new file mode 100644 index 0000000..fc8a511 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/authentication/GrantedAuthoritiesUserDetailsFederationService.java @@ -0,0 +1,65 @@ +/** + * 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.spring.authentication; + +import java.util.*; + +import org.apache.cxf.fediz.core.ClaimCollection; +import org.apache.cxf.fediz.core.processor.FedizResponse; +import org.apache.cxf.fediz.spring.FederationUser; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +/** + * This AuthenticationUserDetailsService implementation creates a FederationUser + * object based on the data in the provided FederationResponseAuthenticationToken. + */ +public class GrantedAuthoritiesUserDetailsFederationService + extends AbstractFederationUserDetailsService { + + private boolean convertToUpperCase = true; + + @Override + protected UserDetails loadUserDetails(FedizResponse response) { + + final List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); + + if (response.getRoles() != null) { + for (final String role : response.getRoles()) { + + grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + + (this.convertToUpperCase ? role.toUpperCase() : role))); + } + } + return new FederationUser(response.getUsername(), "N/A", + grantedAuthorities, new ClaimCollection(response.getClaims())); + + } + + + /** + * Converts the role value to uppercase value. + * + * @param convertToUpperCase true if it should convert, false otherwise. + */ + public void setConvertToUpperCase(final boolean convertToUpperCase) { + this.convertToUpperCase = convertToUpperCase; + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/FederationPreAuthenticatedProcessingFilter.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/FederationPreAuthenticatedProcessingFilter.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/FederationPreAuthenticatedProcessingFilter.java new file mode 100644 index 0000000..7322a62 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/FederationPreAuthenticatedProcessingFilter.java @@ -0,0 +1,72 @@ +/** + * 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.spring.preauth; + +import java.security.Principal; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.cxf.fediz.core.FedizPrincipal; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; + +/** + * This AbstractPreAuthenticatedProcessingFilter implementation is based on the + * J2EE container-based authentication mechanism. It will use the J2EE user + * principal name as the pre-authenticated principal and the WS-Federation signin request + * as the credentials. + */ +public class FederationPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter { + + private static final String SECURITY_TOKEN_ATTR = "org.apache.fediz.SECURITY_TOKEN"; + + /** + * Return the J2EE user name. + */ + protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpRequest) { + Principal principal = httpRequest.getUserPrincipal(); + if (logger.isDebugEnabled()) { + logger.debug("PreAuthenticated J2EE principal: " + + principal == null ? null : principal.getName()); + } + return principal; + } + + /** + * For J2EE container-based authentication there is no generic way to + * retrieve the credentials, as such this method returns a fixed dummy + * value. + */ + protected Object getPreAuthenticatedCredentials(HttpServletRequest httpRequest) { + Principal principal = httpRequest.getUserPrincipal() == null ? null : httpRequest.getUserPrincipal(); + if (principal instanceof FedizPrincipal) { + Object obj = httpRequest.getSession(false).getAttribute(SECURITY_TOKEN_ATTR); + if (obj != null) { + return obj; + } else { + logger.error("Session must contain Federation response"); + throw new IllegalStateException("Session must contain Federation response"); + } + } else { + logger.error("Principal must be instance of FedizPrincipal: " + principal); + throw new IllegalStateException("Principal must be instance of FedizPrincipal"); + } + //return "N/A"; + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService.java new file mode 100644 index 0000000..2551d0e --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/preauth/PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService.java @@ -0,0 +1,80 @@ +/** + * 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.spring.preauth; + +import java.util.*; + +import org.apache.cxf.fediz.core.ClaimCollection; +import org.apache.cxf.fediz.core.FedizPrincipal; +import org.apache.cxf.fediz.spring.FederationUser; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.GrantedAuthoritiesContainer; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; + +import org.springframework.util.Assert; + +/** + * <p> + * This AuthenticationUserDetailsService implementation creates a UserDetails + * object based solely on the information contained in the given + * PreAuthenticatedAuthenticationToken. The user name is set to the name as + * returned by PreAuthenticatedAuthenticationToken.getName(), the password is + * set to a fixed dummy value (it will not be used by the + * PreAuthenticatedAuthenticationProvider anyway), and the Granted Authorities + * are retrieved from the details object as returned by + * PreAuthenticatedAuthenticationToken.getDetails(). + * + * <p> + * The details object as returned by PreAuthenticatedAuthenticationToken.getDetails() must implement the + * {@link GrantedAuthoritiesContainer} interface for this implementation to work. + *l + */ +public class PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService + implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { + /** + * Get a UserDetails object based on the user name contained in the given + * token, and the GrantedAuthorities as returned by the + * GrantedAuthoritiesContainer implementation as returned by + * the token.getDetails() method. + */ + public final UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws AuthenticationException { + Assert.notNull(token.getDetails()); + Assert.isInstanceOf(GrantedAuthoritiesContainer.class, token.getDetails()); + Assert.isInstanceOf(FedizPrincipal.class, token.getPrincipal()); + Collection<? extends GrantedAuthority> authorities = + ((GrantedAuthoritiesContainer) token.getDetails()).getGrantedAuthorities(); + + return createuserDetails(token, authorities, ((FedizPrincipal)token.getPrincipal()).getClaims()); + } + + /** + * Creates the final <tt>UserDetails</tt> object. Can be overridden to customize the contents. + * + * @param token the authentication request token + * @param authorities the pre-authenticated authorities. + */ + protected UserDetails createuserDetails(Authentication token, + Collection<? extends GrantedAuthority> authorities, ClaimCollection claims) { + return new FederationUser(token.getName(), "N/A", authorities, claims); + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationEntryPoint.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationEntryPoint.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationEntryPoint.java new file mode 100644 index 0000000..d8b6611 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationEntryPoint.java @@ -0,0 +1,144 @@ +/** + * 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.spring.web; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.cxf.fediz.core.config.FedizContext; +import org.apache.cxf.fediz.core.exception.ProcessingException; +import org.apache.cxf.fediz.core.metadata.MetadataDocumentHandler; +import org.apache.cxf.fediz.core.processor.FedizProcessor; +import org.apache.cxf.fediz.core.processor.FedizProcessorFactory; +import org.apache.cxf.fediz.core.processor.RedirectionResponse; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.util.Assert; + + +/** + * Used by the <code>ExceptionTranslationFilter</code> to commence authentication via the + * WS-Federation protocol. + * <p> + * The user's browser will be redirected to the IDP. + * + */ +public class FederationAuthenticationEntryPoint implements AuthenticationEntryPoint, + InitializingBean, ApplicationContextAware { + + /** + * The key used to save the context of the request + */ + public static final String SAVED_CONTEXT = "SAVED_CONTEXT"; + + private static final Logger LOG = LoggerFactory.getLogger(FederationAuthenticationEntryPoint.class); + + private ApplicationContext appContext; + private FederationConfig federationConfig; + + public FederationConfig getFederationConfig() { + return federationConfig; + } + + public void setFederationConfig(FederationConfig federationConfig) { + this.federationConfig = federationConfig; + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.appContext, "ApplicationContext cannot be null."); + Assert.notNull(this.federationConfig, "FederationConfig cannot be null."); + } + + public final void commence(final HttpServletRequest servletRequest, final HttpServletResponse response, + final AuthenticationException authenticationException) throws IOException, ServletException { + + FedizContext fedContext = federationConfig.getFedizContext(); + LOG.debug("Federation context: {}", fedContext); + + // Check to see if it is a metadata request + MetadataDocumentHandler mdHandler = new MetadataDocumentHandler(fedContext); + if (mdHandler.canHandleRequest(servletRequest)) { + mdHandler.handleRequest(servletRequest, response); + return; + } + + String redirectUrl = null; + try { + FedizProcessor wfProc = + FedizProcessorFactory.newFedizProcessor(fedContext.getProtocol()); + RedirectionResponse redirectionResponse = + wfProc.createSignInRequest(servletRequest, fedContext); + redirectUrl = redirectionResponse.getRedirectionURL(); + + if (redirectUrl == null) { + LOG.warn("Failed to create SignInRequest. Redirect URL null"); + throw new ServletException("Failed to create SignInRequest. Redirect URL null"); + } + + Map<String, String> headers = redirectionResponse.getHeaders(); + if (!headers.isEmpty()) { + for (Entry<String, String> entry : headers.entrySet()) { + response.addHeader(entry.getKey(), entry.getValue()); + } + } + + HttpSession session = servletRequest.getSession(true); + session.setAttribute(SAVED_CONTEXT, redirectionResponse.getRequestState().getState()); + } catch (ProcessingException ex) { + LOG.warn("Failed to create SignInRequest", ex); + throw new ServletException("Failed to create SignInRequest: " + ex.getMessage()); + } + + preCommence(servletRequest, response); + if (LOG.isInfoEnabled()) { + LOG.info("Redirecting to IDP: " + redirectUrl); + } + response.sendRedirect(redirectUrl); + } + + /** + * Template method for you to do your own pre-processing before the redirect occurs. + * + * @param request the HttpServletRequest + * @param response the HttpServletResponse + */ + protected void preCommence(final HttpServletRequest request, final HttpServletResponse response) { + + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.appContext = applicationContext; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java new file mode 100644 index 0000000..8b98982 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java @@ -0,0 +1,103 @@ +/** + * 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.spring.web; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.cxf.fediz.core.config.FedizContext; +import org.apache.cxf.fediz.core.exception.ProcessingException; +import org.apache.cxf.fediz.core.processor.FedizProcessor; +import org.apache.cxf.fediz.core.processor.FedizProcessorFactory; +import org.apache.cxf.fediz.core.processor.RedirectionResponse; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.apache.cxf.fediz.spring.authentication.ExpiredTokenException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +/** + * A AuthenticationFailureHandler which will redirect a expired user (token) back to the IdP. + */ +public class FederationAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + + private static final Logger LOG = LoggerFactory.getLogger(FederationAuthenticationFailureHandler.class); + + private FederationConfig federationConfig; + + public FederationAuthenticationFailureHandler() { + super(); + } + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException { + + if (exception instanceof ExpiredTokenException) { + String redirectUrl = null; + try { + FedizContext fedContext = federationConfig.getFedizContext(); + FedizProcessor wfProc = + FedizProcessorFactory.newFedizProcessor(fedContext.getProtocol()); + RedirectionResponse redirectionResponse = + wfProc.createSignInRequest(request, fedContext); + redirectUrl = redirectionResponse.getRedirectionURL(); + + if (redirectUrl == null) { + LOG.warn("Failed to create SignInRequest. Redirect URL null"); + throw new ServletException("Failed to create SignInRequest. Redirect URL null"); + } + + Map<String, String> headers = redirectionResponse.getHeaders(); + if (!headers.isEmpty()) { + for (Entry<String, String> entry : headers.entrySet()) { + response.addHeader(entry.getKey(), entry.getValue()); + } + } + + } catch (ProcessingException ex) { + LOG.warn("Failed to create SignInRequest", ex); + throw new ServletException("Failed to create SignInRequest: " + ex.getMessage()); + } + + if (LOG.isInfoEnabled()) { + LOG.info("Redirecting to IDP: " + redirectUrl); + } + response.sendRedirect(redirectUrl); + } + + super.onAuthenticationFailure(request, response, exception); + } + + public FederationConfig getFederationConfig() { + return federationConfig; + } + + public void setFederationConfig(FederationConfig fedConfig) { + this.federationConfig = fedConfig; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java new file mode 100644 index 0000000..485ca38 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java @@ -0,0 +1,161 @@ +/** + * 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.spring.web; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Date; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.cxf.fediz.core.FederationConstants; +import org.apache.cxf.fediz.core.SAMLSSOConstants; +import org.apache.cxf.fediz.core.processor.FedizRequest; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.apache.cxf.fediz.spring.authentication.ExpiredTokenException; +import org.apache.cxf.fediz.spring.authentication.FederationAuthenticationToken; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + + +public class FederationAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + + private FederationConfig federationConfig; + + public FederationAuthenticationFilter() { + super("/j_spring_fediz_security_check"); + setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler()); + } + + @Override + public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) + throws AuthenticationException, IOException { + + if (isTokenExpired()) { + throw new ExpiredTokenException("Token is expired"); + } + + verifySavedState(request); + + String wa = request.getParameter(FederationConstants.PARAM_ACTION); + String responseToken = getResponseToken(request); + + FedizRequest wfReq = new FedizRequest(); + wfReq.setAction(wa); + wfReq.setResponseToken(responseToken); + wfReq.setState(getState(request)); + wfReq.setRequest(request); + + X509Certificate certs[] = + (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate"); + wfReq.setCerts(certs); + + final UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(null, wfReq); + + authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); + + return this.getAuthenticationManager().authenticate(authRequest); + } + + private boolean isTokenExpired() { + SecurityContext context = SecurityContextHolder.getContext(); + boolean detectExpiredTokens = + federationConfig != null && federationConfig.getFedizContext().isDetectExpiredTokens(); + if (context != null && detectExpiredTokens) { + Authentication authentication = context.getAuthentication(); + if (authentication instanceof FederationAuthenticationToken) { + Date tokenExpires = + ((FederationAuthenticationToken)authentication).getResponse().getTokenExpires(); + if (tokenExpires == null) { + return false; + } + + Date currentTime = new Date(); + if (currentTime.after(tokenExpires)) { + return true; + } + } + } + + return false; + } + + private String getResponseToken(ServletRequest request) { + if (request.getParameter(FederationConstants.PARAM_RESULT) != null) { + return request.getParameter(FederationConstants.PARAM_RESULT); + } else if (request.getParameter(SAMLSSOConstants.SAML_RESPONSE) != null) { + return request.getParameter(SAMLSSOConstants.SAML_RESPONSE); + } + + return null; + } + + private String getState(ServletRequest request) { + if (request.getParameter(FederationConstants.PARAM_CONTEXT) != null) { + return request.getParameter(FederationConstants.PARAM_CONTEXT); + } else if (request.getParameter(SAMLSSOConstants.RELAY_STATE) != null) { + return request.getParameter(SAMLSSOConstants.RELAY_STATE); + } + + return null; + } + + private void verifySavedState(HttpServletRequest request) { + HttpSession session = request.getSession(false); + if (session != null) { + String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT); + String state = getState(request); + if (savedContext != null && !savedContext.equals(state)) { + logger.warn("The received state does not match the state saved in the context"); + throw new BadCredentialsException("The received state does not match the state saved in the context"); + } + } + } + + /** + * + */ + @Override + protected boolean requiresAuthentication(final HttpServletRequest request, final HttpServletResponse response) { + boolean result = isTokenExpired() || super.requiresAuthentication(request, response); + if (logger.isDebugEnabled()) { + logger.debug("requiresAuthentication = " + result); + } + return result; + } + + public FederationConfig getFederationConfig() { + return federationConfig; + } + + public void setFederationConfig(FederationConfig fedConfig) { + this.federationConfig = fedConfig; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutFilter.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutFilter.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutFilter.java new file mode 100644 index 0000000..d33607d --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutFilter.java @@ -0,0 +1,71 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.spring.web; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.cxf.fediz.core.FederationConstants; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.springframework.beans.factory.annotation.Required; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +public class FederationLogoutFilter extends LogoutFilter { + + private FederationConfig federationConfig; + private String logoutUrl; + + public FederationLogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers) { + super(logoutSuccessHandler, handlers); + } + + @Required + public void setFederationConfig(FederationConfig federationConfig) { + this.federationConfig = federationConfig; + } + + @Override + protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) { + String wa = request.getParameter(FederationConstants.PARAM_ACTION); + if (FederationConstants.ACTION_SIGNOUT.equals(wa) || FederationConstants.ACTION_SIGNOUT_CLEANUP.equals(wa)) { + // Default WS-Federation logout action + return true; + } + + if (this.logoutUrl == null) { + String contextName = request.getContextPath(); + if (contextName == null || contextName.isEmpty()) { + contextName = "/"; + } + this.logoutUrl = federationConfig.getFedizContext(contextName).getLogoutURL(); + } + if (this.logoutUrl != null && !this.logoutUrl.isEmpty()) { + super.setLogoutRequestMatcher(new AntPathRequestMatcher(logoutUrl)); + return super.requiresLogout(request, response); + } + return false; + } + + protected String getFilterProcessesUrl() { + return this.logoutUrl; + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutSuccessHandler.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutSuccessHandler.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutSuccessHandler.java new file mode 100644 index 0000000..6e01592 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationLogoutSuccessHandler.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 org.apache.cxf.fediz.spring.web; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.cxf.fediz.core.config.FedizContext; +import org.apache.cxf.fediz.core.exception.ProcessingException; +import org.apache.cxf.fediz.core.processor.FedizProcessor; +import org.apache.cxf.fediz.core.processor.FedizProcessorFactory; +import org.apache.cxf.fediz.core.processor.RedirectionResponse; +import org.apache.cxf.fediz.spring.FederationConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Required; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +public class FederationLogoutSuccessHandler implements LogoutSuccessHandler { + + private static final Logger LOG = LoggerFactory.getLogger(FederationLogoutSuccessHandler.class); + + private FederationConfig federationConfig; + + @Required + public void setFederationConfig(FederationConfig federationConfig) { + this.federationConfig = federationConfig; + } + + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + String contextName = request.getContextPath(); + if (contextName == null || contextName.isEmpty()) { + contextName = "/"; + } + FedizContext fedCtx = federationConfig.getFedizContext(contextName); + try { + FedizProcessor wfProc = + FedizProcessorFactory.newFedizProcessor(fedCtx.getProtocol()); + RedirectionResponse redirectionResponse = + wfProc.createSignOutRequest(request, null, fedCtx); //TODO + String redirectURL = redirectionResponse.getRedirectionURL(); + if (redirectURL != null) { + Map<String, String> headers = redirectionResponse.getHeaders(); + if (!headers.isEmpty()) { + for (Entry<String, String> entry : headers.entrySet()) { + response.addHeader(entry.getKey(), entry.getValue()); + } + } + + response.sendRedirect(redirectURL); + } else { + LOG.warn("Failed to create SignOutRequest."); + response.sendError( + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to create SignOutRequest."); + } + } catch (ProcessingException ex) { + LOG.warn("Failed to create SignOutRequest: " + ex.getMessage()); + response.sendError( + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to create SignOutRequest."); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationSignOutCleanupFilter.java ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationSignOutCleanupFilter.java b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationSignOutCleanupFilter.java new file mode 100644 index 0000000..e242944 --- /dev/null +++ b/plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationSignOutCleanupFilter.java @@ -0,0 +1,67 @@ +/** + * 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.spring.web; + +import java.io.IOException; +import java.io.InputStream; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.apache.cxf.fediz.core.FederationConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.filter.GenericFilterBean; + +public class FederationSignOutCleanupFilter extends GenericFilterBean { + + private static final Logger LOG = LoggerFactory.getLogger(FederationSignOutCleanupFilter.class); + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + String wa = request.getParameter(FederationConstants.PARAM_ACTION); + if (FederationConstants.ACTION_SIGNOUT_CLEANUP.equals(wa)) { + if (request instanceof HttpServletRequest) { + ((HttpServletRequest)request).getSession().invalidate(); + } + + final ServletOutputStream responseOutputStream = response.getOutputStream(); + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("logout.jpg"); + if (inputStream == null) { + LOG.warn("Could not write logout.jpg"); + return; + } + int read = 0; + byte[] buf = new byte[1024]; + while ((read = inputStream.read(buf)) != -1) { + responseOutputStream.write(buf, 0, read); + } + inputStream.close(); + responseOutputStream.flush(); + } else { + chain.doFilter(request, response); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/plugins/spring3/src/main/resources/org/apache/cxf/fediz/spring/messages.properties ---------------------------------------------------------------------- diff --git a/plugins/spring3/src/main/resources/org/apache/cxf/fediz/spring/messages.properties b/plugins/spring3/src/main/resources/org/apache/cxf/fediz/spring/messages.properties new file mode 100644 index 0000000..8d3d4bb --- /dev/null +++ b/plugins/spring3/src/main/resources/org/apache/cxf/fediz/spring/messages.properties @@ -0,0 +1,2 @@ +FederationAuthenticationProvider.incorrectKey=The presented FederationAuthenticationToken does not contain the expected key +FederationAuthenticationProvider.noSignInRequest=Failed to get SignIn request http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5f752297/systests/spring/pom.xml ---------------------------------------------------------------------- diff --git a/systests/spring/pom.xml b/systests/spring/pom.xml index 5ff3e98..d5b56f2 100644 --- a/systests/spring/pom.xml +++ b/systests/spring/pom.xml @@ -165,6 +165,14 @@ <outputDirectory>target/tomcat/rp/webapps/fediz-systests-webapps-spring2</outputDirectory> </artifactItem> <artifactItem> + <groupId>org.apache.cxf.fediz.systests.webapps</groupId> + <artifactId>fediz-systests-webapps-spring3</artifactId> + <version>${project.version}</version> + <type>war</type> + <overWrite>true</overWrite> + <outputDirectory>target/tomcat/rp/webapps/fediz-systests-webapps-spring3</outputDirectory> + </artifactItem> + <artifactItem> <groupId>org.apache.cxf.fediz.systests</groupId> <artifactId>fediz-systests-tests</artifactId> <version>${project.version}</version>
