cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1173182 [5/9] - in /cxf/trunk: ./ services/ services/sts/ services/sts/sts-core/ services/sts/sts-core/src/ services/sts/sts-core/src/main/ services/sts/sts-core/src/main/java/ services/sts/sts-core/src/main/java/org/ services/sts/sts-core...
Date Tue, 20 Sep 2011 15:12:11 GMT
Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,141 @@
+/**
+ * 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.token.validator;
+
+import java.security.cert.X509Certificate;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Text;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+
+import org.apache.cxf.ws.security.sts.provider.model.secext.BinarySecurityTokenType;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.processor.BinarySecurityTokenProcessor;
+import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.validate.Credential;
+import org.apache.ws.security.validate.SignatureTrustValidator;
+import org.apache.ws.security.validate.Validator;
+
+/**
+ * This class validates an X.509 V.3 certificate (received as a BinarySecurityToken). The cert must
+ * be known (or trusted) by the STS crypto object.
+ */
+public class X509TokenValidator implements TokenValidator {
+    
+    public static final String X509_V3_TYPE = WSConstants.X509TOKEN_NS + "#X509v3";
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(X509TokenValidator.class);
+
+    /**
+     * Return true if this TokenValidator implementation is capable of validating the
+     * ReceivedToken argument.
+     */
+    public boolean canHandleToken(ReceivedToken validateTarget) {
+        Object token = validateTarget.getToken();
+        if ((token instanceof BinarySecurityTokenType)
+            && X509_V3_TYPE.equals(((BinarySecurityTokenType)token).getValueType())) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        LOG.fine("Validating X.509 Token");
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        ReceivedToken validateTarget = tokenRequirements.getValidateTarget();
+
+        STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+        Crypto sigCrypto = stsProperties.getSignatureCrypto();
+        CallbackHandler callbackHandler = stsProperties.getCallbackHandler();
+
+        RequestData requestData = new RequestData();
+        requestData.setSigCrypto(sigCrypto);
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        wssConfig.setValidator(WSSecurityEngine.BINARY_TOKEN, BSTValidator.class);
+        requestData.setWssConfig(wssConfig);
+        requestData.setCallbackHandler(callbackHandler);
+
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        response.setValid(false);
+        
+        if (validateTarget != null && validateTarget.isBinarySecurityToken()) {
+            BinarySecurityTokenType binarySecurityType = 
+                (BinarySecurityTokenType)validateTarget.getToken();
+            //
+            // Turn the received JAXB object into a DOM element
+            //
+            Document doc = DOMUtils.createDocument();
+            BinarySecurity binarySecurity = new X509Security(doc);
+            binarySecurity.setEncodingType(binarySecurityType.getEncodingType());
+            String data = binarySecurityType.getValue();
+            ((Text)binarySecurity.getElement().getFirstChild()).setData(data);
+            
+            //
+            // Process and Validate the token
+            //
+            Processor processor = new BinarySecurityTokenProcessor();
+            try {
+                processor.handleToken(
+                    binarySecurity.getElement(), requestData, new WSDocInfo(doc)
+                );
+                X509Certificate cert = ((X509Security) binarySecurity).getX509Certificate(sigCrypto);
+                response.setPrincipal(cert.getSubjectX500Principal());
+                response.setValid(true);
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+            }
+        }
+        return response;
+    }
+    
+    /**
+     * A Custom Validator for a BinarySecurityToken - it just sends the BinarySecurityToken
+     * to the SignatureTrustValidator for validation.
+     */
+    public static class BSTValidator implements Validator {
+
+        public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
+            Validator delegate = new SignatureTrustValidator();
+            return delegate.validate(credential, data);
+        }
+        
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryCacheTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryCacheTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryCacheTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryCacheTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,56 @@
+/**
+ * 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.cache;
+
+import org.junit.BeforeClass;
+
+public class DefaultInMemoryCacheTest extends org.junit.Assert {
+  
+    private static STSCache cache;
+    
+    @BeforeClass
+    public static void init() {
+        cache = new DefaultInMemoryCache();
+    }
+    
+    // tests STSCache apis for storing in the cache.
+    @org.junit.Test
+    public void testCacheStore() {
+        String key = "key";
+        String value = "value";
+        cache.put(key, value);
+        assertEquals(value, cache.get(key));
+        cache.remove(key);
+        assertNull(cache.get(key));
+    }
+    
+    // tests STSCache apis for removing from the cache.
+    @org.junit.Test
+    public void testCacheRemove() {
+        cache.put("test1", "test1");
+        cache.put("test2", "test2");
+        cache.put("test3", "test3");
+        assertTrue(cache.size() == 3);
+        assertTrue(cache.remove("test3"));
+        assertFalse(cache.remove("test3"));
+        assertNull(cache.get("test3"));
+        cache.removeAll();
+        assertTrue(cache.size() == 0);
+    }
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryTokenStoreTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryTokenStoreTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryTokenStoreTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/DefaultInMemoryTokenStoreTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,64 @@
+/**
+ * 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.cache;
+
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.junit.BeforeClass;
+
+public class DefaultInMemoryTokenStoreTest extends org.junit.Assert {
+  
+    private static STSTokenStore store;
+    
+    @BeforeClass
+    public static void init() {
+        store = new DefaultInMemoryTokenStore();
+    }
+    
+    // tests STSCache apis for storing in the cache.
+    @org.junit.Test
+    public void testTokenAdd() throws Exception {
+        String key = "key";
+        SecurityToken token = new SecurityToken(key);
+        store.add(token);
+        assertEquals(token, store.getToken(key));
+        store.remove(token);
+        assertNull(store.getToken(key));
+        store.add(token, new Integer(1));
+        assertNotNull(store.getToken(key));
+        Thread.sleep(2000);
+        assertNull(store.getToken(key));
+    }
+    
+    // tests STSCache apis for removing from the cache.
+    @org.junit.Test
+    public void testTokenRemove() {
+        SecurityToken token1 = new SecurityToken("token1");
+        SecurityToken token2 = new SecurityToken("token2");
+        SecurityToken token3 = new SecurityToken("token3");
+        store.add(token1);
+        store.add(token2);
+        store.add(token3);
+        assertTrue(store.getValidTokens().size() == 3);
+        store.remove(token3);
+        assertNull(store.getToken("test3"));
+        store.remove(token1);
+        store.remove(token2);
+        assertTrue(store.getValidTokens().size() == 0);
+    }
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/HazelCastCacheTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/HazelCastCacheTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/HazelCastCacheTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/cache/HazelCastCacheTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,56 @@
+/**
+ * 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.cache;
+
+import org.junit.BeforeClass;
+
+public class HazelCastCacheTest extends org.junit.Assert {
+  
+    private static STSCache cache;
+    
+    @BeforeClass
+    public static void init() throws Exception {
+        cache = new HazelCastCache("default");
+    }
+    
+    // tests STSCache apis for storing in the cache.
+    @org.junit.Test
+    public void testCacheStore() {
+        String key = "key";
+        String value = "value";
+        cache.put(key, value);
+        assertEquals(value, cache.get(key));
+        cache.remove(key);
+        assertNull(cache.get(key));
+    }
+    
+    // tests STSCache apis for removing from the cache.
+    @org.junit.Test
+    public void testCacheRemove() {
+        cache.put("test1", "test1");
+        cache.put("test2", "test2");
+        cache.put("test3", "test3");
+        assertTrue(cache.size() == 3);
+        assertTrue(cache.remove("test3"));
+        assertFalse(cache.remove("test3"));
+        assertNull(cache.get("test3"));
+        cache.removeAll();
+        assertTrue(cache.size() == 0);
+    }
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,175 @@
+/**
+ * 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.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.sts.claims.Claim;
+import org.apache.cxf.sts.claims.ClaimCollection;
+import org.apache.cxf.sts.claims.ClaimsManager;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.token.provider.AttributeStatementProvider;
+import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
+import org.apache.ws.security.SAMLTokenPrincipal;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.saml.ext.bean.AttributeBean;
+import org.apache.ws.security.saml.ext.bean.AttributeStatementBean;
+
+/**
+ * A custom AttributeStatementProvider implementation for use in the tests.
+ */
+public class CustomAttributeProvider implements AttributeStatementProvider {
+
+    /**
+     * Get an AttributeStatementBean using the given parameters.
+     */
+    public AttributeStatementBean getStatement(TokenProviderParameters providerParameters) {
+        List<AttributeBean> attributeList = new ArrayList<AttributeBean>();
+
+        TokenRequirements tokenRequirements = providerParameters.getTokenRequirements();
+        String tokenType = tokenRequirements.getTokenType();
+        
+        // Handle Claims
+        ClaimsManager claimsManager = providerParameters.getClaimsManager();
+        ClaimCollection retrievedClaims = new ClaimCollection();
+        if (claimsManager != null) {
+            retrievedClaims = 
+                claimsManager.retrieveClaimValues(
+                    providerParameters.getPrincipal(), providerParameters.getRequestedClaims()
+                );
+        }
+        
+        AttributeStatementBean attrBean = new AttributeStatementBean();
+        Iterator<Claim> claimIterator = retrievedClaims.iterator();
+        if (!claimIterator.hasNext()) {
+            // If no Claims have been processed then create a default attribute
+            AttributeBean attributeBean = createDefaultAttribute(tokenType);
+            attributeList.add(attributeBean);
+        }
+        
+        while (claimIterator.hasNext()) {
+            Claim claim = claimIterator.next();
+            AttributeBean attributeBean = createAttributeFromClaim(claim, tokenType);
+            attributeList.add(attributeBean);
+        }
+        
+        ReceivedToken onBehalfOf = tokenRequirements.getOnBehalfOf();
+        ReceivedToken actAs = tokenRequirements.getActAs();
+        try {
+            if (onBehalfOf != null) {
+                AttributeBean parameterBean = 
+                    handleAdditionalParameters(false, onBehalfOf.getToken(), tokenType);
+                if (!parameterBean.getAttributeValues().isEmpty()) {
+                    attributeList.add(parameterBean);
+                }
+            }
+            if (actAs != null) {
+                AttributeBean parameterBean = 
+                    handleAdditionalParameters(true, actAs.getToken(), tokenType);
+                if (!parameterBean.getAttributeValues().isEmpty()) {
+                    attributeList.add(parameterBean);
+                }
+            }
+        } catch (WSSecurityException ex) {
+            throw new STSException(ex.getMessage(), ex);
+        }
+        
+        attrBean.setSamlAttributes(attributeList);
+        
+        return attrBean;
+    }
+    
+    /**
+     * Create a default attribute
+     */
+    private AttributeBean createDefaultAttribute(String tokenType) {
+        AttributeBean attributeBean = new AttributeBean();
+
+        if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
+            || WSConstants.SAML2_NS.equals(tokenType)) {
+            attributeBean.setQualifiedName("token-requestor");
+            attributeBean.setNameFormat("http://cxf.apache.org/sts/custom");
+        } else {
+            attributeBean.setSimpleName("token-requestor");
+            attributeBean.setQualifiedName("http://cxf.apache.org/sts/custom");
+        }
+        
+        attributeBean.setAttributeValues(Collections.singletonList("authenticated"));
+        
+        return attributeBean;
+    }
+
+    /**
+     * Handle ActAs or OnBehalfOf elements.
+     */
+    private AttributeBean handleAdditionalParameters(
+        boolean actAs, 
+        Object parameter, 
+        String tokenType
+    ) throws WSSecurityException {
+        AttributeBean parameterBean = new AttributeBean();
+
+        String claimType = actAs ? "CustomActAs" : "CustomOnBehalfOf";
+        if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType) || WSConstants.SAML2_NS.equals(tokenType)) {
+            parameterBean.setQualifiedName(claimType);
+            parameterBean.setNameFormat("http://cxf.apache.org/sts/custom/" + claimType);
+        } else {
+            parameterBean.setSimpleName(claimType);
+            parameterBean.setQualifiedName("http://cxf.apache.org/sts/custom/" + claimType);
+        }
+        if (parameter instanceof UsernameTokenType) {
+            parameterBean.setAttributeValues(
+                Collections.singletonList(((UsernameTokenType)parameter).getUsername().getValue())
+            );
+        } else if (parameter instanceof Element) {
+            AssertionWrapper wrapper = new AssertionWrapper((Element)parameter);
+            SAMLTokenPrincipal principal = new SAMLTokenPrincipal(wrapper);
+            parameterBean.setAttributeValues(Collections.singletonList(principal.getName()));
+        }
+
+        return parameterBean;
+    }
+
+    /**
+     * Create an Attribute from a claim.
+     */
+    private AttributeBean createAttributeFromClaim(Claim claim, String tokenType) {
+        AttributeBean attributeBean = new AttributeBean();
+        if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
+            || WSConstants.SAML2_NS.equals(tokenType)) {
+            attributeBean.setQualifiedName(claim.getClaimType().toString());
+        } else {
+            attributeBean.setSimpleName(claim.getClaimType().toString());
+        }
+        attributeBean.setAttributeValues(Collections.singletonList(claim.getValue()));
+
+        return attributeBean;
+    }
+
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomClaimsHandler.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.sts.common;
+
+import java.net.URI;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cxf.sts.claims.Claim;
+import org.apache.cxf.sts.claims.ClaimCollection;
+import org.apache.cxf.sts.claims.ClaimTypes;
+import org.apache.cxf.sts.claims.ClaimsHandler;
+import org.apache.cxf.sts.claims.RequestClaim;
+import org.apache.cxf.sts.claims.RequestClaimCollection;
+
+/**
+ * A custom ClaimsHandler implementation for use in the tests.
+ */
+public class CustomClaimsHandler implements ClaimsHandler {
+    
+    private static List<URI> knownURIs = new ArrayList<URI>();
+    
+    static {
+        knownURIs.add(ClaimTypes.FIRSTNAME);
+        knownURIs.add(ClaimTypes.LASTNAME);
+        knownURIs.add(ClaimTypes.EMAILADDRESS);
+    }
+
+    public List<URI> getSupportedClaimTypes() {
+        return knownURIs;
+    }
+
+    public ClaimCollection retrieveClaimValues(Principal principal, RequestClaimCollection claims) {
+        if (claims != null && claims.size() > 0) {
+            ClaimCollection claimCollection = new ClaimCollection();
+            for (RequestClaim requestClaim : claims) {
+                Claim claim = new Claim();
+                claim.setClaimType(requestClaim.getClaimType());
+                if (ClaimTypes.FIRSTNAME.equals(requestClaim.getClaimType())) {
+                    claim.setValue("alice");
+                } else if (ClaimTypes.LASTNAME.equals(requestClaim.getClaimType())) {
+                    claim.setValue("doe");
+                } else if (ClaimTypes.EMAILADDRESS.equals(requestClaim.getClaimType())) {
+                    claim.setValue("alice@cxf.apache.org");
+                }
+                claimCollection.add(claim);
+            }
+            return claimCollection;
+        }
+        
+        return null;
+    }
+
+        
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,47 @@
+/**
+ * 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.io.IOException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.ws.security.WSPasswordCallback;
+
+public class PasswordCallbackHandler implements CallbackHandler {
+
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) { // CXF
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                if ("alice".equals(pc.getIdentifier())) {
+                    pc.setPassword("clarinet");
+                    break;
+                } else if ("bob".equals(pc.getIdentifier())) {
+                    pc.setPassword("trombone");
+                    break;
+                } else if ("mystskey".equals(pc.getIdentifier())) {
+                    pc.setPassword("stskpass");
+                    break;
+                }
+            }
+        }
+    }
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/ldap/LDAPClaimsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/ldap/LDAPClaimsTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/ldap/LDAPClaimsTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/ldap/LDAPClaimsTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,271 @@
+/**
+ * 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.ldap;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+
+import org.apache.cxf.sts.claims.Claim;
+import org.apache.cxf.sts.claims.ClaimCollection;
+import org.apache.cxf.sts.claims.ClaimTypes;
+import org.apache.cxf.sts.claims.LdapClaimsHandler;
+import org.apache.cxf.sts.claims.RequestClaim;
+import org.apache.cxf.sts.claims.RequestClaimCollection;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.ws.security.CustomTokenPrincipal;
+import org.junit.BeforeClass;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.filter.AndFilter;
+import org.springframework.ldap.filter.EqualsFilter;
+import org.springframework.util.Assert;
+
+public class LDAPClaimsTest {
+
+    private static ClassPathXmlApplicationContext appContext;
+    private static Properties props;
+
+    @BeforeClass
+    public static void setUpLdap() throws Exception {
+        appContext = new ClassPathXmlApplicationContext("ldap.xml");
+        props = new Properties();
+
+        InputStream is = null;
+        try {
+            is = LDAPClaimsTest.class.getResourceAsStream("/ldap.properties");
+            props.load(is);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+
+
+    @org.junit.Test
+    @org.junit.Ignore
+    public void testRetrieveClaims() throws Exception {
+        LdapClaimsHandler claimsHandler = (LdapClaimsHandler)appContext.getBean("testClaimsHandler");
+
+        String user = props.getProperty("claimUser");
+        Assert.notNull(user, "Property 'claimUser' not configured");
+
+        RequestClaimCollection requestedClaims = createRequestClaimCollection();
+
+        List<URI> expectedClaims = new ArrayList<URI>();
+        expectedClaims.add(ClaimTypes.FIRSTNAME);
+        expectedClaims.add(ClaimTypes.LASTNAME);
+        expectedClaims.add(ClaimTypes.EMAILADDRESS);
+
+        ClaimCollection retrievedClaims = 
+            claimsHandler.retrieveClaimValues(new CustomTokenPrincipal(user), requestedClaims);
+
+        Assert.isTrue(
+                      retrievedClaims.size() == expectedClaims.size(), 
+                      "Retrieved number of claims [" + retrievedClaims.size() 
+                      + "] doesn't match with expected [" + expectedClaims.size() + "]"
+        );
+
+        for (Claim c : retrievedClaims) {
+            if (expectedClaims.contains(c.getClaimType())) {
+                expectedClaims.remove(c.getClaimType());
+            } else {
+                Assert.isTrue(false, "Claim '" + c.getClaimType() + "' not requested");
+            }
+        }
+
+    }
+
+
+    @org.junit.Test(expected = STSException.class)
+    @org.junit.Ignore
+    public void testRetrieveClaimsWithUnsupportedMandatoryClaimType() throws Exception {
+        LdapClaimsHandler claimsHandler = (LdapClaimsHandler)appContext.getBean("testClaimsHandler");
+
+        String user = props.getProperty("claimUser");
+        Assert.notNull(user, "Property 'claimUser' not configured");
+
+        RequestClaimCollection requestedClaims = createRequestClaimCollection();
+        // add unsupported but mandatory claim
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(ClaimTypes.GENDER);
+        claim.setOptional(false);
+        requestedClaims.add(claim);
+
+        claimsHandler.retrieveClaimValues(new CustomTokenPrincipal(user), requestedClaims);
+
+    }
+
+    @org.junit.Test
+    @org.junit.Ignore
+    public void testRetrieveClaimsWithUnsupportedOptionalClaimType() throws Exception {
+        LdapClaimsHandler claimsHandler = (LdapClaimsHandler)appContext.getBean("testClaimsHandler");
+
+        String user = props.getProperty("claimUser");
+        Assert.notNull(user, "Property 'claimUser' not configured");
+
+        RequestClaimCollection requestedClaims = createRequestClaimCollection();
+        // add unsupported but optional unsupported claim
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(ClaimTypes.GENDER);
+        claim.setOptional(true);
+        requestedClaims.add(claim);
+
+        // Gender is not expected to be returned because not supported
+        List<URI> expectedClaims = new ArrayList<URI>();
+        expectedClaims.add(ClaimTypes.FIRSTNAME);
+        expectedClaims.add(ClaimTypes.LASTNAME);
+        expectedClaims.add(ClaimTypes.EMAILADDRESS);
+
+        ClaimCollection retrievedClaims = 
+            claimsHandler.retrieveClaimValues(new CustomTokenPrincipal(user), requestedClaims);
+
+        Assert.isTrue(
+                      retrievedClaims.size() == expectedClaims.size(), 
+                      "Retrieved number of claims [" + retrievedClaims.size() 
+                      + "] doesn't match with expected [" + expectedClaims.size() + "]"
+        );
+
+        for (Claim c : retrievedClaims) {
+            if (expectedClaims.contains(c.getClaimType())) {
+                expectedClaims.remove(c.getClaimType());
+            } else {
+                Assert.isTrue(false, "Claim '" + c.getClaimType() + "' not requested");
+            }
+        }
+    }
+
+    private RequestClaimCollection createRequestClaimCollection() {
+        RequestClaimCollection claims = new RequestClaimCollection();
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(ClaimTypes.FIRSTNAME);
+        claim.setOptional(true);
+        claims.add(claim);
+        claim = new RequestClaim();
+        claim.setClaimType(ClaimTypes.LASTNAME);
+        claim.setOptional(true);
+        claims.add(claim);
+        claim = new RequestClaim();
+        claim.setClaimType(ClaimTypes.EMAILADDRESS);
+        claim.setOptional(true);
+        claims.add(claim);
+        return claims;
+    }
+
+    @org.junit.Test    
+    public void testSupportedClaims() throws Exception {
+
+        @SuppressWarnings("unchecked")
+        Map<String, String> mapping = (Map)appContext.getBean("claimsToLdapAttributeMapping");
+
+        LdapClaimsHandler cHandler = new LdapClaimsHandler();
+        cHandler.setClaimsLdapAttributeMapping(mapping);
+
+        List<URI> supportedClaims = cHandler.getSupportedClaimTypes();
+
+        Assert.isTrue(
+                      mapping.size() == supportedClaims.size(), 
+                      "Supported claims and claims/ldap attribute mapping size different"
+        );
+
+        for (String claim : mapping.keySet()) {
+            Assert.isTrue(
+                          supportedClaims.contains(new URI(claim)), 
+                          "Claim '" + claim + "' not listed in supported list"
+            );
+        }
+    }
+
+
+    @org.junit.Test
+    @org.junit.Ignore    
+    public void testLdapTemplate() throws Exception {
+
+        try {
+            LdapTemplate ldap = (LdapTemplate)appContext.getBean("ldapTemplate");
+
+            String user = props.getProperty("claimUser");
+            Assert.notNull(user, "Property 'claimUser' not configured");
+
+            String dn = null;
+
+            AndFilter filter = new AndFilter();
+            filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("cn", user));
+
+            //find DN of user
+            AttributesMapper mapper = 
+                new AttributesMapper() {
+                    public Object mapFromAttributes(Attributes attrs) throws NamingException {
+                        return attrs.get("distinguishedName").get();
+                    }
+                };
+            @SuppressWarnings("rawtypes")
+            List users = 
+                ldap.search(
+                            "OU=users,DC=emea,DC=mycompany,DC=com", 
+                            filter.toString(), 
+                            SearchControls.SUBTREE_SCOPE,
+                            mapper
+                );
+
+            Assert.isTrue(users.size() == 1, "Only one user expected");
+            dn = (String)users.get(0);
+
+            // get attributes
+            AttributesMapper mapper2 = 
+                new AttributesMapper() {
+                    public Object mapFromAttributes(Attributes attrs) throws NamingException {
+                        Map<String, String> map = new HashMap<String, String>();
+                        NamingEnumeration<? extends Attribute> attrEnum = attrs.getAll();
+                        while (attrEnum.hasMore()) {
+                            Attribute att = attrEnum.next();
+                            System.out.println(att.toString());
+                        }
+    
+                        map.put("cn", (String)attrs.get("cn").get());
+                        map.put("mail", (String)attrs.get("mail").get());
+                        map.put("sn", (String)attrs.get("sn").get());
+                        map.put("givenName", (String)attrs.get("givenName").get());
+                        return map;
+                    }
+                };
+            ldap.lookup(dn, new String[] {"cn", "mail", "sn", "givenName", "c"}, mapper2);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+    }
+
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/CancelSCTUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/CancelSCTUnitTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/CancelSCTUnitTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/CancelSCTUnitTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,227 @@
+/**
+ * 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.operation;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.jaxws.context.WebServiceContextImpl;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.cache.DefaultInMemoryCache;
+import org.apache.cxf.sts.cache.STSCache;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.token.canceller.SCTCanceller;
+import org.apache.cxf.sts.token.canceller.TokenCanceller;
+import org.apache.cxf.sts.token.provider.SCTProvider;
+import org.apache.cxf.sts.token.provider.TokenProvider;
+import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.sts.token.provider.TokenProviderResponse;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.CancelTargetType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
+import org.apache.cxf.ws.security.trust.STSUtils;
+import org.apache.ws.security.CustomTokenPrincipal;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+
+/**
+ * Some unit tests for the cancel operation to cancel SecurityContextTokens.
+ */
+public class CancelSCTUnitTest extends org.junit.Assert {
+    
+    public static final QName REQUESTED_SECURITY_TOKEN = 
+        QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName();
+    private static final QName QNAME_REQ_TOKEN_CANCELLED = 
+        QNameConstants.WS_TRUST_FACTORY.createRequestedTokenCancelled(null).getName();
+    
+    private static STSCache cache = new DefaultInMemoryCache();
+    
+    /**
+     * Test to successfully cancel a SecurityContextToken
+     */
+    @org.junit.Test
+    public void testCancelSCT() throws Exception {
+        TokenCancelOperation cancelOperation = new TokenCancelOperation();
+        cancelOperation.setCache(cache);
+        
+        // Add Token Canceller
+        List<TokenCanceller> cancellerList = new ArrayList<TokenCanceller>();
+        cancellerList.add(new SCTCanceller());
+        cancelOperation.setTokenCancellers(cancellerList);
+        
+        // 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");
+        cancelOperation.setStsProperties(stsProperties);
+        
+        // Get a SecurityContextToken via the SCTProvider
+        TokenProviderResponse providerResponse = createSCT();
+        Element sct = providerResponse.getToken();
+        Document doc = sct.getOwnerDocument();
+        sct = (Element)doc.appendChild(sct);
+        CancelTargetType cancelTarget = new CancelTargetType();
+        cancelTarget.setAny(sct);
+        
+        // Mock up a request
+        JAXBElement<CancelTargetType> cancelTargetType = 
+            new JAXBElement<CancelTargetType>(
+                QNameConstants.CANCEL_TARGET, CancelTargetType.class, cancelTarget
+            );
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        request.getAny().add(cancelTargetType);
+        
+        // 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);
+        
+        // Cancel a token
+        RequestSecurityTokenResponseType response = 
+            cancelOperation.cancel(request, webServiceContext);
+        assertTrue(validateResponse(response));
+        
+        // Now try to cancel again
+        try {
+            cancelOperation.cancel(request, webServiceContext);
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    /*
+     * Create a security context object
+     */
+    private SecurityContext createSecurityContext(final Principal p) {
+        return new SecurityContext() {
+            public Principal getUserPrincipal() {
+                return p;
+            }
+            public boolean isUserInRole(String role) {
+                return false;
+            }
+        };
+    }
+    
+    /**
+     * Return true if the response has a valid RequestTokenCancelled element, false otherwise
+     */
+    private boolean validateResponse(RequestSecurityTokenResponseType response) {
+        assertTrue(response != null && response.getAny() != null && !response.getAny().isEmpty());
+        
+        for (Object requestObject : response.getAny()) {
+            if (requestObject instanceof JAXBElement<?>) {
+                JAXBElement<?> jaxbElement = (JAXBElement<?>) requestObject;
+                if (QNAME_REQ_TOKEN_CANCELLED.equals(jaxbElement.getName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    private Properties getEncryptionProperties() {
+        Properties properties = new Properties();
+        properties.put(
+            "org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"
+        );
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "stsspass");
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.file", "stsstore.jks");
+        
+        return properties;
+    }
+    
+    private TokenProviderResponse createSCT() throws WSSecurityException {
+        TokenProvider sctTokenProvider = new SCTProvider();
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(STSUtils.TOKEN_TYPE_SCT_05_12);
+        
+        assertTrue(sctTokenProvider.canHandleToken(STSUtils.TOKEN_TYPE_SCT_05_12));
+        TokenProviderResponse providerResponse = sctTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+
+        return providerResponse;
+    }
+
+    private TokenProviderParameters createProviderParameters(String tokenType) throws WSSecurityException {
+        TokenProviderParameters parameters = new TokenProviderParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(tokenType);
+        parameters.setTokenRequirements(tokenRequirements);
+        
+        KeyRequirements keyRequirements = new KeyRequirements();
+        parameters.setKeyRequirements(keyRequirements);
+
+        parameters.setCache(cache);
+        
+        parameters.setPrincipal(new CustomTokenPrincipal("alice"));
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        parameters.setWebServiceContext(webServiceContext);
+        
+        parameters.setAppliesToAddress("http://dummy-service.com/dummy");
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        parameters.setStsProperties(stsProperties);
+        
+        parameters.setEncryptionProperties(new EncryptionProperties());
+        
+        return parameters;
+    }
+
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,73 @@
+/**
+ * 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.operation;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.sts.token.provider.TokenProvider;
+import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.sts.token.provider.TokenProviderResponse;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.message.token.BinarySecurity;
+
+/**
+ * A Dummy TokenProvider for use in the unit tests. It mocks up a dummy BinarySecurityToken.
+ */
+public class DummyTokenProvider implements TokenProvider {
+    
+    public static final String TOKEN_TYPE = 
+        "http://dummy-token-type.com/dummy";
+    public static final String BASE64_NS = 
+        WSConstants.SOAPMESSAGE_NS + "#Base64Binary";
+    
+    public boolean canHandleToken(String tokenType) {
+        if (TOKEN_TYPE.equals(tokenType)) {
+            return true;
+        }
+        return false;
+    }
+    
+    public TokenProviderResponse createToken(TokenProviderParameters tokenParameters) {
+        try {
+            Document doc = DOMUtils.createDocument();
+            
+            // Mock up a dummy BinarySecurityToken
+            String id = "BST-1234";
+            BinarySecurity bst = new BinarySecurity(doc);
+            bst.addWSSENamespace();
+            bst.addWSUNamespace();
+            bst.setID(id);
+            bst.setValueType(TOKEN_TYPE);
+            bst.setEncodingType(BASE64_NS);
+            bst.setToken("12345678".getBytes());
+            
+            TokenProviderResponse response = new TokenProviderResponse();
+            response.setToken(bst.getElement());
+            response.setTokenId(id);
+            
+            return response;
+        } catch (Exception e) {
+            throw new STSException("Can't serialize SAML assertion", e, STSException.REQUEST_FAILED);
+        }
+    }
+
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/DummyTokenValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.sts.operation;
+
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.token.validator.TokenValidator;
+import org.apache.cxf.sts.token.validator.TokenValidatorParameters;
+import org.apache.cxf.sts.token.validator.TokenValidatorResponse;
+import org.apache.cxf.ws.security.sts.provider.model.secext.BinarySecurityTokenType;
+
+/**
+ * A Dummy TokenValidator for use in the unit tests. It validates the status of a
+ * dummy BinarySecurityToken by checking the token value.
+ */
+public class DummyTokenValidator implements TokenValidator {
+    
+    public static final String TOKEN_TYPE = 
+        "http://dummy-token-type.com/dummy";
+    
+    public boolean canHandleToken(ReceivedToken validateTarget) {
+        Object token = validateTarget.getToken();
+        if ((token instanceof BinarySecurityTokenType)
+            && TOKEN_TYPE.equals(((BinarySecurityTokenType)token).getValueType())) {
+            return true;
+        }
+        return false;
+    }
+    
+
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        ReceivedToken validateTarget = tokenRequirements.getValidateTarget();
+        
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        response.setValid(false);
+        
+        if (validateTarget != null && validateTarget.isBinarySecurityToken()) {
+            BinarySecurityTokenType binarySecurity = 
+                (BinarySecurityTokenType)validateTarget.getToken();
+            if ("12345678".equals(binarySecurity.getValue())) {
+                response.setValid(true);
+            }
+        }
+        
+        return response;
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueEncryptedUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueEncryptedUnitTest.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueEncryptedUnitTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueEncryptedUnitTest.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,524 @@
+/**
+ * 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.operation;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.bind.JAXBElement;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxws.context.WebServiceContextImpl;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.service.ServiceMBean;
+import org.apache.cxf.sts.service.StaticService;
+import org.apache.cxf.sts.token.provider.TokenProvider;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseCollectionType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+
+/**
+ * Some unit tests for issuing encrypted tokens.
+ */
+public class IssueEncryptedUnitTest extends org.junit.Assert {
+    
+    /**
+     * Test to successfully issue a (dummy) encrypted token.
+     */
+    @org.junit.Test
+    public void testIssueEncryptedToken() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+    }
+    
+    /**
+     * Test for various options relating to specifying a name for encryption
+     */
+    @org.junit.Test
+    public void testEncryptionName() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token - this will fail as the STSProperties has no encryption name specified
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on no encryption name");
+        } catch (STSException ex) {
+            // expected
+        }
+        
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        service.setEncryptionProperties(encryptionProperties);
+        
+        // Issue a token - this should work as the Service is configured with an EncryptionName
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+    }
+    
+    
+    /**
+     * Test for various options relating to configuring an algorithm for encryption
+     */
+    @org.junit.Test
+    public void testConfiguredEncryptionAlgorithm() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        encryptionProperties.setEncryptionAlgorithm(WSConstants.TRIPLE_DES);
+        service.setEncryptionProperties(encryptionProperties);
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token - this should use a (new) default encryption algorithm as configured
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        encryptionProperties.setEncryptionAlgorithm(WSConstants.KEYTRANSPORT_RSA15);
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on a bad encryption algorithm");
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Test for various options relating to receiving an algorithm for encryption
+     */
+    @org.junit.Test
+    public void testReceivedEncryptionAlgorithm() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        service.setEncryptionProperties(encryptionProperties);
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        JAXBElement<String> encryptionAlgorithmType = 
+            new JAXBElement<String>(
+                QNameConstants.ENCRYPTION_ALGORITHM, String.class, WSConstants.TRIPLE_DES
+            );
+        request.getAny().add(encryptionAlgorithmType);
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Now specify a non-supported algorithm
+        List<String> acceptedAlgorithms = Collections.singletonList(WSConstants.KEYTRANSPORT_RSA15);
+        encryptionProperties.setAcceptedEncryptionAlgorithms(acceptedAlgorithms);
+        request.getAny().remove(request.getAny().size() - 1);
+        encryptionAlgorithmType = 
+            new JAXBElement<String>(
+                QNameConstants.ENCRYPTION_ALGORITHM, String.class, WSConstants.KEYTRANSPORT_RSA15
+            );
+        request.getAny().add(encryptionAlgorithmType);
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on a bad encryption algorithm");
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    
+    /**
+     * Test for various options relating to configuring a key-wrap algorithm
+     */
+    @org.junit.Test
+    public void testConfiguredKeyWrapAlgorithm() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        encryptionProperties.setKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSAOEP);
+        service.setEncryptionProperties(encryptionProperties);
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token - this should use a (new) default key-wrap algorithm as configured
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        encryptionProperties.setKeyWrapAlgorithm(WSConstants.AES_128);
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on a bad key-wrap algorithm");
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Test for various options relating to configuring a key-wrap algorithm
+     */
+    @org.junit.Test
+    public void testSpecifiedKeyWrapAlgorithm() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        service.setEncryptionProperties(encryptionProperties);
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        JAXBElement<String> encryptionAlgorithmType = 
+            new JAXBElement<String>(
+                QNameConstants.KEYWRAP_ALGORITHM, String.class, WSConstants.KEYTRANSPORT_RSAOEP
+            );
+        request.getAny().add(encryptionAlgorithmType);
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Now specify a non-supported algorithm
+        String aesKw = "http://www.w3.org/2001/04/xmlenc#kw-aes128";
+        List<String> acceptedAlgorithms = Collections.singletonList(aesKw);
+        encryptionProperties.setAcceptedKeyWrapAlgorithms(acceptedAlgorithms);
+        request.getAny().remove(request.getAny().size() - 1);
+        encryptionAlgorithmType = 
+            new JAXBElement<String>(
+                QNameConstants.KEYWRAP_ALGORITHM, String.class, aesKw
+            );
+        request.getAny().add(encryptionAlgorithmType);
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on a bad key-wrap algorithm");
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Test for various options relating to configuring a KeyIdentifier
+     */
+    @org.junit.Test
+    public void testConfiguredKeyIdentifiers() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        issueOperation.setEncryptIssuedToken(true);
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new DummyTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        EncryptionProperties encryptionProperties = new EncryptionProperties();
+        encryptionProperties.setEncryptionName("myservicekey");
+        encryptionProperties.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+        service.setEncryptionProperties(encryptionProperties);
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto encryptionCrypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(encryptionCrypto);
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        issueOperation.setStsProperties(stsProperties);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, DummyTokenProvider.TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Issue a token - use various KeyIdentifiers
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        encryptionProperties.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+        issueOperation.issue(request, webServiceContext);
+        
+        encryptionProperties.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+        issueOperation.issue(request, webServiceContext);
+        
+        encryptionProperties.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
+        issueOperation.issue(request, webServiceContext);
+        
+        try {
+            encryptionProperties.setKeyIdentifierType(WSConstants.BST);
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected on a bad key identifier");
+        } catch (STSException ex) {
+            // expected
+        }
+    }
+    
+    
+    /*
+     * Mock up an AppliesTo element using the supplied address
+     */
+    private Element createAppliesToElement(String addressUrl) {
+        Document doc = DOMUtils.createDocument();
+        Element appliesTo = doc.createElementNS(STSConstants.WSP_NS, "wsp:AppliesTo");
+        appliesTo.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsp", STSConstants.WSP_NS);
+        Element endpointRef = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:EndpointReference");
+        endpointRef.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05);
+        Element address = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:Address");
+        address.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05);
+        address.setTextContent(addressUrl);
+        endpointRef.appendChild(address);
+        appliesTo.appendChild(endpointRef);
+        return appliesTo;
+    }
+    
+    private Properties getEncryptionProperties() {
+        Properties properties = new Properties();
+        properties.put(
+            "org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"
+        );
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "stsspass");
+        properties.put("org.apache.ws.security.crypto.merlin.keystore.file", "stsstore.jks");
+        
+        return properties;
+    }
+    
+    
+}



Mime
View raw message