Author: owulff
Date: Tue Jun  5 21:48:37 2012
New Revision: 1346619

URL: http://svn.apache.org/viewvc?rev=1346619&view=rev
Log:
Exception handling improved and new testcases added

Added:
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/exception/ProcessingException.java
Modified:
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessor.java
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessorImpl.java
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidator.java
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorResponse.java
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FederationProtocol.java
    
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
    
cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
    
cxf/fediz/trunk/plugins/tomcat/src/main/java/org/apache/cxf/fediz/tomcat/FederationAuthenticator.java

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessor.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessor.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessor.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessor.java
 Tue Jun  5 21:48:37 2012
@@ -22,11 +22,12 @@ package org.apache.cxf.fediz.core;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.cxf.fediz.core.config.FederationContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
 
 public interface FederationProcessor {
 
-    FederationResponse processRequest(FederationRequest request, 
FederationContext config);
+    FederationResponse processRequest(FederationRequest request, 
FederationContext config) throws ProcessingException;
     
-    String createSignInRequest(HttpServletRequest request, FederationContext 
config);
+    String createSignInRequest(HttpServletRequest request, FederationContext 
config) throws ProcessingException;
 
 }

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessorImpl.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessorImpl.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessorImpl.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/FederationProcessorImpl.java
 Tue Jun  5 21:48:37 2012
@@ -20,7 +20,6 @@
 package org.apache.cxf.fediz.core;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.text.DateFormat;
@@ -31,14 +30,14 @@ import java.util.List;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.ParserConfigurationException;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
 
 import org.apache.cxf.fediz.core.config.FederationContext;
 import org.apache.cxf.fediz.core.config.FederationProtocol;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
 import org.apache.cxf.fediz.core.spi.HomeRealmCallback;
 import org.apache.cxf.fediz.core.spi.IDPCallback;
 import org.apache.cxf.fediz.core.spi.WAuthCallback;
