cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1173182 [4/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/provider/SAMLTokenProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,356 @@
+/**
+ * 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.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.saml.ext.SAMLParms;
+import org.apache.ws.security.saml.ext.bean.AttributeStatementBean;
+import org.apache.ws.security.saml.ext.bean.AuthDecisionStatementBean;
+import org.apache.ws.security.saml.ext.bean.AuthenticationStatementBean;
+import org.apache.ws.security.saml.ext.bean.ConditionsBean;
+import org.apache.ws.security.saml.ext.bean.SubjectBean;
+
+/**
+ * A TokenProvider implementation that provides a SAML Token.
+ */
+public class SAMLTokenProvider implements TokenProvider {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SAMLTokenProvider.class);
+    
+    private List<AttributeStatementProvider> attributeStatementProviders;
+    private List<AuthenticationStatementProvider> authenticationStatementProviders;
+    private List<AuthDecisionStatementProvider> authenticationDecisionStatementProviders;
+    private SubjectProvider subjectProvider = new DefaultSubjectProvider();
+    private ConditionsProvider conditionsProvider = new DefaultConditionsProvider();
+    private boolean signToken = true;
+    
+    /**
+     * Return true if this TokenProvider implementation is capable of providing a token
+     * that corresponds to the given TokenType.
+     */
+    public boolean canHandleToken(String tokenType) {
+        if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType) || WSConstants.SAML2_NS.equals(tokenType)
+            || WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType) || WSConstants.SAML_NS.equals(tokenType)) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Create a token given a TokenProviderParameters
+     */
+    public TokenProviderResponse createToken(TokenProviderParameters tokenParameters) {
+        testKeyType(tokenParameters);
+        byte[] secret = null;
+        byte[] entropyBytes = null;
+        long keySize = 0;
+        boolean computedKey = false;
+        KeyRequirements keyRequirements = tokenParameters.getKeyRequirements();
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        LOG.fine("Handling token of type: " + tokenRequirements.getTokenType());
+        
+        if (STSConstants.SYMMETRIC_KEY_KEYTYPE.equals(keyRequirements.getKeyType())) {
+            SymmetricKeyHandler keyHandler = new SymmetricKeyHandler(tokenParameters);
+            keyHandler.createSymmetricKey();
+            secret = keyHandler.getSecret();
+            entropyBytes = keyHandler.getEntropyBytes();
+            keySize = keyHandler.getKeySize();
+            computedKey = keyHandler.isComputedKey();
+        } 
+        
+        try {
+            Document doc = DOMUtils.createDocument();
+            AssertionWrapper assertion = createSamlToken(tokenParameters, secret, doc);
+            Element token = assertion.toDOM(doc);
+            
+            TokenProviderResponse response = new TokenProviderResponse();
+            response.setToken(token);
+            String tokenType = tokenRequirements.getTokenType();
+            if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType) 
+                || WSConstants.SAML2_NS.equals(tokenType)) {
+                response.setTokenId(token.getAttribute("ID"));
+            } else {
+                response.setTokenId(token.getAttribute("AssertionID"));
+            }
+            response.setLifetime(conditionsProvider.getLifetime());
+            response.setEntropy(entropyBytes);
+            if (keySize > 0) {
+                response.setKeySize(keySize);
+            }
+            response.setComputedKey(computedKey);
+            
+            return response;
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "", e);
+            throw new STSException("Can't serialize SAML assertion", e, STSException.REQUEST_FAILED);
+        }
+    }
+    
+    /**
+     * Set the List of AttributeStatementProviders.
+     */
+    public void setAttributeStatementProviders(
+        List<AttributeStatementProvider> attributeStatementProviders
+    ) {
+        this.attributeStatementProviders = attributeStatementProviders;
+    }
+    
+    /**
+     * Get the List of AttributeStatementProviders.
+     */
+    public List<AttributeStatementProvider> getAttributeStatementProviders() {
+        return attributeStatementProviders;
+    }
+    
+    /**
+     * Set the List of AuthenticationStatementProviders.
+     */
+    public void setAuthenticationStatementProviders(
+        List<AuthenticationStatementProvider> authnStatementProviders
+    ) {
+        this.authenticationStatementProviders = authnStatementProviders;
+    }
+    
+    /**
+     * Get the List of AuthenticationStatementProviders.
+     */
+    public List<AuthenticationStatementProvider> getAuthenticationStatementProviders() {
+        return authenticationStatementProviders;
+    }
+    
+    /**
+     * Set the List of AuthDecisionStatementProviders.
+     */
+    public void setAuthDecisionStatementProviders(
+        List<AuthDecisionStatementProvider> authDecisionStatementProviders
+    ) {
+        this.authenticationDecisionStatementProviders = authDecisionStatementProviders;
+    }
+    
+    /**
+     * Get the List of AuthDecisionStatementProviders.
+     */
+    public List<AuthDecisionStatementProvider> getAuthDecisionStatementProviders() {
+        return authenticationDecisionStatementProviders;
+    }
+
+    /**
+     * Set the SubjectProvider.
+     */
+    public void setSubjectProvider(SubjectProvider subjectProvider) {
+        this.subjectProvider = subjectProvider;
+    }
+    
+    /**
+     * Get the SubjectProvider.
+     */
+    public SubjectProvider getSubjectProvider() {
+        return subjectProvider;
+    }
+    
+    /**
+     * Set the ConditionsProvider
+     */
+    public void setConditionsProvider(ConditionsProvider conditionsProvider) {
+        this.conditionsProvider = conditionsProvider;
+    }
+    
+    /**
+     * Get the ConditionsProvider
+     */
+    public ConditionsProvider getConditionsProvider() {
+        return conditionsProvider;
+    }
+
+    /**
+     * Return whether the provided token will be signed or not. Default is true.
+     */
+    public boolean isSignToken() {
+        return signToken;
+    }
+
+    /**
+     * Set whether the provided token will be signed or not. Default is true.
+     */
+    public void setSignToken(boolean signToken) {
+        this.signToken = signToken;
+    }
+
+    private AssertionWrapper createSamlToken(
+        TokenProviderParameters tokenParameters, byte[] secret, Document doc
+    ) throws Exception {
+        SamlCallbackHandler handler = createCallbackHandler(tokenParameters, secret, doc);
+        
+        SAMLParms samlParms = new SAMLParms();
+        samlParms.setCallbackHandler(handler);
+        AssertionWrapper assertion = new AssertionWrapper(samlParms);
+        
+        if (signToken) {
+            STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+            
+            String alias = stsProperties.getSignatureUsername();
+            if (alias == null || "".equals(alias)) {
+                Crypto signatureCrypto = stsProperties.getSignatureCrypto();
+                if (signatureCrypto != null) {
+                    alias = signatureCrypto.getDefaultX509Identifier();
+                    LOG.fine("Signature alias is null so using default alias: " + alias);
+                }
+            }
+            // Get the password
+            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
+            LOG.fine("Creating SAML Token");
+            stsProperties.getCallbackHandler().handle(cb);
+            String password = cb[0].getPassword();
+    
+            LOG.fine("Signing SAML Token");
+            boolean useKeyValue = stsProperties.getSignatureProperties().isUseKeyValue();
+            assertion.signAssertion(alias, password, stsProperties.getSignatureCrypto(), useKeyValue);
+        }
+        
+        return assertion;
+    }
+    
+    public SamlCallbackHandler createCallbackHandler(
+        TokenProviderParameters tokenParameters, byte[] secret, Document doc
+    ) throws Exception {
+        // Parse the AttributeStatements
+        List<AttributeStatementBean> attrBeanList = null;
+        if (attributeStatementProviders != null && attributeStatementProviders.size() > 0) {
+            attrBeanList = new ArrayList<AttributeStatementBean>();
+            for (AttributeStatementProvider statementProvider : attributeStatementProviders) {
+                AttributeStatementBean statementBean = statementProvider.getStatement(tokenParameters);
+                if (statementBean != null) {
+                    LOG.fine(
+                        "AttributeStatements" + statementBean.toString() 
+                        + "returned by AttributeStatementProvider " 
+                        + statementProvider.getClass().getName()
+                    );
+                    attrBeanList.add(statementBean);
+                }
+            }
+        }
+        
+        // Parse the AuthenticationStatements
+        List<AuthenticationStatementBean> authBeanList = null;
+        if (authenticationStatementProviders != null && authenticationStatementProviders.size() > 0) {
+            authBeanList = new ArrayList<AuthenticationStatementBean>();
+            for (AuthenticationStatementProvider statementProvider : authenticationStatementProviders) {
+                AuthenticationStatementBean statementBean = 
+                    statementProvider.getStatement(tokenParameters);
+                if (statementBean != null) {
+                    LOG.fine(
+                        "AuthenticationStatement" + statementBean.toString() 
+                        + "returned by AuthenticationStatementProvider " 
+                        + statementProvider.getClass().getName()
+                    );
+                    authBeanList.add(statementBean);
+                }
+            }
+        }
+        
+        // Parse the AuthDecisionStatements
+        List<AuthDecisionStatementBean> authDecisionBeanList = null;
+        if (authenticationDecisionStatementProviders != null 
+            && authenticationDecisionStatementProviders.size() > 0) {
+            authDecisionBeanList = new ArrayList<AuthDecisionStatementBean>();
+            for (AuthDecisionStatementProvider statementProvider 
+                : authenticationDecisionStatementProviders) {
+                AuthDecisionStatementBean statementBean = 
+                    statementProvider.getStatement(tokenParameters);
+                if (statementBean != null) {
+                    LOG.fine(
+                        "AuthDecisionStatement" + statementBean.toString() 
+                        + "returned by AuthDecisionStatementProvider " 
+                        + statementProvider.getClass().getName()
+                    );
+                    authDecisionBeanList.add(statementBean);
+                }
+            }
+        }
+        
+        // If no statements, then default to the DefaultAttributeStatementProvider
+        if ((attrBeanList == null || attrBeanList.isEmpty()) 
+            && (authBeanList == null || authBeanList.isEmpty())
+            && (authDecisionBeanList == null || authDecisionBeanList.isEmpty())) {
+            attrBeanList = new ArrayList<AttributeStatementBean>();
+            AttributeStatementProvider attributeProvider = new DefaultAttributeStatementProvider();
+            AttributeStatementBean attributeBean = attributeProvider.getStatement(tokenParameters);
+            attrBeanList.add(attributeBean);
+        }
+        
+        // Get the Subject and Conditions
+        SubjectBean subjectBean = subjectProvider.getSubject(tokenParameters, doc, secret);
+        ConditionsBean conditionsBean = conditionsProvider.getConditions(tokenParameters);
+        
+        // Set all of the beans on the SamlCallbackHandler
+        SamlCallbackHandler handler = new SamlCallbackHandler();
+        handler.setTokenProviderParameters(tokenParameters);
+        handler.setSubjectBean(subjectBean);
+        handler.setConditionsBean(conditionsBean);
+        handler.setAttributeBeans(attrBeanList);
+        handler.setAuthenticationBeans(authBeanList);
+        handler.setAuthDecisionStatementBeans(authDecisionBeanList);
+        
+        return handler;
+    }
+    
+    /**
+     * Do some tests on the KeyType parameter.
+     */
+    private void testKeyType(TokenProviderParameters tokenParameters) {
+        KeyRequirements keyRequirements = tokenParameters.getKeyRequirements();
+
+        String keyType = keyRequirements.getKeyType();
+        if (STSConstants.PUBLIC_KEY_KEYTYPE.equals(keyType)) {
+            if (keyRequirements.getCertificate() == null) {
+                LOG.log(Level.WARNING, "A PublicKey Keytype is requested, but no certificate is provided");
+                throw new STSException(
+                    "No client certificate for PublicKey KeyType", STSException.INVALID_REQUEST
+                );
+            }
+        } else if (!STSConstants.SYMMETRIC_KEY_KEYTYPE.equals(keyType)
+            && !STSConstants.BEARER_KEY_KEYTYPE.equals(keyType) && keyType != null) {
+            LOG.log(Level.WARNING, "An unknown KeyType was requested: " + keyType);
+            throw new STSException("Unknown KeyType", STSException.INVALID_REQUEST);
+        }
+        
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SCTProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SCTProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SCTProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SCTProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,170 @@
+/**
+ * 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.provider;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.trust.STSUtils;
+
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.ConversationException;
+import org.apache.ws.security.message.token.SecurityContextToken;
+
+/**
+ * A TokenProvider implementation that provides a SecurityContextToken.
+ */
+public class SCTProvider implements TokenProvider {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SCTProvider.class);
+    private boolean returnEntropy = true;
+    private long lifetime = 300L;
+    
+    /**
+     * Return the lifetime of the generated SCT
+     * @return the lifetime of the generated SCT
+     */
+    public long getLifetime() {
+        return lifetime;
+    }
+
+    /**
+     * Set the lifetime of the generated SCT
+     * @param lifetime the lifetime of the generated SCT
+     */
+    public void setLifetime(long lifetime) {
+        this.lifetime = lifetime;
+    }
+
+    /**
+     * Return true if this TokenProvider implementation is capable of providing a token
+     * that corresponds to the given TokenType.
+     */
+    public boolean canHandleToken(String tokenType) {
+        if (STSUtils.TOKEN_TYPE_SCT_05_02.equals(tokenType) 
+            || STSUtils.TOKEN_TYPE_SCT_05_12.equals(tokenType)) {
+            return true;
+        }
+        return false;
+    }
+        
+    /**
+     * Set whether Entropy is returned to the client or not
+     * @param returnEntropy whether Entropy is returned to the client or not
+     */
+    public void setReturnEntropy(boolean returnEntropy) {
+        this.returnEntropy = returnEntropy;
+    }
+
+    /**
+     * Get whether Entropy is returned to the client or not
+     * @return whether Entropy is returned to the client or not
+     */
+    public boolean isReturnEntropy() {
+        return returnEntropy;
+    }
+    
+    /**
+     * Create a token given a TokenProviderParameters
+     */
+    public TokenProviderResponse createToken(TokenProviderParameters tokenParameters) {
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        LOG.fine("Handling token of type: " + tokenRequirements.getTokenType());
+        
+        if (tokenParameters.getCache() == null) {
+            LOG.log(Level.FINE, "A cache must be configured to use the SCTProvider");
+            throw new STSException("Can't serialize SCT", STSException.REQUEST_FAILED);
+        }
+
+        SymmetricKeyHandler keyHandler = new SymmetricKeyHandler(tokenParameters);
+        keyHandler.createSymmetricKey();
+        
+        try {
+            Document doc = DOMUtils.createDocument();
+            SecurityContextToken sct =
+                new SecurityContextToken(getWSCVersion(tokenRequirements.getTokenType()), doc);
+    
+            TokenProviderResponse response = new TokenProviderResponse();
+            response.setToken(sct.getElement());
+            response.setTokenId(sct.getIdentifier());
+            if (returnEntropy) {
+                response.setEntropy(keyHandler.getEntropyBytes());
+            }
+            long keySize = keyHandler.getKeySize();
+            response.setKeySize(keySize);
+            response.setComputedKey(keyHandler.isComputedKey());
+            
+            // putting the secret key into the cache
+            if (lifetime > 0) {
+                Integer lifetimeInteger = new Integer(Long.valueOf(lifetime).intValue());
+                tokenParameters.getCache().put(
+                    sct.getIdentifier(), keyHandler.getSecret(), lifetimeInteger
+                );
+            } else {
+                tokenParameters.getCache().put(sct.getIdentifier(), keyHandler.getSecret());
+            }
+            
+            // Create the references
+            TokenReference attachedReference = new TokenReference();
+            attachedReference.setIdentifier(sct.getID());
+            attachedReference.setUseDirectReference(true);
+            attachedReference.setWsseValueType(tokenRequirements.getTokenType());
+            response.setAttachedReference(attachedReference);
+            
+            TokenReference unAttachedReference = new TokenReference();
+            unAttachedReference.setIdentifier(sct.getIdentifier());
+            unAttachedReference.setUseDirectReference(true);
+            unAttachedReference.setWsseValueType(tokenRequirements.getTokenType());
+            response.setUnattachedReference(unAttachedReference);
+            
+            response.setLifetime(lifetime);
+            
+            return response;
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "", e);
+            throw new STSException("Can't serialize SCT", e, STSException.REQUEST_FAILED);
+        }
+    }
+    
+    /**
+     * Get the Secure Conversation version from the TokenType parameter
+     */
+    private static int getWSCVersion(String tokenType) throws ConversationException {
+        if (tokenType == null) {
+            return ConversationConstants.DEFAULT_VERSION;
+        }
+
+        if (tokenType.startsWith(ConversationConstants.WSC_NS_05_02)) {
+            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_02);
+        } else if (tokenType.startsWith(ConversationConstants.WSC_NS_05_12)) {
+            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_12);
+        } else {
+            throw new ConversationException("unsupportedSecConvVersion");
+        }
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SamlCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SamlCallbackHandler.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SamlCallbackHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SamlCallbackHandler.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,166 @@
+/**
+ * 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.provider;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.TokenRequirements;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.saml.ext.SAMLCallback;
+import org.apache.ws.security.saml.ext.bean.AttributeStatementBean;
+import org.apache.ws.security.saml.ext.bean.AuthDecisionStatementBean;
+import org.apache.ws.security.saml.ext.bean.AuthenticationStatementBean;
+import org.apache.ws.security.saml.ext.bean.ConditionsBean;
+import org.apache.ws.security.saml.ext.bean.SubjectBean;
+import org.opensaml.common.SAMLVersion;
+
+/**
+ * This CallbackHandler implementation is populated with SAML Beans by the SAMLTokenProvider, and is tasked
+ * with setting them on a SAMLCallback object, which will be parsed (by WSS4J) into a SAML Assertion.
+ */
+public class SamlCallbackHandler implements CallbackHandler {
+    private TokenProviderParameters tokenParameters;
+    private List<AttributeStatementBean> attributeBeans;
+    private List<AuthenticationStatementBean> authBeans;
+    private List<AuthDecisionStatementBean> authDecisionBeans;
+    private ConditionsBean conditionsBean;
+    private SubjectBean subjectBean;
+    
+    /**
+     * Set the list of AttributeBeans.
+     */
+    public void setAttributeBeans(List<AttributeStatementBean> attributeBeanList) {
+        this.attributeBeans = attributeBeanList;
+    }
+    
+    /**
+     * Set the list of AuthenticationBeans.
+     */
+    public void setAuthenticationBeans(List<AuthenticationStatementBean> authBeanList) {
+        this.authBeans = authBeanList;
+    }
+    
+    /**
+     * Set the list of AuthDecisionBeans.
+     */
+    public void setAuthDecisionStatementBeans(List<AuthDecisionStatementBean> authDecisionBeanList) {
+        this.authDecisionBeans = authDecisionBeanList;
+    }
+
+    /**
+     * Set the SubjectBean
+     */
+    public void setSubjectBean(SubjectBean subjectBean) {
+        this.subjectBean = subjectBean;
+    }
+    
+    /**
+     * Set the ConditionsBean
+     */
+    public void setConditionsBean(ConditionsBean conditionsBean) {
+        this.conditionsBean = conditionsBean;
+    }
+    
+    /**
+     * Set the TokenProviderParameters.
+     */
+    public void setTokenProviderParameters(TokenProviderParameters tokenProviderParameters) {
+        this.tokenParameters = tokenProviderParameters;
+    }
+    
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof SAMLCallback) {
+                SAMLCallback callback = (SAMLCallback) callbacks[i];
+
+                // Set the Subject
+                if (subjectBean != null) {
+                    callback.setSubject(subjectBean);
+                }
+                
+                // Set the token Type.
+                TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+                String tokenType = tokenRequirements.getTokenType();
+                if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
+                    || WSConstants.SAML2_NS.equals(tokenType)) {
+                    callback.setSamlVersion(SAMLVersion.VERSION_20);
+                } else {
+                    callback.setSamlVersion(SAMLVersion.VERSION_11);
+                    setSubjectOnBeans();
+                }
+                
+                // Set the issuer
+                STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+                callback.setIssuer(stsProperties.getIssuer());
+
+                // Set the statements
+                if (attributeBeans != null && !attributeBeans.isEmpty()) {
+                    callback.setAttributeStatementData(attributeBeans);
+                }
+                if (authBeans != null && !authBeans.isEmpty()) {
+                    callback.setAuthenticationStatementData(authBeans);
+                }
+                if (authDecisionBeans != null && !authDecisionBeans.isEmpty()) {
+                    callback.setAuthDecisionStatementData(authDecisionBeans);
+                }
+                
+                // Set the conditions
+                callback.setConditions(conditionsBean);
+            }
+        }
+    }
+    
+    /**
+     * For SAML 1.1 default to setting the SubjectBean on the statements if they
+     * don't already have a Subject defined.
+     */
+    private void setSubjectOnBeans() {
+        if (attributeBeans != null) {
+            for (AttributeStatementBean attributeBean : attributeBeans) {
+                if (attributeBean.getSubject() == null) {
+                    attributeBean.setSubject(subjectBean);
+                }
+            }
+        }
+        if (authBeans != null) {
+            for (AuthenticationStatementBean authBean : authBeans) {
+                if (authBean.getSubject() == null) {
+                    authBean.setSubject(subjectBean);
+                }
+            }
+        }
+        if (authDecisionBeans != null) {
+            for (AuthDecisionStatementBean authDecisionBean : authDecisionBeans) {
+                if (authDecisionBean.getSubject() == null) {
+                    authDecisionBean.setSubject(subjectBean);
+                }
+            }
+        }
+
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SubjectProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SubjectProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SubjectProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SubjectProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.sts.token.provider;
+
+import org.w3c.dom.Document;
+import org.apache.ws.security.saml.ext.bean.SubjectBean;
+
+/**
+ * An interface that allows a pluggable way of obtaining a SAML SubjectBean used to populate the
+ * Subject of a SAML Assertion.
+ */
+public interface SubjectProvider {
+
+    /**
+     * Get a SubjectBean object.
+     */
+    SubjectBean getSubject(TokenProviderParameters providerParameters, Document doc, byte[] secret);
+        
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,150 @@
+/**
+ * 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.provider;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.SignatureProperties;
+import org.apache.cxf.sts.request.Entropy;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.conversation.ConversationException;
+import org.apache.ws.security.conversation.dkalgo.P_SHA1;
+import org.apache.ws.security.util.WSSecurityUtil;
+
+/**
+ * Some common functionality relating to parsing and generating Symmetric Keys.
+ */
+public class SymmetricKeyHandler {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SymmetricKeyHandler.class);
+    
+    private int keySize = 256;
+    private Entropy clientEntropy;
+    private byte[] entropyBytes;
+    private byte[] secret;
+    private boolean computedKey;
+    
+    public SymmetricKeyHandler(TokenProviderParameters tokenParameters) {
+        KeyRequirements keyRequirements = tokenParameters.getKeyRequirements();
+        
+        // Test KeySize
+        keySize = Long.valueOf(keyRequirements.getKeySize()).intValue();
+        STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+        SignatureProperties signatureProperties = stsProperties.getSignatureProperties();
+        if (keySize < signatureProperties.getMinimumKeySize()
+            || keySize > signatureProperties.getMaximumKeySize()) {
+            keySize = Long.valueOf(signatureProperties.getKeySize()).intValue();
+            LOG.log(
+                Level.WARNING, "Received KeySize of " + keyRequirements.getKeySize() 
+                + " not accepted so defaulting to " + signatureProperties.getKeySize()
+            );
+        }
+
+        // Test Entropy
+        clientEntropy = keyRequirements.getEntropy();
+        if (clientEntropy == null) {
+            LOG.log(Level.WARNING, "A SymmetricKey KeyType is requested, but no client entropy is provided");
+        } else {
+            String binarySecurityType = clientEntropy.getBinarySecretType();
+            byte[] nonce = clientEntropy.getBinarySecretValue();
+            if (!STSConstants.NONCE_TYPE.equals(binarySecurityType)) {
+                LOG.log(Level.WARNING, "The type " + binarySecurityType + " is not supported");
+                throw new STSException(
+                    "No user supplied entropy for SymmetricKey case", STSException.INVALID_REQUEST
+                );
+            }
+            if (nonce == null || (nonce.length < (keySize / 8))) {
+                LOG.log(Level.WARNING, "User Entropy rejected");
+                clientEntropy = null;
+            }
+            String computedKeyAlgorithm = keyRequirements.getComputedKeyAlgorithm();
+            if (!STSConstants.COMPUTED_KEY_PSHA1.equals(computedKeyAlgorithm)) {
+                LOG.log(
+                    Level.WARNING, 
+                    "The computed key algorithm of " + computedKeyAlgorithm + " is not supported"
+                );
+                throw new STSException(
+                    "Computed Key Algorithm not supported", STSException.INVALID_REQUEST
+                );
+            }
+        }
+    }
+
+    /**
+     * Create the Symmetric Key
+     */
+    public void createSymmetricKey() {
+        try {
+            entropyBytes = WSSecurityUtil.generateNonce(keySize / 8);
+            secret = entropyBytes;
+            computedKey = false;
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.WARNING, "", ex);
+            throw new STSException("Error in creating symmetric key", ex, STSException.INVALID_REQUEST);
+        } 
+        if (clientEntropy != null) {
+            byte[] nonce = clientEntropy.getBinarySecretValue();
+            try {
+                P_SHA1 psha1 = new P_SHA1();
+                secret = psha1.createKey(nonce, entropyBytes, 0, keySize / 8);
+                computedKey = true;
+            } catch (ConversationException ex) {
+                LOG.log(Level.WARNING, "", ex);
+                throw new STSException("Error in creating symmetric key", STSException.INVALID_REQUEST);
+            }
+        }
+    }
+    
+    /**
+     * Get the KeySize.
+     */
+    public long getKeySize() {
+        return keySize;
+    }
+    
+    /**
+     * Get the Entropy bytes
+     */
+    public byte[] getEntropyBytes() {
+        return entropyBytes;
+    }
+
+    /**
+     * Get the secret
+     */
+    public byte[] getSecret() {
+        return secret;
+    }
+    
+    /**
+     * Get whether this is a computed key or not
+     */
+    public boolean isComputedKey() {
+        return computedKey;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProvider.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProvider.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProvider.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,38 @@
+/**
+ * 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.provider;
+
+/**
+ * An interface that can provide a security token.
+ */
+public interface TokenProvider {
+    
+    /**
+     * Return true if this TokenProvider implementation is capable of providing a token
+     * that corresponds to the given TokenType.
+     */
+    boolean canHandleToken(String tokenType);
+
+    /**
+     * Create a token given a TokenProviderParameters
+     */
+    TokenProviderResponse createToken(TokenProviderParameters tokenParameters);
+
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderParameters.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderParameters.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderParameters.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderParameters.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,142 @@
+/**
+ * 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.provider;
+
+import java.security.Principal;
+import java.util.Map;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.cache.STSCache;
+import org.apache.cxf.sts.claims.ClaimsManager;
+import org.apache.cxf.sts.claims.RequestClaimCollection;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+
+/**
+ * This class encapsulates the parameters that will be passed to a TokenProvider instance to
+ * create a token. It consists of both parameters that have been extracted from the request,
+ * as well as configuration specific to the STS itself.
+ */
+public class TokenProviderParameters {
+
+    private STSPropertiesMBean stsProperties;
+    private EncryptionProperties encryptionProperties;
+    private Principal principal;
+    private WebServiceContext webServiceContext;
+    private RequestClaimCollection requestedClaims;
+    private KeyRequirements keyRequirements;
+    private TokenRequirements tokenRequirements;
+    private String appliesToAddress;
+    private ClaimsManager claimsManager;
+    private Map<String, Object> additionalProperties;
+    private STSCache cache;
+    
+    public STSCache getCache() {
+        return cache;
+    }
+
+    public void setCache(STSCache cache) {
+        this.cache = cache;
+    }
+
+    public ClaimsManager getClaimsManager() {
+        return claimsManager;
+    }
+
+    public void setClaimsManager(ClaimsManager claimsManager) {
+        this.claimsManager = claimsManager;
+    }
+        
+    public String getAppliesToAddress() {
+        return appliesToAddress;
+    }
+
+    public void setAppliesToAddress(String appliesToAddress) {
+        this.appliesToAddress = appliesToAddress;
+    }
+
+    public TokenRequirements getTokenRequirements() {
+        return tokenRequirements;
+    }
+
+    public void setTokenRequirements(TokenRequirements tokenRequirements) {
+        this.tokenRequirements = tokenRequirements;
+    }
+    
+    public KeyRequirements getKeyRequirements() {
+        return keyRequirements;
+    }
+
+    public void setKeyRequirements(KeyRequirements keyRequirements) {
+        this.keyRequirements = keyRequirements;
+    }
+
+    public RequestClaimCollection getRequestedClaims() {
+        return requestedClaims;
+    }
+
+    public void setRequestedClaims(RequestClaimCollection requestedClaims) {
+        this.requestedClaims = requestedClaims;
+    }
+
+    public STSPropertiesMBean getStsProperties() {
+        return stsProperties;
+    }
+
+    public void setStsProperties(STSPropertiesMBean stsProperties) {
+        this.stsProperties = stsProperties;
+    }
+    
+    public EncryptionProperties getEncryptionProperties() {
+        return encryptionProperties;
+    }
+
+    public void setEncryptionProperties(EncryptionProperties encryptionProperties) {
+        this.encryptionProperties = encryptionProperties;
+    }
+    
+    public WebServiceContext getWebServiceContext() {
+        return webServiceContext;
+    }
+
+    public void setWebServiceContext(WebServiceContext webServiceContext) {
+        this.webServiceContext = webServiceContext;
+    }
+    
+    public void setPrincipal(Principal principal) {
+        this.principal = principal;
+    }
+    
+    public Principal getPrincipal() {
+        return principal;
+    }
+    
+    public void setAdditionalProperties(Map<String, Object> additionalProperties) {
+        this.additionalProperties = additionalProperties;
+    }
+    
+    public Map<String, Object> getAdditionalProperties() {
+        return additionalProperties;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderResponse.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderResponse.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderResponse.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderResponse.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,162 @@
+/**
+ * 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.provider;
+
+import org.w3c.dom.Element;
+
+/**
+ * This class encapsulates the response from a TokenProvider instance after creating a token.
+ */
+public class TokenProviderResponse {
+
+    private Element token;
+    private String tokenId;
+    private long lifetime;
+    private byte[] entropy;
+    private long keySize;
+    private boolean computedKey;
+    private TokenReference attachedReference;
+    private TokenReference unAttachedReference;
+    
+    /**
+     * Return true if the entropy represents a Computed Key.
+     */
+    public boolean isComputedKey() {
+        return computedKey;
+    }
+
+    /**
+     * Set whether the entropy represents a Computed Key or not
+     */
+    public void setComputedKey(boolean computedKey) {
+        this.computedKey = computedKey;
+    }
+
+    /**
+     * Get the KeySize that the TokenProvider set
+     */
+    public long getKeySize() {
+        return keySize;
+    }
+
+    /**
+     * Set the KeySize
+     */
+    public void setKeySize(long keySize) {
+        this.keySize = keySize;
+    }
+
+    /**
+     * Set the token
+     * @param token the token to set
+     */
+    public void setToken(Element token) {
+        this.token = token;
+    }
+    
+    /**
+     * Get the token
+     * @return the token to set
+     */
+    public Element getToken() {
+        return token;
+    }
+
+    /**
+     * Set the token Id
+     * @param tokenId the token Id
+     */
+    public void setTokenId(String tokenId) {
+        this.tokenId = tokenId;
+    }
+    
+    /**
+     * Get the token Id
+     * @return the token Id
+     */
+    public String getTokenId() {
+        return tokenId;
+    }
+    
+    /**
+     * Set the lifetime of the Token to be returned in seconds
+     * @param lifetime the lifetime of the Token to be returned in seconds
+     */
+    public void setLifetime(long lifetime) {
+        this.lifetime = lifetime;
+    }
+    
+    /**
+     * Get the lifetime of the Token to be returned in seconds
+     * @return the lifetime of the Token to be returned in seconds
+     */
+    public long getLifetime() {
+        return lifetime;
+    }
+    
+    /**
+     * Set the entropy associated with the token.
+     * @param entropy the entropy associated with the token.
+     */
+    public void setEntropy(byte[] entropy) {
+        this.entropy = entropy;
+    }
+    
+    /**
+     * Get the entropy associated with the token.
+     * @return the entropy associated with the token.
+     */
+    public byte[] getEntropy() {
+        return entropy;
+    }
+    
+    /**
+     * Set the attached TokenReference
+     * @param attachtedReference the attached TokenReference
+     */
+    public void setAttachedReference(TokenReference attachedReference) {
+        this.attachedReference = attachedReference;
+    }
+    
+    /**
+     * Get the attached TokenReference
+     * @return the attached TokenReference
+     */
+    public TokenReference getAttachedReference() {
+        return attachedReference;
+    }
+    
+    /**
+     * Set the unattached TokenReference
+     * @param unAttachedReference  Set the unattached TokenReference
+     */
+    public void setUnattachedReference(TokenReference unattachedReference) {
+        this.unAttachedReference = unattachedReference;
+    }
+    
+    /**
+     * Get the unattached TokenReference
+     * @return the unattached TokenReference
+     */
+    public TokenReference getUnAttachedReference() {
+        return unAttachedReference;
+    }
+
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenReference.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenReference.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenReference.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenReference.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,114 @@
+/**
+ * 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.provider;
+
+/**
+ * A class that encapsulates how a token should be referenced
+ */
+public class TokenReference {
+
+    private String identifier;
+    private String wsse11TokenType;
+    private String wsseValueType;
+    private boolean useDirectReference;
+    private boolean useKeyIdentifier;
+    
+    /**
+     * Get the identifier associated with this token
+     * @return the identifier associated with this token
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+    
+    /**
+     * Set the identifier associated with this token
+     * @param identifier the identifier associated with this token
+     */
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+    
+    /**
+     * Get the wsse11 TokenType attribute
+     * @return the wsse11 TokenType attribute
+     */
+    public String getWsse11TokenType() {
+        return wsse11TokenType;
+    }
+    
+    /**
+     * Set the wsse11 TokenType attribute
+     * @param wsse11TokenType the wsse11 TokenType attribute
+     */
+    public void setWsse11TokenType(String wsse11TokenType) {
+        this.wsse11TokenType = wsse11TokenType;
+    }
+    
+    /**
+     * Get the wsse ValueType attribute
+     * @return the wsse ValueType attribute
+     */
+    public String getWsseValueType() {
+        return wsseValueType;
+    }
+    
+    /**
+     * Set the wsse ValueType attribute
+     * @param wsseValueType the wsse ValueType attribute
+     */
+    public void setWsseValueType(String wsseValueType) {
+        this.wsseValueType = wsseValueType;
+    }
+    
+    /**
+     * Get whether to use direct reference to refer to this token
+     * @return whether to use direct reference to refer to this token
+     */
+    public boolean isUseDirectReference() {
+        return useDirectReference;
+    }
+    
+    /**
+     * Set whether to use direct reference to refer to this token
+     * @param useDirectReference whether to use direct reference to refer to this token
+     */
+    public void setUseDirectReference(boolean useDirectReference) {
+        this.useDirectReference = useDirectReference;
+    }
+    
+    /**
+     * Get whether to use a KeyIdentifier to refer to this token
+     * @return whether to use a KeyIdentifier to refer to this token
+     */
+    public boolean isUseKeyIdentifier() {
+        return useKeyIdentifier;
+    }
+    
+    /**
+     * Set whether to use a KeyIdentifier to refer to this token
+     * @param useKeyIdentifier whether to use a KeyIdentifier to refer to this token
+     */
+    public void setUseKeyIdentifier(boolean useKeyIdentifier) {
+        this.useKeyIdentifier = useKeyIdentifier;
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,131 @@
+/**
+ * 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.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+
+import org.apache.ws.security.SAMLTokenPrincipal;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+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.saml.SAMLKeyInfo;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.validate.Credential;
+import org.apache.ws.security.validate.SignatureTrustValidator;
+
+/**
+ * Validate a SAML Assertion. It is valid if it was issued and signed by this STS.
+ */
+public class SAMLTokenValidator implements TokenValidator {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SAMLTokenValidator.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 Element) {
+            Element tokenElement = (Element)token;
+            String namespace = tokenElement.getNamespaceURI();
+            String localname = tokenElement.getLocalName();
+            if ((WSConstants.SAML_NS.equals(namespace) || WSConstants.SAML2_NS.equals(namespace))
+                && "Assertion".equals(localname)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        LOG.fine("Validating SAML Token");
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        ReceivedToken validateTarget = tokenRequirements.getValidateTarget();
+        STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+        Crypto sigCrypto = stsProperties.getSignatureCrypto();
+        CallbackHandler callbackHandler = stsProperties.getCallbackHandler();
+        String issuer = stsProperties.getIssuer();
+
+        RequestData requestData = new RequestData();
+        requestData.setSigCrypto(sigCrypto);
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        requestData.setWssConfig(wssConfig);
+        requestData.setCallbackHandler(callbackHandler);
+
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        response.setValid(false);
+        
+        if (validateTarget != null && validateTarget.isDOMElement()) {
+            try {
+                Element validateTargetElement = (Element)validateTarget.getToken();
+                AssertionWrapper assertion = new AssertionWrapper(validateTargetElement);
+                if (!assertion.isSigned()) {
+                    LOG.log(Level.WARNING, "The received assertion is not signed, and therefore not trusted");
+                    return response;
+                }
+                // Verify the signature
+                assertion.verifySignature(
+                        requestData, new WSDocInfo(validateTargetElement.getOwnerDocument())
+                );
+                
+                // Now verify trust on the signature
+                Credential trustCredential = new Credential();
+                SAMLKeyInfo samlKeyInfo = assertion.getSignatureKeyInfo();
+                trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
+                trustCredential.setCertificates(samlKeyInfo.getCerts());
+                
+                SignatureTrustValidator trustValidator = new SignatureTrustValidator();
+                trustValidator.validate(trustCredential, requestData);
+                
+                // Finally check the issuer
+                String assertionIssuer = assertion.getIssuerString();
+                
+                if (issuer.equals(assertionIssuer)) {
+                    response.setValid(true);
+                    SAMLTokenPrincipal samlPrincipal = new SAMLTokenPrincipal(assertion);
+                    response.setPrincipal(samlPrincipal);
+                }
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+            }
+        }
+
+        return response;
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SCTValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SCTValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SCTValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SCTValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,110 @@
+/**
+ * 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.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+
+import org.apache.cxf.ws.security.trust.STSUtils;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityContextToken;
+
+/**
+ * This class validates a SecurityContextToken.
+ */
+public class SCTValidator implements TokenValidator {
+    
+    /**
+     * This tag refers to the secret key (byte[]) associated with a SecurityContextToken that has been
+     * validated. It is inserted into the additional properties map of the response, so that it can be
+     * retrieved and inserted into a generated token by a TokenProvider instance.
+     */
+    public static final String SCT_VALIDATOR_SECRET = "sct-validator-secret";
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SCTValidator.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 Element) {
+            Element tokenElement = (Element)token;
+            String namespace = tokenElement.getNamespaceURI();
+            String localname = tokenElement.getLocalName();
+            if ((STSUtils.SCT_NS_05_02.equals(namespace) 
+                || STSUtils.SCT_NS_05_12.equals(namespace))
+                && "SecurityContextToken".equals(localname)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        LOG.fine("Validating SecurityContextToken");
+        
+        if (tokenParameters.getCache() == null) {
+            LOG.log(Level.FINE, "A cache must be configured to use the SCTValidator");
+            TokenValidatorResponse response = new TokenValidatorResponse();
+            response.setValid(false);
+            return response;
+        }
+        
+        TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
+        ReceivedToken validateTarget = tokenRequirements.getValidateTarget();
+
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        response.setValid(false);
+        
+        if (validateTarget != null && validateTarget.isDOMElement()) {
+            try {
+                Element validateTargetElement = (Element)validateTarget.getToken();
+                SecurityContextToken sct = new SecurityContextToken(validateTargetElement);
+                String identifier = sct.getIdentifier();
+                byte[] secret = (byte[])tokenParameters.getCache().get(identifier);
+                if (secret == null) {
+                    LOG.fine("Identifier: " + identifier + " is not found in the cache");
+                    return response;
+                }
+                response.setValid(true);
+                Map<String, Object> properties = new HashMap<String, Object>();
+                properties.put(SCT_VALIDATOR_SECRET, secret);
+                response.setAdditionalProperties(properties);
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+            }
+        }
+        return response;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +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.token.validator;
+
+import org.apache.cxf.sts.request.ReceivedToken;
+
+/**
+ * An interface that can validate a security token.
+ */
+public interface TokenValidator {
+    
+    /**
+     * Return true if this TokenValidator implementation is capable of validating the
+     * ReceivedToken argument.
+     */
+    boolean canHandleToken(ReceivedToken validateTarget);
+
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters);
+
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorParameters.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorParameters.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorParameters.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorParameters.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,93 @@
+/**
+ * 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.Principal;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.cache.STSCache;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.TokenRequirements;
+
+/**
+ * This class encapsulates the parameters that will be passed to a TokenValidator instance to
+ * validate a token. It consists of both parameters that have been extracted from the request,
+ * as well as configuration specific to the Operation itself (STSPropertiesMBean etc.)
+ */
+public class TokenValidatorParameters {
+
+    private STSPropertiesMBean stsProperties;
+    private Principal principal;
+    private WebServiceContext webServiceContext;
+    private KeyRequirements keyRequirements;
+    private TokenRequirements tokenRequirements;
+    private STSCache cache;
+    
+    public STSCache getCache() {
+        return cache;
+    }
+
+    public void setCache(STSCache cache) {
+        this.cache = cache;
+    }
+    
+    public TokenRequirements getTokenRequirements() {
+        return tokenRequirements;
+    }
+
+    public void setTokenRequirements(TokenRequirements tokenRequirements) {
+        this.tokenRequirements = tokenRequirements;
+    }
+
+    public KeyRequirements getKeyRequirements() {
+        return keyRequirements;
+    }
+
+    public void setKeyRequirements(KeyRequirements keyRequirements) {
+        this.keyRequirements = keyRequirements;
+    }
+    
+    public STSPropertiesMBean getStsProperties() {
+        return stsProperties;
+    }
+
+    public void setStsProperties(STSPropertiesMBean stsProperties) {
+        this.stsProperties = stsProperties;
+    }
+    
+    public WebServiceContext getWebServiceContext() {
+        return webServiceContext;
+    }
+
+    public void setWebServiceContext(WebServiceContext webServiceContext) {
+        this.webServiceContext = webServiceContext;
+    }
+    
+    public void setPrincipal(Principal principal) {
+        this.principal = principal;
+    }
+    
+    public Principal getPrincipal() {
+        return principal;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorResponse.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorResponse.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorResponse.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/TokenValidatorResponse.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,57 @@
+/**
+ * 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.Principal;
+import java.util.Map;
+
+/**
+ * This class encapsulates the response from a TokenValidator instance after validating a token.
+ */
+public class TokenValidatorResponse {
+
+    private boolean valid;
+    private Principal principal;
+    private Map<String, Object> additionalProperties;
+    
+    public void setValid(boolean valid) {
+        this.valid = valid;
+    }
+    
+    public boolean isValid() {
+        return valid;
+    }
+    
+    public void setPrincipal(Principal principal) {
+        this.principal = principal;
+    }
+    
+    public Principal getPrincipal() {
+        return principal;
+    }
+    
+    public void setAdditionalProperties(Map<String, Object> additionalProperties) {
+        this.additionalProperties = additionalProperties;
+    }
+    
+    public Map<String, Object> getAdditionalProperties() {
+        return additionalProperties;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java?rev=1173182&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java Tue Sep 20 15:12:07 2011
@@ -0,0 +1,219 @@
+/**
+ * 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.io.IOException;
+import java.security.Principal;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.bind.JAXBElement;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.QNameConstants;
+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.EncodedString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.PasswordString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+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.UsernameToken;
+
+/**
+ * This class validates a wsse UsernameToken.
+ */
+public class UsernameTokenValidator implements TokenValidator {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(UsernameTokenValidator.class);
+    
+    /**
+     * Return true if this TokenValidator implementation is capable of validating the
+     * ReceivedToken argument.
+     */
+    public boolean canHandleToken(ReceivedToken validateTarget) {
+        if (validateTarget.getToken() instanceof UsernameTokenType) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        LOG.fine("Validating UsernameToken");
+        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();
+        requestData.setWssConfig(wssConfig);
+        requestData.setCallbackHandler(callbackHandler);
+
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        response.setValid(false);
+        
+        if (validateTarget != null && validateTarget.isUsernameToken()) {
+            //
+            // Parse the JAXB object
+            //
+            String passwordType = null;
+            String passwordValue = null;
+            String nonce = null;
+            String created = null;
+            UsernameTokenType usernameTokenType = (UsernameTokenType)validateTarget.getToken();
+            for (Object any : usernameTokenType.getAny()) {
+                if (any instanceof JAXBElement<?>) {
+                    JAXBElement<?> anyElement = (JAXBElement<?>) any;
+                    if (QNameConstants.PASSWORD.equals(anyElement.getName())) {
+                        PasswordString passwordString = 
+                            (PasswordString)anyElement.getValue();
+                        passwordType = passwordString.getType();
+                        passwordValue = passwordString.getValue();
+                    } else if (QNameConstants.NONCE.equals(anyElement.getName())) {
+                        EncodedString nonceES = (EncodedString)anyElement.getValue();
+                        nonce = nonceES.getValue();
+                        // Encoding Type must be equal to Base64Binary
+                        if (!BinarySecurity.BASE64_ENCODING.equals(nonceES.getEncodingType())) {
+                            String errorMsg = "The UsernameToken nonce element has a bad encoding type";
+                            LOG.log(Level.WARNING, errorMsg + " : " + nonceES.getEncodingType());
+                            return response;
+                        }
+                    }
+                } else if (any instanceof Element) {
+                    Element element = (Element)any;
+                    if (WSConstants.WSU_NS.equals(element.getNamespaceURI()) 
+                        && WSConstants.CREATED_LN.equals(element.getLocalName())) {
+                        created = element.getTextContent();
+                    }
+                }
+            }
+            
+            //
+            // Validate the token
+            //
+            try {
+                boolean valid = 
+                    verifyPassword(
+                        usernameTokenType.getUsername().getValue(), passwordValue, passwordType, 
+                        nonce, created, requestData
+                    );
+                response.setValid(valid);
+                if (valid) {
+                    Principal principal = 
+                        createPrincipal(
+                            usernameTokenType.getUsername().getValue(), passwordValue, passwordType, 
+                            nonce, created
+                        );
+                    response.setPrincipal(principal);
+                }
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+            }
+        }
+            
+        return response;
+    }
+    
+    private boolean verifyPassword(
+        String username,
+        String passwordValue,
+        String passwordType,
+        String nonce,
+        String createdTime,
+        RequestData requestData
+    ) throws WSSecurityException {
+        WSPasswordCallback pwCb = 
+            new WSPasswordCallback(
+                username, null, passwordType, WSPasswordCallback.USERNAME_TOKEN, requestData
+            );
+        try {
+            requestData.getCallbackHandler().handle(new Callback[]{pwCb});
+        } catch (IOException e) {
+            LOG.log(Level.WARNING, "", e);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        } catch (UnsupportedCallbackException e) {
+            LOG.log(Level.WARNING, "", e);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        }
+        String origPassword = pwCb.getPassword();
+        if (origPassword == null) {
+            LOG.fine("Callback supplied no password for: " + username);
+            return false;
+        }
+        if (WSConstants.PASSWORD_DIGEST.equals(passwordType)) {
+            String passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
+            if (!passDigest.equals(passwordValue)) {
+                return false;
+            }
+        } else {
+            if (!origPassword.equals(passwordValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Create a principal based on the authenticated UsernameToken.
+     */
+    private Principal createPrincipal(
+        String username,
+        String passwordValue,
+        String passwordType,
+        String nonce,
+        String createdTime
+    ) {
+        boolean hashed = false;
+        if (WSConstants.PASSWORD_DIGEST.equals(passwordType)) {
+            hashed = true;
+        }
+        WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(username, hashed);
+        principal.setNonce(nonce);
+        principal.setPassword(passwordValue);
+        principal.setCreatedTime(createdTime);
+        principal.setPasswordType(passwordType);
+        return principal;
+    }
+    
+}



Mime
View raw message