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.");
}
+
}
}