@@ -62,17 +61,22 @@ public class FederationProcessorImpl imp
 
     @Override
     public FederationResponse processRequest(FederationRequest request,
-                                             FederationContext config) {
+                                             FederationContext config)
+        throws ProcessingException {
         FederationResponse response = null;
-        if (request.getWa().equals(FederationConstants.ACTION_SIGNIN)) {
+        if (FederationConstants.ACTION_SIGNIN.equals(request.getWa())) {
             response = this.processSignInRequest(request, config);
+        } else {
+            LOG.error("Invalid action '" + request.getWa() + "'");
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
         return response;
     }
 
     protected FederationResponse processSignInRequest(
-            FederationRequest request, FederationContext config) {
-
+            FederationRequest request, FederationContext config)
+        throws ProcessingException {
+        
         byte[] wresult = request.getWresult().getBytes();
 
         Document doc = null;
@@ -81,23 +85,17 @@ public class FederationProcessorImpl imp
             doc = DOMUtils.readXml(new ByteArrayInputStream(wresult));
             el = doc.getDocumentElement();
 
-        } catch (SAXException e) {
-            e.printStackTrace();
-            return null;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        } catch (ParserConfigurationException e) {
-            e.printStackTrace();
-            return null;
+        } catch (Exception e) {
+            LOG.warn("Failed to parse wresult: " + e.getMessage());
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
 
         if 
("RequestSecurityTokenResponseCollection".equals(el.getLocalName())) {
             el = DOMUtils.getFirstElement(el);
         }
         if (!"RequestSecurityTokenResponse".equals(el.getLocalName())) {
-            throw new RuntimeException("Unexpected element "
-                    + el.getLocalName());
+            LOG.warn("Unexpected root element of wresult: '" + 
el.getLocalName() + "'");
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
         el = DOMUtils.getFirstElement(el);
         Element rst = null;
@@ -119,15 +117,15 @@ public class FederationProcessorImpl imp
             el = DOMUtils.getNextElement(el);
         }
         if (LOG.isDebugEnabled()) {
-            LOG.debug("RST: " + rst.toString());
+            LOG.debug("RST: " + ((rst != null) ? rst.toString() : "null"));
             LOG.debug("Lifetime: "
                     + ((lifetimeElem != null) ? lifetimeElem.toString()
                             : "null"));
             LOG.debug("Tokentype: " + ((tt != null) ? tt.toString() : "null"));
         }
         if (rst == null) {
-            LOG.info("RST is null");
-            throw new RuntimeException("RST is null");
+            LOG.warn("RequestedSecurityToken element not found in wresult");
+            throw new ProcessingException(TYPE.BAD_REQUEST);
         }
         LifeTime lifeTime = null;
         if (lifetimeElem != null) {
@@ -145,9 +143,6 @@ public class FederationProcessorImpl imp
             }
         }
 
-        // [TODO] Exception: TokenExpiredException, TokenInvalidException, 
TokenCachedException
-        // throw new FedizRuntimeException("Error in providing a token", ex, 
FedizRuntimeException.TOKEN_EXPIRED);
-        
         TokenValidatorResponse validatorResponse = null;
         List<TokenValidator> validators = 
((FederationProtocol)config.getProtocol()).getTokenValidators();
         for (TokenValidator validator : validators) {
@@ -160,11 +155,16 @@ public class FederationProcessorImpl imp
             if (canHandle) {
                 try {
                     validatorResponse = validator.validateAndProcessToken(rst, 
config);
-                } catch (RuntimeException ex) {
-                    LOG.warn("Failed to validate token", ex);
+                } catch (ProcessingException ex) {
                     throw ex;
+                } catch (Exception ex) {
+                    LOG.warn("Failed to validate token", ex);
+                    throw new ProcessingException(TYPE.TOKEN_INVALID);
                 }
                 break;
+            } else {
+                LOG.warn("No security token validator found for '" + tt + "'");
+                throw new ProcessingException(TYPE.BAD_REQUEST);
             }
         }
 
@@ -173,7 +173,6 @@ public class FederationProcessorImpl imp
                 && config.isDetectReplayedTokens()) {
             // Check whether token has already been processed once, prevent
             // replay attack
-
             if 
(config.getTokenReplayCache().getId(validatorResponse.getUniqueTokenId()) == 
null) {
                 // not cached
                 Date expires = null;
@@ -190,10 +189,9 @@ public class FederationProcessorImpl imp
                     
config.getTokenReplayCache().putId(validatorResponse.getUniqueTokenId());
                 }
             } else {
-                LOG.error("Replay attack with token id: "
-                        + validatorResponse.getUniqueTokenId());
-                throw new RuntimeException("Replay attack with token id: "
-                        + validatorResponse.getUniqueTokenId());
+                LOG.error("Replay attack with token id: " + 
validatorResponse.getUniqueTokenId());
+                throw new ProcessingException("Replay attack with token id: "
+                        + validatorResponse.getUniqueTokenId(), 
TYPE.TOKEN_REPLAY);
             }
         }
 
@@ -208,7 +206,7 @@ public class FederationProcessorImpl imp
         return fedResponse;
     }
 
