Author: coheigea
Date: Fri Mar 16 11:33:48 2012
New Revision: 1301440
URL: http://svn.apache.org/viewvc?rev=1301440&view=rev
Log:
[CXF-4062][CXF-4173] - Enabling custom claim parser / Support for ClaimValue
element of federation claims dialect added
- Patch(es) applied, thanks! I made a few minor modifications
Conflicts:
services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
services/sts/sts-core/src/test/java/org/apache/cxf/sts/request/RequestParserUnitTest.java
Added:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsParser.java
- copied, changed from r1299692,
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/IdentityClaimsParser.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimParser.java
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
Fri Mar 16 11:33:48 2012
@@ -37,6 +37,7 @@ public class ClaimsManager {
private static final Logger LOG =
LogUtils.getL7dLogger(ClaimsManager.class);
+ private List<ClaimsParser> claimParsers;
private List<ClaimsHandler> claimHandlers;
private List<URI> supportedClaimTypes = new ArrayList<URI>();
@@ -44,10 +45,18 @@ public class ClaimsManager {
return supportedClaimTypes;
}
+ public List<ClaimsParser> getClaimParsers() {
+ return claimParsers;
+ }
+
public List<ClaimsHandler> getClaimHandlers() {
return claimHandlers;
}
+ public void setClaimParsers(List<ClaimsParser> claimParsers) {
+ this.claimParsers = claimParsers;
+ }
+
public void setClaimHandlers(List<ClaimsHandler> claimHandlers) {
this.claimHandlers = claimHandlers;
if (claimHandlers == null) {
@@ -116,4 +125,4 @@ public class ClaimsManager {
}
-
\ No newline at end of file
+
Copied:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsParser.java
(from r1299692,
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java)
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsParser.java?p2=cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsParser.java&p1=cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java&r1=1299692&r2=1301440&rev=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsParser.java
Fri Mar 16 11:33:48 2012
@@ -1,48 +1,39 @@
-/**
- * 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.sts.claims;
-
-import java.net.URI;
-
-/**
- * This represents a Claim that has been processed by the RequestParser.
- */
-public class RequestClaim {
-
- private URI claimType;
- private boolean optional;
-
- public URI getClaimType() {
- return claimType;
- }
-
- public void setClaimType(URI claimType) {
- this.claimType = claimType;
- }
-
- public boolean isOptional() {
- return optional;
- }
-
- public void setOptional(boolean optional) {
- this.optional = optional;
- }
-
-}
+/**
+ * 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.sts.claims;
+
+import org.w3c.dom.Element;
+
+public interface ClaimsParser {
+
+ /**
+ * @param claim Element to parse claim request from
+ * @return RequestClaim parsed from claim
+ */
+ RequestClaim parse(Element claim);
+
+ /**
+ * This method indicates the claims dialect this Parser can handle.
+ *
+ * @return Name of supported Dialect
+ */
+ String getSupportedDialect();
+
+}
Added:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/IdentityClaimsParser.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/IdentityClaimsParser.java?rev=1301440&view=auto
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/IdentityClaimsParser.java
(added)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/IdentityClaimsParser.java
Fri Mar 16 11:33:48 2012
@@ -0,0 +1,105 @@
+/**
+ * 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.sts.claims;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.logging.LogUtils;
+
+public class IdentityClaimsParser implements ClaimsParser {
+
+ public static final String IDENTITY_CLAIMS_DIALECT =
+ "http://schemas.xmlsoap.org/ws/2005/05/identity";
+
+ private static final Logger LOG =
LogUtils.getL7dLogger(IdentityClaimsParser.class);
+
+ public RequestClaim parse(Element claim) {
+ return parseClaimType(claim);
+ }
+
+ public static RequestClaim parseClaimType(Element claimType) {
+ String claimLocalName = claimType.getLocalName();
+ String claimNS = claimType.getNamespaceURI();
+ if ("ClaimType".equals(claimLocalName)) {
+ String claimTypeUri = claimType.getAttribute("Uri");
+ String claimTypeOptional = claimType.getAttribute("Optional");
+ RequestClaim requestClaim = new RequestClaim();
+ try {
+ requestClaim.setClaimType(new URI(claimTypeUri));
+ } catch (URISyntaxException e) {
+ LOG.log(
+ Level.WARNING,
+ "Cannot create URI from the given ClaimType attribute
value " + claimTypeUri,
+ e
+ );
+ }
+ requestClaim.setOptional(Boolean.parseBoolean(claimTypeOptional));
+ return requestClaim;
+ } else if ("ClaimValue".equals(claimLocalName)) {
+ String claimTypeUri = claimType.getAttribute("Uri");
+ String claimTypeOptional = claimType.getAttribute("Optional");
+ RequestClaim requestClaim = new RequestClaim();
+ try {
+ requestClaim.setClaimType(new URI(claimTypeUri));
+ } catch (URISyntaxException e) {
+ LOG.log(
+ Level.WARNING,
+ "Cannot create URI from the given ClaimTye attribute value
" + claimTypeUri,
+ e
+ );
+ }
+
+ Node valueNode = claimType.getFirstChild();
+ if (valueNode != null) {
+ if ("Value".equals(valueNode.getLocalName())) {
+ requestClaim.setClaimValue(valueNode.getTextContent());
+ } else {
+ LOG.warning("Unsupported child element of ClaimValue
element "
+ + valueNode.getLocalName());
+ return null;
+ }
+ } else {
+ LOG.warning("No child element of ClaimValue element
available");
+ return null;
+ }
+
+ requestClaim.setOptional(Boolean.parseBoolean(claimTypeOptional));
+
+ return requestClaim;
+ }
+
+ LOG.fine("Found unknown element: " + claimLocalName + " " + claimNS);
+ return null;
+ }
+
+ /**
+ * Return the supported dialect of this class
+ */
+ public String getSupportedDialect() {
+ return IDENTITY_CLAIMS_DIALECT;
+ }
+}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/RequestClaim.java
Fri Mar 16 11:33:48 2012
@@ -28,6 +28,7 @@ public class RequestClaim {
private URI claimType;
private boolean optional;
+ private String claimValue;
public URI getClaimType() {
return claimType;
@@ -44,5 +45,13 @@ public class RequestClaim {
public void setOptional(boolean optional) {
this.optional = optional;
}
+
+ public String getClaimValue() {
+ return claimValue;
+ }
+
+ public void setClaimValue(String claimValue) {
+ this.claimValue = claimValue;
+ }
}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
Fri Mar 16 11:33:48 2012
@@ -98,7 +98,7 @@ public abstract class AbstractOperation
protected List<TokenValidator> tokenValidators = new
ArrayList<TokenValidator>();
protected boolean returnReferences = true;
protected STSTokenStore tokenStore;
- protected ClaimsManager claimsManager;
+ protected ClaimsManager claimsManager = new ClaimsManager();
public boolean isReturnReferences() {
return returnReferences;
@@ -169,7 +169,7 @@ public abstract class AbstractOperation
stsProperties.configureProperties();
RequestParser requestParser = new RequestParser();
- requestParser.parseRequest(request, context);
+ requestParser.parseRequest(request, context, stsProperties,
claimsManager.getClaimParsers());
return requestParser;
}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
Fri Mar 16 11:33:48 2012
@@ -43,6 +43,9 @@ import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.sts.QNameConstants;
import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.claims.ClaimsParser;
+import org.apache.cxf.sts.claims.IdentityClaimsParser;
import org.apache.cxf.sts.claims.RequestClaim;
import org.apache.cxf.sts.claims.RequestClaimCollection;
import org.apache.cxf.ws.security.sts.provider.STSException;
@@ -78,10 +81,19 @@ public class RequestParser {
private KeyRequirements keyRequirements = new KeyRequirements();
private TokenRequirements tokenRequirements = new TokenRequirements();
+ @Deprecated
public void parseRequest(
RequestSecurityTokenType request, WebServiceContext wsContext
) throws STSException {
+ parseRequest(request, wsContext, null, null);
+ }
+
+ public void parseRequest(
+ RequestSecurityTokenType request, WebServiceContext wsContext,
STSPropertiesMBean stsProperties,
+ List<ClaimsParser> claimsParsers
+ ) throws STSException {
LOG.fine("Parsing RequestSecurityToken");
+
keyRequirements = new KeyRequirements();
tokenRequirements = new TokenRequirements();
@@ -89,7 +101,8 @@ public class RequestParser {
// JAXB types
if (requestObject instanceof JAXBElement<?>) {
JAXBElement<?> jaxbElement = (JAXBElement<?>) requestObject;
- boolean found = parseTokenRequirements(jaxbElement,
tokenRequirements, wsContext);
+ boolean found =
+ parseTokenRequirements(jaxbElement, tokenRequirements,
wsContext, claimsParsers);
if (!found) {
found = parseKeyRequirements(jaxbElement, keyRequirements);
}
@@ -104,7 +117,7 @@ public class RequestParser {
Element element = (Element)requestObject;
if (STSConstants.WST_NS_05_12.equals(element.getNamespaceURI())
&& "SecondaryParameters".equals(element.getLocalName())) {
- parseSecondaryParameters(element);
+ parseSecondaryParameters(element, claimsParsers);
} else if ("AppliesTo".equals(element.getLocalName())
&& (STSConstants.WSP_NS.equals(element.getNamespaceURI())
||
STSConstants.WSP_NS_04.equals(element.getNamespaceURI()))) {
@@ -199,7 +212,8 @@ public class RequestParser {
private static boolean parseTokenRequirements(
JAXBElement<?> jaxbElement,
TokenRequirements tokenRequirements,
- WebServiceContext wsContext
+ WebServiceContext wsContext,
+ List<ClaimsParser> claimsParsers
) {
if (QNameConstants.TOKEN_TYPE.equals(jaxbElement.getName())) {
String tokenType = (String)jaxbElement.getValue();
@@ -244,7 +258,7 @@ public class RequestParser {
LOG.fine("Found CancelTarget token");
} else if (QNameConstants.CLAIMS.equals(jaxbElement.getName())) {
ClaimsType claimsType = (ClaimsType)jaxbElement.getValue();
- RequestClaimCollection requestedClaims = parseClaims(claimsType);
+ RequestClaimCollection requestedClaims = parseClaims(claimsType,
claimsParsers);
tokenRequirements.setClaims(requestedClaims);
LOG.fine("Found Claims token");
} else {
@@ -348,7 +362,7 @@ public class RequestParser {
* direct children of the RequestSecurityToken element.
* @param secondaryParameters the secondaryParameters element to parse
*/
- private void parseSecondaryParameters(Element secondaryParameters) {
+ private void parseSecondaryParameters(Element secondaryParameters,
List<ClaimsParser> claimsParsers) {
LOG.fine("Found SecondaryParameters element");
Element child = DOMUtils.getFirstElement(secondaryParameters);
while (child != null) {
@@ -372,7 +386,7 @@ public class RequestParser {
} else if (tokenRequirements.getClaims() == null
&& "Claims".equals(localName) &&
STSConstants.WST_NS_05_12.equals(namespace)) {
LOG.fine("Found Claims element");
- RequestClaimCollection requestedClaims = parseClaims(child);
+ RequestClaimCollection requestedClaims = parseClaims(child,
claimsParsers);
tokenRequirements.setClaims(requestedClaims);
} else {
LOG.fine("Found unknown element: " + localName + " " +
namespace);
@@ -384,7 +398,7 @@ public class RequestParser {
/**
* Create a RequestClaimCollection from a DOM Element
*/
- private RequestClaimCollection parseClaims(Element claimsElement) {
+ private RequestClaimCollection parseClaims(Element claimsElement,
List<ClaimsParser> claimsParsers) {
String dialectAttr = null;
RequestClaimCollection requestedClaims = new RequestClaimCollection();
try {
@@ -402,7 +416,7 @@ public class RequestParser {
Element childClaimType = DOMUtils.getFirstElement(claimsElement);
while (childClaimType != null) {
- RequestClaim requestClaim = parseChildClaimType(childClaimType);
+ RequestClaim requestClaim = parseChildClaimType(childClaimType,
dialectAttr, claimsParsers);
if (requestClaim != null) {
requestedClaims.add(requestClaim);
}
@@ -415,7 +429,9 @@ public class RequestParser {
/**
* Create a RequestClaimCollection from a JAXB ClaimsType object
*/
- private static RequestClaimCollection parseClaims(ClaimsType claimsType) {
+ private static RequestClaimCollection parseClaims(
+ ClaimsType claimsType, List<ClaimsParser> claimsParsers
+ ) {
String dialectAttr = null;
RequestClaimCollection requestedClaims = new RequestClaimCollection();
try {
@@ -433,7 +449,7 @@ public class RequestParser {
for (Object claim : claimsType.getAny()) {
if (claim instanceof Element) {
- RequestClaim requestClaim =
parseChildClaimType((Element)claim);
+ RequestClaim requestClaim =
parseChildClaimType((Element)claim, dialectAttr, claimsParsers);
if (requestClaim != null) {
requestedClaims.add(requestClaim);
}
@@ -446,28 +462,24 @@ public class RequestParser {
/**
* Parse a child ClaimType into a RequestClaim object.
*/
- private static RequestClaim parseChildClaimType(Element childClaimType) {
- String claimLocalName = childClaimType.getLocalName();
- String claimNS = childClaimType.getNamespaceURI();
- if ("ClaimType".equals(claimLocalName)) {
- String claimTypeUri = childClaimType.getAttribute("Uri");
- String claimTypeOptional = childClaimType.getAttribute("Optional");
- RequestClaim requestClaim = new RequestClaim();
- try {
- requestClaim.setClaimType(new URI(claimTypeUri));
- } catch (URISyntaxException e) {
- LOG.log(
- Level.WARNING,
- "Cannot create URI from the given ClaimType attribute
value " + claimTypeUri,
- e
- );
+ private static RequestClaim parseChildClaimType(
+ Element childClaimType, String dialect, List<ClaimsParser>
claimsParsers
+ ) {
+ if (claimsParsers != null) {
+ for (ClaimsParser parser : claimsParsers) {
+ if (parser != null &&
dialect.equals(parser.getSupportedDialect())) {
+ return parser.parse(childClaimType);
+ }
}
- requestClaim.setOptional(Boolean.parseBoolean(claimTypeOptional));
- return requestClaim;
+ }
+ if (IdentityClaimsParser.IDENTITY_CLAIMS_DIALECT.equals(dialect)) {
+ return IdentityClaimsParser.parseClaimType(childClaimType);
}
- LOG.fine("Found unknown element: " + claimLocalName + " " + claimNS);
- return null;
+ LOG.log(Level.WARNING, "No ClaimsParser is registered for dialect " +
dialect);
+ throw new STSException(
+ "No ClaimsParser is registered for dialect " + dialect,
STSException.BAD_REQUEST
+ );
}
Added:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimParser.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimParser.java?rev=1301440&view=auto
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimParser.java
(added)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimParser.java
Fri Mar 16 11:33:48 2012
@@ -0,0 +1,68 @@
+/**
+ * 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.sts.common;
+
+import java.net.URI;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.sts.claims.ClaimsParser;
+import org.apache.cxf.sts.claims.RequestClaim;
+
+public class CustomClaimParser implements ClaimsParser {
+
+ public static final String CLAIMS_DIALECT =
"http://my.custom.org/my/custom/namespace";
+
+ public RequestClaim parse(Element claim) {
+
+ String claimLocalName = claim.getLocalName();
+ String claimNS = claim.getNamespaceURI();
+ if (CLAIMS_DIALECT.equals(claimNS) &&
"MyElement".equals(claimLocalName)) {
+ String claimTypeUri = claim.getAttribute("Uri");
+ CustomRequestClaim response = new CustomRequestClaim();
+ response.setClaimType(URI.create(claimTypeUri));
+ String claimValue = claim.getAttribute("value");
+ response.setClaimValue(claimValue);
+ String scope = claim.getAttribute("scope");
+ response.setScope(scope);
+ return response;
+ }
+ return null;
+ }
+
+ public String getSupportedDialect() {
+ return CLAIMS_DIALECT;
+ }
+
+ /**
+ * Extends RequestClaim class to add additional attributes
+ */
+ public class CustomRequestClaim extends RequestClaim {
+ private String scope;
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+ }
+
+}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java
Fri Mar 16 11:33:48 2012
@@ -32,6 +32,7 @@ import org.apache.cxf.sts.claims.ClaimsH
import org.apache.cxf.sts.claims.ClaimsParameters;
import org.apache.cxf.sts.claims.RequestClaim;
import org.apache.cxf.sts.claims.RequestClaimCollection;
+import org.apache.cxf.sts.common.CustomClaimParser.CustomRequestClaim;
/**
* A custom ClaimsHandler implementation for use in the tests.
@@ -39,11 +40,14 @@ import org.apache.cxf.sts.claims.Request
public class CustomClaimsHandler implements ClaimsHandler {
private static List<URI> knownURIs = new ArrayList<URI>();
+ private static final URI ROLE_CLAIM =
+
URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
static {
knownURIs.add(ClaimTypes.FIRSTNAME);
knownURIs.add(ClaimTypes.LASTNAME);
knownURIs.add(ClaimTypes.EMAILADDRESS);
+ knownURIs.add(ROLE_CLAIM);
}
public List<URI> getSupportedClaimTypes() {
@@ -72,12 +76,25 @@ public class CustomClaimsHandler impleme
Claim claim = new Claim();
claim.setClaimType(requestClaim.getClaimType());
if (ClaimTypes.FIRSTNAME.equals(requestClaim.getClaimType())) {
- claim.setValue("alice");
+ if (requestClaim instanceof CustomRequestClaim) {
+ CustomRequestClaim customClaim = (CustomRequestClaim)
requestClaim;
+ String customName = customClaim.getClaimValue() + "@"
+ customClaim.getScope();
+ claim.setValue(customName);
+ } else {
+ claim.setValue("alice");
+ }
} else if
(ClaimTypes.LASTNAME.equals(requestClaim.getClaimType())) {
claim.setValue("doe");
} else if
(ClaimTypes.EMAILADDRESS.equals(requestClaim.getClaimType())) {
claim.setValue("[email protected]");
- }
+ } else if (ROLE_CLAIM.equals(requestClaim.getClaimType())) {
+ String requestedRole = requestClaim.getClaimValue();
+ if (isUserInRole(parameters.getPrincipal(),
requestedRole)) {
+ claim.setValue(requestedRole);
+ } else {
+ continue;
+ }
+ }
claimCollection.add(claim);
}
return claimCollection;
@@ -86,5 +103,8 @@ public class CustomClaimsHandler impleme
return null;
}
+ private boolean isUserInRole(Principal principal, String requestedRole) {
+ return true;
+ }
}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java?rev=1301440&r1=1301439&r2=1301440&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
Fri Mar 16 11:33:48 2012
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.sts.operation;
+import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
@@ -42,7 +43,9 @@ import org.apache.cxf.sts.StaticSTSPrope
import org.apache.cxf.sts.claims.ClaimTypes;
import org.apache.cxf.sts.claims.ClaimsHandler;
import org.apache.cxf.sts.claims.ClaimsManager;
+import org.apache.cxf.sts.claims.ClaimsParser;
import org.apache.cxf.sts.common.CustomAttributeProvider;
+import org.apache.cxf.sts.common.CustomClaimParser;
import org.apache.cxf.sts.common.CustomClaimsHandler;
import org.apache.cxf.sts.common.PasswordCallbackHandler;
import org.apache.cxf.sts.service.ServiceMBean;
@@ -57,6 +60,7 @@ import org.apache.cxf.ws.security.sts.pr
import
org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType;
import org.apache.ws.security.CustomTokenPrincipal;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.saml.ext.builder.SAML1Constants;
@@ -71,6 +75,9 @@ public class IssueSamlClaimsUnitTest ext
public static final QName REQUESTED_SECURITY_TOKEN =
QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName();
+ private static final URI ROLE_CLAIM =
+
URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
+
/**
* Test to successfully issue a Saml 1.1 token.
*/
@@ -78,32 +85,11 @@ public class IssueSamlClaimsUnitTest ext
public void testIssueSaml1Token() throws Exception {
TokenIssueOperation issueOperation = new TokenIssueOperation();
- // Add Token Provider
- List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ addTokenProvider(issueOperation);
- List<AttributeStatementProvider> customProviderList =
- new ArrayList<AttributeStatementProvider>();
- customProviderList.add(new CustomAttributeProvider());
- SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
- samlTokenProvider.setAttributeStatementProviders(customProviderList);
- providerList.add(samlTokenProvider);
- issueOperation.setTokenProviders(providerList);
-
- // Add Service
- ServiceMBean service = new StaticService();
-
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
- issueOperation.setServices(Collections.singletonList(service));
+ addService(issueOperation);
- // Add STSProperties object
- STSPropertiesMBean stsProperties = new StaticSTSProperties();
- Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
- stsProperties.setEncryptionCrypto(crypto);
- stsProperties.setSignatureCrypto(crypto);
- stsProperties.setEncryptionUsername("myservicekey");
- stsProperties.setSignatureUsername("mystskey");
- stsProperties.setCallbackHandler(new PasswordCallbackHandler());
- stsProperties.setIssuer("STS");
- issueOperation.setStsProperties(stsProperties);
+ addSTSProperties(issueOperation);
// Set the ClaimsManager
ClaimsManager claimsManager = new ClaimsManager();
@@ -122,21 +108,10 @@ public class IssueSamlClaimsUnitTest ext
request.getAny().add(secondaryParameters);
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
- // Mock up message context
- MessageImpl msg = new MessageImpl();
- WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
- msgCtx.put(
- SecurityContext.class.getName(),
- createSecurityContext(new CustomTokenPrincipal("alice"))
- );
- WebServiceContextImpl webServiceContext = new
WebServiceContextImpl(msgCtx);
+ WebServiceContextImpl webServiceContext = setupMessageContext();
- // Issue a token
- RequestSecurityTokenResponseCollectionType response =
- issueOperation.issue(request, webServiceContext);
- List<RequestSecurityTokenResponseType> securityTokenResponse =
- response.getRequestSecurityTokenResponse();
- assertTrue(!securityTokenResponse.isEmpty());
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
issueToken(issueOperation, request,
+ webServiceContext);
// Test the generated token.
Element assertion = null;
@@ -155,7 +130,9 @@ public class IssueSamlClaimsUnitTest ext
assertTrue(tokenString.contains("AttributeStatement"));
assertTrue(tokenString.contains("alice"));
assertTrue(tokenString.contains(SAML1Constants.CONF_BEARER));
- assertTrue(tokenString.contains(ClaimTypes.FIRSTNAME.toString()));
+ assertTrue(tokenString.contains(ClaimTypes.LASTNAME.toString()));
+ assertTrue(tokenString.contains(ROLE_CLAIM.toString()));
+ assertTrue(tokenString.contains("administrator"));
}
/**
@@ -166,31 +143,13 @@ public class IssueSamlClaimsUnitTest ext
TokenIssueOperation issueOperation = new TokenIssueOperation();
// Add Token Provider
- List<TokenProvider> providerList = new ArrayList<TokenProvider>();
-
- List<AttributeStatementProvider> customProviderList =
- new ArrayList<AttributeStatementProvider>();
- customProviderList.add(new CustomAttributeProvider());
- SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
- samlTokenProvider.setAttributeStatementProviders(customProviderList);
- providerList.add(samlTokenProvider);
- issueOperation.setTokenProviders(providerList);
+ addTokenProvider(issueOperation);
// Add Service
- ServiceMBean service = new StaticService();
-
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
- issueOperation.setServices(Collections.singletonList(service));
+ addService(issueOperation);
// Add STSProperties object
- STSPropertiesMBean stsProperties = new StaticSTSProperties();
- Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
- stsProperties.setEncryptionCrypto(crypto);
- stsProperties.setSignatureCrypto(crypto);
- stsProperties.setEncryptionUsername("myservicekey");
- stsProperties.setSignatureUsername("mystskey");
- stsProperties.setCallbackHandler(new PasswordCallbackHandler());
- stsProperties.setIssuer("STS");
- issueOperation.setStsProperties(stsProperties);
+ addSTSProperties(issueOperation);
// Set the ClaimsManager
ClaimsManager claimsManager = new ClaimsManager();
@@ -209,21 +168,10 @@ public class IssueSamlClaimsUnitTest ext
request.getAny().add(secondaryParameters);
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
- // Mock up message context
- MessageImpl msg = new MessageImpl();
- WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
- msgCtx.put(
- SecurityContext.class.getName(),
- createSecurityContext(new CustomTokenPrincipal("alice"))
- );
- WebServiceContextImpl webServiceContext = new
WebServiceContextImpl(msgCtx);
+ WebServiceContextImpl webServiceContext = setupMessageContext();
- // Issue a token
- RequestSecurityTokenResponseCollectionType response =
- issueOperation.issue(request, webServiceContext);
- List<RequestSecurityTokenResponseType> securityTokenResponse =
- response.getRequestSecurityTokenResponse();
- assertTrue(!securityTokenResponse.isEmpty());
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
issueToken(issueOperation, request,
+ webServiceContext);
// Test the generated token.
Element assertion = null;
@@ -242,34 +190,105 @@ public class IssueSamlClaimsUnitTest ext
assertTrue(tokenString.contains("AttributeStatement"));
assertTrue(tokenString.contains("alice"));
assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
- assertTrue(tokenString.contains(ClaimTypes.FIRSTNAME.toString()));
+ assertTrue(tokenString.contains(ClaimTypes.LASTNAME.toString()));
+ assertTrue(tokenString.contains(ROLE_CLAIM.toString()));
+ assertTrue(tokenString.contains("administrator"));
}
/**
- * Test to successfully issue a Saml 1.1 token. The claims information is
included as a
- * JAXB Element under RequestSecurityToken, rather than as a child of
SecondaryParameters.
+ * Test custom claim parser and handler.
*/
@org.junit.Test
- public void testIssueJaxbSaml1Token() throws Exception {
+ public void testCustomClaimDialect() throws Exception {
TokenIssueOperation issueOperation = new TokenIssueOperation();
// Add Token Provider
- List<TokenProvider> providerList = new ArrayList<TokenProvider>();
-
- List<AttributeStatementProvider> customProviderList =
- new ArrayList<AttributeStatementProvider>();
- customProviderList.add(new CustomAttributeProvider());
- SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
- samlTokenProvider.setAttributeStatementProviders(customProviderList);
- providerList.add(samlTokenProvider);
- issueOperation.setTokenProviders(providerList);
+ addTokenProvider(issueOperation);
// Add Service
- ServiceMBean service = new StaticService();
-
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
- issueOperation.setServices(Collections.singletonList(service));
+ addService(issueOperation);
// Add STSProperties object
+ addSTSProperties(issueOperation);
+
+ // Set the ClaimsManager
+ ClaimsManager claimsManager = new ClaimsManager();
+ ClaimsHandler claimsHandler = new CustomClaimsHandler();
+ ClaimsParser claimsParser = new CustomClaimParser();
+ claimsManager.setClaimParsers(Collections.singletonList(claimsParser));
+
claimsManager.setClaimHandlers(Collections.singletonList(claimsHandler));
+ issueOperation.setClaimsManager(claimsManager);
+
+ // Mock up a request
+ RequestSecurityTokenType request = new RequestSecurityTokenType();
+ JAXBElement<String> tokenType =
+ new JAXBElement<String>(
+ QNameConstants.TOKEN_TYPE, String.class,
WSConstants.WSS_SAML2_TOKEN_TYPE
+ );
+ request.getAny().add(tokenType);
+ Element secondaryParameters = createCustomSecondaryParameters();
+ request.getAny().add(secondaryParameters);
+
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+
+ // Mock up message context
+ WebServiceContextImpl webServiceContext = setupMessageContext();
+
+ // Issue a token
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
issueToken(issueOperation,
+ request, webServiceContext);
+
+ // Test the generated token.
+ Element assertion = null;
+ for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+ if (tokenObject instanceof JAXBElement<?>
+ &&
REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+ RequestedSecurityTokenType rstType =
+
(RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+ assertion = (Element)rstType.getAny();
+ break;
+ }
+ }
+
+ assertNotNull(assertion);
+ String tokenString = DOM2Writer.nodeToString(assertion);
+ assertTrue(tokenString.contains("AttributeStatement"));
+ assertTrue(tokenString.contains("bob@custom"));
+ }
+
+ /**
+ * @param issueOperation
+ * @param request
+ * @param webServiceContext
+ * @return
+ */
+ private List<RequestSecurityTokenResponseType>
issueToken(TokenIssueOperation issueOperation,
+ RequestSecurityTokenType request, WebServiceContextImpl
webServiceContext) {
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ return securityTokenResponse;
+ }
+
+ /**
+ * @return
+ */
+ private WebServiceContextImpl setupMessageContext() {
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ msgCtx.put(
+ SecurityContext.class.getName(),
+ createSecurityContext(new CustomTokenPrincipal("alice"))
+ );
+ return new WebServiceContextImpl(msgCtx);
+ }
+
+ /**
+ * @param issueOperation
+ * @throws WSSecurityException
+ */
+ private void addSTSProperties(TokenIssueOperation issueOperation) throws
WSSecurityException {
STSPropertiesMBean stsProperties = new StaticSTSProperties();
Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
stsProperties.setEncryptionCrypto(crypto);
@@ -279,6 +298,45 @@ public class IssueSamlClaimsUnitTest ext
stsProperties.setCallbackHandler(new PasswordCallbackHandler());
stsProperties.setIssuer("STS");
issueOperation.setStsProperties(stsProperties);
+ }
+
+ /**
+ * @param issueOperation
+ */
+ private void addService(TokenIssueOperation issueOperation) {
+ ServiceMBean service = new StaticService();
+
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+ }
+
+ /**
+ * @param issueOperation
+ */
+ private void addTokenProvider(TokenIssueOperation issueOperation) {
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+
+ List<AttributeStatementProvider> customProviderList =
+ new ArrayList<AttributeStatementProvider>();
+ customProviderList.add(new CustomAttributeProvider());
+ SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+ samlTokenProvider.setAttributeStatementProviders(customProviderList);
+ providerList.add(samlTokenProvider);
+ issueOperation.setTokenProviders(providerList);
+ }
+
+ /**
+ * Test to successfully issue a Saml 1.1 token. The claims information is
included as a
+ * JAXB Element under RequestSecurityToken, rather than as a child of
SecondaryParameters.
+ */
+ @org.junit.Test
+ public void testIssueJaxbSaml1Token() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ addTokenProvider(issueOperation);
+
+ addService(issueOperation);
+
+ addSTSProperties(issueOperation);
// Set the ClaimsManager
ClaimsManager claimsManager = new ClaimsManager();
@@ -309,21 +367,10 @@ public class IssueSamlClaimsUnitTest ext
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
- // Mock up message context
- MessageImpl msg = new MessageImpl();
- WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
- msgCtx.put(
- SecurityContext.class.getName(),
- createSecurityContext(new CustomTokenPrincipal("alice"))
- );
- WebServiceContextImpl webServiceContext = new
WebServiceContextImpl(msgCtx);
+ WebServiceContextImpl webServiceContext = setupMessageContext();
- // Issue a token
- RequestSecurityTokenResponseCollectionType response =
- issueOperation.issue(request, webServiceContext);
- List<RequestSecurityTokenResponseType> securityTokenResponse =
- response.getRequestSecurityTokenResponse();
- assertTrue(!securityTokenResponse.isEmpty());
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
issueToken(issueOperation, request,
+ webServiceContext);
// Test the generated token.
Element assertion = null;
@@ -342,7 +389,7 @@ public class IssueSamlClaimsUnitTest ext
assertTrue(tokenString.contains("AttributeStatement"));
assertTrue(tokenString.contains("alice"));
assertTrue(tokenString.contains(SAML1Constants.CONF_BEARER));
- assertTrue(tokenString.contains(ClaimTypes.FIRSTNAME.toString()));
+ assertTrue(tokenString.contains(ClaimTypes.LASTNAME.toString()));
}
/*
@@ -399,8 +446,31 @@ public class IssueSamlClaimsUnitTest ext
claims.setAttributeNS(null, "Dialect", STSConstants.IDT_NS_05_05);
Element claimType = createClaimsType(doc);
-
claims.appendChild(claimType);
+ Element claimValue = createClaimValue(doc);
+ claims.appendChild(claimValue);
+ secondary.appendChild(claims);
+
+ return secondary;
+ }
+
+ /*
+ * Mock up a SecondaryParameters DOM Element containing a custom claim
dialect.
+ */
+ private Element createCustomSecondaryParameters() {
+ Document doc = DOMUtils.createDocument();
+ Element secondary = doc.createElementNS(STSConstants.WST_NS_05_12,
"SecondaryParameters");
+ secondary.setAttributeNS(WSConstants.XMLNS_NS, "xmlns",
STSConstants.WST_NS_05_12);
+
+ Element claims = doc.createElementNS(STSConstants.WST_NS_05_12,
"Claims");
+ claims.setAttributeNS(null, "Dialect",
CustomClaimParser.CLAIMS_DIALECT);
+
+ Element claim = doc.createElementNS(CustomClaimParser.CLAIMS_DIALECT,
"MyElement");
+ claim.setAttributeNS(null, "Uri", ClaimTypes.FIRSTNAME.toString());
+ claim.setAttributeNS(null, "value", "bob");
+ claim.setAttributeNS(null, "scope", "custom");
+
+ claims.appendChild(claim);
secondary.appendChild(claims);
return secondary;
@@ -409,11 +479,21 @@ public class IssueSamlClaimsUnitTest ext
private Element createClaimsType(Document doc) {
Element claimType = doc.createElementNS(STSConstants.IDT_NS_05_05,
"ClaimType");
claimType.setAttributeNS(
- null, "Uri",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
+ null, "Uri", ClaimTypes.LASTNAME.toString()
);
claimType.setAttributeNS(WSConstants.XMLNS_NS, "xmlns",
STSConstants.IDT_NS_05_05);
return claimType;
}
+ private Element createClaimValue(Document doc) {
+ Element claimValue = doc.createElementNS(STSConstants.IDT_NS_05_05,
"ClaimValue");
+ claimValue.setAttributeNS(null, "Uri", ROLE_CLAIM.toString());
+ claimValue.setAttributeNS(WSConstants.XMLNS_NS, "xmlns",
STSConstants.IDT_NS_05_05);
+ Element value = doc.createElementNS(STSConstants.IDT_NS_05_05,
"Value");
+ value.setTextContent("administrator");
+ claimValue.appendChild(value);
+ return claimValue;
+ }
+
}