Repository: cxf-fediz
Updated Branches:
  refs/heads/master 91e97c794 -> cc36307d5


[FEDIZ-106] - Spring plugin support for configurable token validation - part I


Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/cc36307d
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/cc36307d
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/cc36307d

Branch: refs/heads/master
Commit: cc36307d58bb4d7d38c5f9c3e1baf52d093b0ae6
Parents: 91e97c7
Author: Colm O hEigeartaigh <cohei...@apache.org>
Authored: Thu Sep 3 14:38:56 2015 +0100
Committer: Colm O hEigeartaigh <cohei...@apache.org>
Committed: Thu Sep 3 14:38:56 2015 +0100

----------------------------------------------------------------------
 .../authentication/ExpiredTokenException.java   |  35 +++++++
 .../FederationAuthenticationFailureHandler.java | 102 +++++++++++++++++++
 .../web/FederationAuthenticationFilter.java     |  53 +++++++++-
 .../WEB-INF/applicationContext-security.xml     |   5 +-
 4 files changed, 190 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/cc36307d/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java
----------------------------------------------------------------------
diff --git 
a/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java
 
b/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/authentication/ExpiredTokenException.java
new file mode 100644
index 0000000..7e7b0f8
--- /dev/null
+++ 
b/plugins/spring/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/cc36307d/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java
----------------------------------------------------------------------
diff --git 
a/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java
 
b/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java
new file mode 100644
index 0000000..0b9069a
--- /dev/null
+++ 
b/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFailureHandler.java
@@ -0,0 +1,102 @@
+/**
+ * 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 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 (String headerName : headers.keySet()) {
+                        response.addHeader(headerName, 
headers.get(headerName));
+                    }
+                }
+                
+            } 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/cc36307d/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java
----------------------------------------------------------------------
diff --git 
a/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java
 
b/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java
index 906246b..1c13f18 100644
--- 
a/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java
+++ 
b/plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java
@@ -21,6 +21,7 @@ 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;
@@ -29,15 +30,22 @@ import javax.servlet.http.HttpServletResponse;
 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.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());
@@ -47,9 +55,18 @@ public class FederationAuthenticationFilter extends 
AbstractAuthenticationProces
     public Authentication attemptAuthentication(final HttpServletRequest 
request, final HttpServletResponse response)
         throws AuthenticationException, IOException {
 
-        
+        SecurityContext context = SecurityContextHolder.getContext();
+        if (context != null) {
+            Authentication authentication = context.getAuthentication();
+            if (authentication instanceof FederationAuthenticationToken) {
+                // If we reach this point then the token must be expired
+                throw new ExpiredTokenException("Token is expired");
+            }
+        }
+ 
         String wa = request.getParameter(FederationConstants.PARAM_ACTION);
         String responseToken = getResponseToken(request);
+        
         FedizRequest wfReq = new FedizRequest();
         wfReq.setAction(wa);
         wfReq.setResponseToken(responseToken);
@@ -66,6 +83,29 @@ public class FederationAuthenticationFilter extends 
AbstractAuthenticationProces
 
         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) {
@@ -82,13 +122,20 @@ public class FederationAuthenticationFilter extends 
AbstractAuthenticationProces
      */
     @Override
     protected boolean requiresAuthentication(final HttpServletRequest request, 
final HttpServletResponse response) {
-        final boolean result = 
request.getRequestURI().contains(getFilterProcessesUrl());
-        
+        boolean result = 
request.getRequestURI().contains(getFilterProcessesUrl());
+        result |= isTokenExpired();
         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/cc36307d/systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml
----------------------------------------------------------------------
diff --git 
a/systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml
 
b/systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml
index b2c1a08..27dc5f6 100644
--- 
a/systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml
+++ 
b/systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml
@@ -55,10 +55,11 @@ http://www.springframework.org/schema/context 
http://www.springframework.org/sch
  
     <bean id="federationFilter"
         class="org.apache.cxf.fediz.spring.web.FederationAuthenticationFilter"
-        p:authenticationManager-ref="authManager">
+        p:authenticationManager-ref="authManager"
+        p:federationConfig-ref="fedizConfig">
 
         <property name="authenticationFailureHandler">
-            <bean 
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
 />
+            <bean 
class="org.apache.cxf.fediz.spring.web.FederationAuthenticationFailureHandler" 
p:federationConfig-ref="fedizConfig" />
         </property>
     </bean>
     

Reply via email to