-    private LifeTime processLifeTime(Element lifetimeElem) {
+    private LifeTime processLifeTime(Element lifetimeElem) throws 
ProcessingException {
         try {
             Element createdElem = DOMUtils.getFirstChildWithName(lifetimeElem,
                     WSConstants.WSU_NS, WSConstants.CREATED_LN);
@@ -223,9 +221,9 @@ public class FederationProcessorImpl imp
             return new LifeTime(created, expires);
 
         } catch (ParseException e) {
-            e.printStackTrace();
+            LOG.error("Failed to parse lifetime element in wresult: " + 
e.getMessage());
+            throw new ProcessingException(TYPE.BAD_REQUEST);
         }
-        return null;
     }
 
     public class LifeTime {
@@ -249,7 +247,8 @@ public class FederationProcessorImpl imp
     }
 
     @Override
-    public String createSignInRequest(HttpServletRequest request, 
FederationContext config) {
+    public String createSignInRequest(HttpServletRequest request, 
FederationContext config)
+        throws ProcessingException {
 
         String redirectURL = null;
         try {
@@ -351,7 +350,7 @@ public class FederationProcessorImpl imp
             redirectURL = redirectURL + "?" + sb.toString();
         } catch (Exception ex) {
             LOG.error("Failed to create SignInRequest", ex);
-            return null;
+            throw new ProcessingException("Failed to create SignInRequest");
         }
         // [TODO] Current time, wct
 

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidator.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidator.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidator.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidator.java
 Tue Jun  5 21:48:37 2012
@@ -21,6 +21,7 @@ package org.apache.cxf.fediz.core;
 
 import org.w3c.dom.Element;
 import org.apache.cxf.fediz.core.config.FederationContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
 
 public interface TokenValidator {
 
@@ -40,6 +41,7 @@ public interface TokenValidator {
 
     /**
      * Validate a Token using the given Element and Configuration.
+     * @throws ProcessingException 
      */
-    TokenValidatorResponse validateAndProcessToken(Element token, 
FederationContext config);
+    TokenValidatorResponse validateAndProcessToken(Element token, 
FederationContext config) throws ProcessingException;
 }

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorResponse.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorResponse.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorResponse.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/TokenValidatorResponse.java
 Tue Jun  5 21:48:37 2012
@@ -64,7 +64,6 @@ public class TokenValidatorResponse {
         return claims;
     }
 
-
     public Date getExpires() {
         return expires;
     }

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FederationProtocol.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FederationProtocol.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FederationProtocol.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FederationProtocol.java
 Tue Jun  5 21:48:37 2012
@@ -55,7 +55,7 @@ public class FederationProtocol extends 
                     obj = 
Thread.currentThread().getContextClassLoader().loadClass(validatorClassname).newInstance();
                 } catch (Exception ex) {
                     LOG.error("Failed to instantiate TokenValidator 
implementation class: '"
-                              + validatorClassname + "'", ex);
+                              + validatorClassname + "'\n" + 
ex.getClass().getCanonicalName() + ": " + ex.getMessage());
                 }
                 if (obj instanceof TokenValidator) {
                     validators.add((TokenValidator)obj);

Added: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/exception/ProcessingException.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/exception/ProcessingException.java?rev=1346619&view=auto
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/exception/ProcessingException.java
 (added)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/exception/ProcessingException.java
 Tue Jun  5 21:48:37 2012
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.fediz.core.exception;
+
+public class ProcessingException extends Exception {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    
+    public enum TYPE {
+        TOKEN_EXPIRED,
+        TOKEN_REPLAY,
+        BAD_REQUEST,
+        INVALID_REQUEST,
+        ISSUER_NOT_TRUSTED,
+        TOKEN_INVALID,
+        TOKEN_NO_SIGNATURE
+    }
+    
+    /**
+     * A map of Fault Code to Fault Strings
+     */
+    private static final java.util.Map<TYPE, String> TYPE_MAP = 
+            new java.util.HashMap<TYPE, String>();
+    
+    static {
+        TYPE_MAP.put(TYPE.BAD_REQUEST, "The specified request is not 
understood");
+        TYPE_MAP.put(TYPE.INVALID_REQUEST, "The request was invalid or 
malformed");
+        TYPE_MAP.put(TYPE.TOKEN_REPLAY, "Security token already used 
(replay)");
+        TYPE_MAP.put(TYPE.TOKEN_EXPIRED, "Security token expired");
+        TYPE_MAP.put(TYPE.ISSUER_NOT_TRUSTED, "Security token issuer not 
trusted");
+        TYPE_MAP.put(TYPE.TOKEN_INVALID, "Security token has been revoked");
+        TYPE_MAP.put(TYPE.TOKEN_NO_SIGNATURE, "Security token has no 
signature");
+    }
+    
+    private TYPE type;
+    
+    
+    public ProcessingException(String message) {
+        super(message);
+    }
+    
+    public ProcessingException(String message, TYPE type) {
+        super(message);
+        this.type = type;
+    }
+    
+    public ProcessingException(TYPE type) {
+        this.type = type;
+    }
+    
+    public ProcessingException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    public ProcessingException(String message, Throwable e, TYPE type) {
+        super(message, e);
+        this.type = type;
+    }
+    
+    public void setType(TYPE type) {
+        this.type = type;
+    }
+    
+    public TYPE getType() {
+        return type;
+    }
+    
+    @Override
+    public String getMessage() {
+        if (type != null && TYPE_MAP.get(type) != null) {
+            return TYPE_MAP.get(type);
+        }
+        return super.getMessage();
+    }
+
+}

Modified: 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
 Tue Jun  5 21:48:37 2012
@@ -39,6 +39,8 @@ import org.apache.cxf.fediz.core.config.
 import org.apache.cxf.fediz.core.config.FederationProtocol;
 import org.apache.cxf.fediz.core.config.TrustManager;
 import org.apache.cxf.fediz.core.config.TrustedIssuer;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
 import org.apache.cxf.fediz.core.saml.SamlAssertionValidator.TRUST_TYPE;
 
 import org.apache.ws.security.SAMLTokenPrincipal;
@@ -81,7 +83,7 @@ public class SAMLTokenValidator implemen
     }
     
     public TokenValidatorResponse validateAndProcessToken(Element token,
-            FederationContext config) {
+            FederationContext config) throws ProcessingException {
 
         try {          
             RequestData requestData = new RequestData();
@@ -93,8 +95,8 @@ public class SAMLTokenValidator implemen
 
             AssertionWrapper assertion = new AssertionWrapper(token);
             if (!assertion.isSigned()) {
-                throw new RuntimeException(
-                        "The received assertion is not signed, and therefore 
not trusted");
+                LOG.warn("Assertion is not signed");
+                throw new ProcessingException(TYPE.TOKEN_NO_SIGNATURE);
             }
             // Verify the signature
             assertion.verifySignature(requestData,
@@ -152,8 +154,15 @@ public class SAMLTokenValidator implemen
             }
             
             if (!trusted) {
-                throw new RuntimeException("Issuer '" + assertionIssuer
-                        + "' not trusted");
+                // Condition already checked in SamlAssertionValidator
+                // Minor performance impact on untrusted and expired tokens
+                if (!isConditionValid(assertion, 
config.getMaximumClockSkew().intValue())) {
+                    LOG.warn("Security token expired");
+                    throw new ProcessingException(TYPE.TOKEN_EXPIRED);
+                } else {
+                    LOG.warn("Issuer '" + assertionIssuer + "' not trusted");
+                    throw new ProcessingException(TYPE.ISSUER_NOT_TRUSTED);
+                }
             }
 
             String audience = null;
@@ -187,7 +196,8 @@ public class SAMLTokenValidator implemen
                             List<String> values = (List<String>)oValue;
                             roles = Collections.unmodifiableList(values);
                         } else {
-                            throw new IllegalStateException("Invalid value 
type of Claim value");
+                            LOG.error("Unsupported value type of Claim value");
+                            throw new IllegalStateException("Unsupported value 
type of Claim value");
                         }
                         claims.remove(c);
                         break;
@@ -205,8 +215,8 @@ public class SAMLTokenValidator implemen
             return response;
 
         } catch (WSSecurityException ex) {
-            // [TODO] proper exception handling
-            throw new RuntimeException(ex);
+            LOG.error("Security token validation failed", ex);
+            throw new ProcessingException(TYPE.TOKEN_INVALID);
         }
     }
 
@@ -323,7 +333,8 @@ public class SAMLTokenValidator implemen
                 values.addAll(valueList);
                 t.setValue(values);
             } else {
-                throw new IllegalStateException("Invalid value type of Claim 
value");
+                LOG.error("Unsupported value type of Claim value");
+                throw new IllegalStateException("Unsupported value type of 
Claim value");
             }
         } else {
             if (valueList.size() == 1) {
@@ -386,5 +397,38 @@ public class SAMLTokenValidator implemen
         }
         return validTill.toDate();
     }
+    
+    /**
+     * Check the Conditions of the Assertion.
+     */
+    protected boolean isConditionValid(AssertionWrapper assertion, int 
maxClockSkew) throws WSSecurityException {
+        DateTime validFrom = null;
+        DateTime validTill = null;
+        if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)
+            && assertion.getSaml2().getConditions() != null) {
+            validFrom = assertion.getSaml2().getConditions().getNotBefore();
+            validTill = assertion.getSaml2().getConditions().getNotOnOrAfter();
+        } else if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_11)
+            && assertion.getSaml1().getConditions() != null) {
+            validFrom = assertion.getSaml1().getConditions().getNotBefore();
+            validTill = assertion.getSaml1().getConditions().getNotOnOrAfter();
+        }
+        
+        if (validFrom != null) {
+            DateTime currentTime = new DateTime();
+            currentTime = currentTime.plusSeconds(maxClockSkew);
+            if (validFrom.isAfter(currentTime)) {
+                LOG.debug("SAML Token condition (Not Before) not met");
+                return false;
+            }
+        }
+
+        if (validTill != null && validTill.isBeforeNow()) {
+            LOG.debug("SAML Token condition (Not On Or After) not met");
+            return false;
+        }
+        return true;
+    }
+    
 
 }

Modified: 
cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
 (original)
+++ 
cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
 Tue Jun  5 21:48:37 2012
@@ -40,6 +40,8 @@ import org.apache.cxf.fediz.core.Abstrac
 import org.apache.cxf.fediz.core.config.FederationConfigurator;
 import org.apache.cxf.fediz.core.config.FederationContext;
 import org.apache.cxf.fediz.core.config.FederationProtocol;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
 import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
@@ -104,6 +106,80 @@ public class FederationProcessorTest {
         }
     }
 
+    
+    /**
+     * Validate RSTR without RequestedSecurityToken element
+     */
+    @org.junit.Test
+    public void validateRSTRWithoutToken() throws Exception {
+        Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+        
+        FederationRequest wfReq = new FederationRequest();
+        wfReq.setWa(FederationConstants.ACTION_SIGNIN);
+        wfReq.setWresult(DOM2Writer.nodeToString(doc));
+        
+        configurator = null;
+        FederationContext config = 
getFederationConfigurator().getFederationContext("ROOT");
+
+        FederationProcessor wfProc = new FederationProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            fail("Failure expected on missing security token in RSTR");
+        } catch (ProcessingException ex) {
+            if (!TYPE.BAD_REQUEST.equals(ex.getType())) {
+                fail("Expected ProcessingException with BAD_REQUEST type");
+            }
+        }
+    }
+    
+    /**
+     * Validate FederationRequest with unknown action
+     */
+    @org.junit.Test
+    public void validateRequestUnknownAction() throws Exception {
+        Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+        
+        FederationRequest wfReq = new FederationRequest();
+        wfReq.setWa("gugus");
+        wfReq.setWresult(DOM2Writer.nodeToString(doc));
+        
+        configurator = null;
+        FederationContext config = 
getFederationConfigurator().getFederationContext("ROOT");
+
+        FederationProcessor wfProc = new FederationProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            fail("Failure expected due to invalid action");
+        } catch (ProcessingException ex) {
+            if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+                fail("Expected ProcessingException with INVALID_REQUEST type");
+            }
+        }
+    }
+    
+    /**
+     *Validate FederationRequest with invalid RSTR/wresult
+     */
+    @org.junit.Test
+    public void validateSignInInvalidWResult() throws Exception {
+        FederationRequest wfReq = new FederationRequest();
+        wfReq.setWa(FederationConstants.ACTION_SIGNIN);
+        wfReq.setWresult("gugus");
+        
+        configurator = null;
+        FederationContext config = 
getFederationConfigurator().getFederationContext("ROOT");
+
+        FederationProcessor wfProc = new FederationProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            fail("Failure expected due to invalid wresult");
+        } catch (ProcessingException ex) {
+            if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+                fail("Expected ProcessingException with INVALID_REQUEST type");
+            }
+        }
+    }
+    
     /**
      * Validate SAML 2 token which includes the role attribute with 2 values
      * Roles are encoded as a multi-value saml attribute
@@ -122,7 +198,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -161,7 +237,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -199,7 +275,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -240,7 +316,7 @@ public class FederationProcessorTest {
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
         
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
         wfReq.setWresult(rstr);
@@ -253,13 +329,55 @@ public class FederationProcessorTest {
         FederationProcessor wfProc = new FederationProcessorImpl();
         try {
             wfProc.processRequest(wfReq, config);
-            Assert.fail("Processing must fail because of wrong issuer 
configured");
-        } catch (RuntimeException ex) {
-            // expected
+            Assert.fail("Processing must fail because of untrusted issuer 
configured");
+        } catch (ProcessingException ex) {
+            if (!TYPE.ISSUER_NOT_TRUSTED.equals(ex.getType())) {
+                fail("Expected ProcessingException with ISSUER_NOT_TRUSTED 
type");
+            }
         }
     }
 
     /**
+     * Validate SAML 2 token which includes the role attribute with 2 values
+     * The configured subject of the trusted issuer doesn't match with
+     * the issuer of the SAML token
+     */
+    @org.junit.Test
+    public void validateUnsignedSAML2Token() throws Exception {
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+        callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+        callbackHandler.setSubjectName(TEST_USER);
+        ConditionsBean cp = new ConditionsBean();
+        cp.setAudienceURI(TEST_AUDIENCE);
+        callbackHandler.setConditions(cp);
+        
+        SAMLParms samlParms = new SAMLParms();
+        samlParms.setCallbackHandler(callbackHandler);
+        AssertionWrapper assertion = new AssertionWrapper(samlParms);
+        
+        String rstr = createSamlToken(assertion, "mystskey", false);
+        FederationRequest wfReq = new FederationRequest();
+        wfReq.setWa(FederationConstants.ACTION_SIGNIN);
+        wfReq.setWresult(rstr);
+        
+        // Load and update the config to enforce an error
+        configurator = null;
+        FederationContext config = 
getFederationConfigurator().getFederationContext("ROOT");       
+        
+        FederationProcessor wfProc = new FederationProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            Assert.fail("Processing must fail because of missing signature");
+        } catch (ProcessingException ex) {
+            if (!TYPE.TOKEN_NO_SIGNATURE.equals(ex.getType())) {
+                fail("Expected ProcessingException with TOKEN_NO_SIGNATURE 
type");
+            }
+        }
+    }
+    
+    /**
      * Validate SAML 2 token twice which causes an exception
      * due to replay attack
      */
@@ -277,7 +395,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -296,8 +414,10 @@ public class FederationProcessorTest {
         try {
             wfProc.processRequest(wfReq, config);
             fail("Failure expected on a replay attack");
-        } catch (Exception ex) {
-            // expected
+        } catch (ProcessingException ex) {
+            if (!TYPE.TOKEN_REPLAY.equals(ex.getType())) {
+                fail("Expected ProcessingException with TOKEN_REPLAY type");
+            }
         }
     }
     
@@ -322,7 +442,7 @@ public class FederationProcessorTest {
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
         
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
         wfReq.setWresult(rstr);
@@ -361,7 +481,7 @@ public class FederationProcessorTest {
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
         
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
         wfReq.setWresult(rstr);
@@ -403,7 +523,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -416,8 +536,10 @@ public class FederationProcessorTest {
         try {
             wfProc.processRequest(wfReq, config);
             fail("Failure expected on expired SAML token");
-        } catch (Exception ex) {
-            // expected
+        } catch (ProcessingException ex) {
+            if (!TYPE.TOKEN_EXPIRED.equals(ex.getType())) {
+                fail("Expected ProcessingException with TOKEN_EXPIRED type");
+            }
         }
     }
     
@@ -445,7 +567,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -483,7 +605,7 @@ public class FederationProcessorTest {
         SAMLParms samlParms = new SAMLParms();
         samlParms.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = new AssertionWrapper(samlParms);
-        String rstr = createSamlToken(assertion, "mystskey");
+        String rstr = createSamlToken(assertion, "mystskey", true);
         
         FederationRequest wfReq = new FederationRequest();
         wfReq.setWa(FederationConstants.ACTION_SIGNIN);
@@ -506,13 +628,15 @@ public class FederationProcessorTest {
     }
     
     
-    private String createSamlToken(AssertionWrapper assertion, String alias) 
throws IOException,
+    private String createSamlToken(AssertionWrapper assertion, String alias, 
boolean sign) throws IOException,
         UnsupportedCallbackException, WSSecurityException, Exception {
         WSPasswordCallback[] cb = {new WSPasswordCallback(alias, 
WSPasswordCallback.SIGNATURE)};
         cbPasswordHandler.handle(cb);
         String password = cb[0].getPassword();
         
-        assertion.signAssertion(alias, password, crypto, false);
+        if (sign) {
+            assertion.signAssertion(alias, password, crypto, false);
+        }
         Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
         Element token = assertion.toDOM(doc);
              

Modified: 
cxf/fediz/trunk/plugins/tomcat/src/main/java/org/apache/cxf/fediz/tomcat/FederationAuthenticator.java
URL: 
http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/tomcat/src/main/java/org/apache/cxf/fediz/tomcat/FederationAuthenticator.java?rev=1346619&r1=1346618&r2=1346619&view=diff
==============================================================================
--- 
cxf/fediz/trunk/plugins/tomcat/src/main/java/org/apache/cxf/fediz/tomcat/FederationAuthenticator.java
 (original)
+++ 
cxf/fediz/trunk/plugins/tomcat/src/main/java/org/apache/cxf/fediz/tomcat/FederationAuthenticator.java
 Tue Jun  5 21:48:37 2012
@@ -45,6 +45,7 @@ import org.apache.cxf.fediz.core.Federat
 import org.apache.cxf.fediz.core.FederationResponse;
 import org.apache.cxf.fediz.core.config.FederationConfigurator;
 import org.apache.cxf.fediz.core.config.FederationContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 
@@ -305,7 +306,14 @@ public class FederationAuthenticator ext
                 FederationContext fedConfig = 
getContextConfiguration(contextName);
 
                 FederationProcessor wfProc = new FederationProcessorImpl();
-                wfRes = wfProc.processRequest(wfReq, fedConfig);
+                try {
+                    wfRes = wfProc.processRequest(wfReq, fedConfig);
+                } catch (ProcessingException ex) {
+                    LOG.error("Federation processing failed: " + 
ex.getMessage());
+                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+                    return false;
+                }
+                
                 
                 // Validate the AudienceRestriction in Security Token (e.g. 
SAML) 
                 // against the configured list of audienceURIs
@@ -460,14 +468,22 @@ public class FederationAuthenticator ext
             contextName = "/";
         }
         FederationContext fedCtx = 
this.configurator.getFederationContext(contextName);
-        String redirectURL = processor.createSignInRequest(request, fedCtx);
-        if (redirectURL == null) {
-            LOG.warn("Failed to create SignInRequest.");
+        String redirectURL = null;
+        try {
+            redirectURL = processor.createSignInRequest(request, fedCtx);
+            if (redirectURL != null) {
+                response.sendRedirect(redirectURL);
+            } else {
+                LOG.warn("Failed to create SignInRequest.");
+                response.sendError(
+                        HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed 
to create SignInRequest.");
+            }
+        } catch (ProcessingException ex) {
+            LOG.warn("Failed to create SignInRequest: " + ex.getMessage());
             response.sendError(
-                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to 
create SignInRequest.");
-        } else {
-            response.sendRedirect(redirectURL);
+                               HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
"Failed to create SignInRequest.");
         }
+        
     }
 
 }


Reply via email to