You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2012/03/13 13:25:14 UTC

svn commit: r1300092 - in /cxf/trunk: rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/ services/sts/sts-core/src/main/java/org/apache/cxf/sts/ services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/ services/sts/sts-core/src/mai...

Author: coheigea
Date: Tue Mar 13 12:25:13 2012
New Revision: 1300092

URL: http://svn.apache.org/viewvc?rev=1300092&view=rev
Log:
[CXF-4158] - Added support for renewing SecurityContextTokens

Added:
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenRenewOperation.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SCTRenewer.java
      - copied, changed from r1300084, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewer.java
      - copied, changed from r1300084, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerParameters.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerResponse.java
    cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/RenewSCTUnitTest.java
    cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/renewer/
    cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/renewer/SCTRenewerTest.java
    cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SecurityContextTokenRenewTest.java
Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/QNameConstants.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/TokenRequirements.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java
    cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/secure_conv/cxf-sts.xml

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java Tue Mar 13 12:25:13 2012
@@ -684,6 +684,7 @@ public class STSClient implements Config
         
         if (target != null) {
             writer.writeStartElement("wst", "RenewTarget", namespace);
+            client.getRequestContext().put(SecurityConstants.TOKEN, target);
             Element el = target.getUnattachedReference();
             if (el == null) {
                 el = target.getAttachedReference();

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/QNameConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/QNameConstants.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/QNameConstants.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/QNameConstants.java Tue Mar 13 12:25:13 2012
@@ -50,6 +50,8 @@ public final class QNameConstants {
         WS_TRUST_FACTORY.createValidateTarget(null).getName();
     public static final QName CANCEL_TARGET =
         WS_TRUST_FACTORY.createCancelTarget(null).getName();
+    public static final QName RENEW_TARGET =
+        WS_TRUST_FACTORY.createRenewTarget(null).getName();
     public static final QName LIFETIME = 
         WS_TRUST_FACTORY.createLifetime(null).getName();
     public static final QName REQUEST_TYPE = 

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenRenewOperation.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenRenewOperation.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenRenewOperation.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenRenewOperation.java Tue Mar 13 12:25:13 2012
@@ -0,0 +1,204 @@
+/**
+ * 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.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.RequestParser;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.token.provider.TokenReference;
+import org.apache.cxf.sts.token.renewer.TokenRenewer;
+import org.apache.cxf.sts.token.renewer.TokenRenewerParameters;
+import org.apache.cxf.sts.token.renewer.TokenRenewerResponse;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.LifetimeType;
+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.sts.provider.model.RequestedReferenceType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType;
+import org.apache.cxf.ws.security.sts.provider.operation.RenewOperation;
+import org.apache.ws.security.WSSecurityException;
+
+/**
+ * An implementation of the IssueOperation interface to renew tokens.
+ */
+public class TokenRenewOperation extends AbstractOperation implements RenewOperation {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(TokenRenewOperation.class);
+
+    private List<TokenRenewer> tokenRenewers = new ArrayList<TokenRenewer>();
+    
+    public void setTokenRenewers(List<TokenRenewer> tokenRenewerList) {
+        this.tokenRenewers = tokenRenewerList;
+    }
+    
+    public List<TokenRenewer> getTokenRenewers() {
+        return tokenRenewers;
+    }
+
+    public RequestSecurityTokenResponseType renew(
+        RequestSecurityTokenType request, WebServiceContext context
+    ) {
+        RequestParser requestParser = parseRequest(request, context);
+
+        KeyRequirements keyRequirements = requestParser.getKeyRequirements();
+        TokenRequirements tokenRequirements = requestParser.getTokenRequirements();
+        
+        ReceivedToken renewTarget = tokenRequirements.getRenewTarget();
+        if (renewTarget == null || renewTarget.getToken() == null) {
+            throw new STSException("No element presented for renewal", STSException.INVALID_REQUEST);
+        }
+        if (tokenRequirements.getTokenType() == null) {
+            LOG.fine("Received TokenType is null");
+        }
+        
+        TokenRenewerParameters renewerParameters = new TokenRenewerParameters();
+        renewerParameters.setStsProperties(stsProperties);
+        renewerParameters.setPrincipal(context.getUserPrincipal());
+        renewerParameters.setWebServiceContext(context);
+        renewerParameters.setTokenStore(getTokenStore());
+        
+        renewerParameters.setKeyRequirements(keyRequirements);
+        renewerParameters.setTokenRequirements(tokenRequirements);   
+        
+        //
+        // Renew token
+        //
+        TokenRenewerResponse tokenResponse = null;
+        for (TokenRenewer tokenRenewer : tokenRenewers) {
+            if (tokenRenewer.canHandleToken(renewTarget)) {
+                try {
+                    tokenResponse = tokenRenewer.renewToken(renewerParameters);
+                } catch (RuntimeException ex) {
+                    LOG.log(Level.WARNING, "", ex);
+                    throw new STSException(
+                        "Error while renewing a token", ex, STSException.REQUEST_FAILED
+                    );
+                }
+                break;
+            }
+        }
+        if (tokenResponse == null) {
+            LOG.fine("No Token Renewer has been found that can handle this token");
+            throw new STSException(
+                "No token Renewer found for requested token type: " 
+                + tokenRequirements.getTokenType(), 
+                STSException.REQUEST_FAILED
+            );
+        }
+        
+        if (!tokenResponse.isTokenRenewed()) {
+            LOG.log(Level.WARNING, "Token renewal failed.");
+            throw new STSException("Token renewal failed.");
+        }
+        
+        // prepare response
+        try {
+            return createResponse(tokenResponse, tokenRequirements, keyRequirements, context);
+        } catch (Throwable ex) {
+            LOG.log(Level.WARNING, "", ex);
+            throw new STSException("Error in creating the response", ex, STSException.REQUEST_FAILED);
+        }
+    }
+    
+    private RequestSecurityTokenResponseType createResponse(
+        TokenRenewerResponse tokenResponse,
+        TokenRequirements tokenRequirements,
+        KeyRequirements keyRequirements,
+        WebServiceContext webServiceContext
+    ) throws WSSecurityException {
+        RequestSecurityTokenResponseType response = 
+                QNameConstants.WS_TRUST_FACTORY.createRequestSecurityTokenResponseType();
+        String context = tokenRequirements.getContext();
+        if (context != null) {
+            response.setContext(context);
+        }
+        
+        // TokenType
+        JAXBElement<String> jaxbTokenType = 
+            QNameConstants.WS_TRUST_FACTORY.createTokenType(tokenRequirements.getTokenType());
+        response.getAny().add(jaxbTokenType);
+        
+        // RequestedSecurityToken
+        RequestedSecurityTokenType requestedTokenType = 
+            QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityTokenType();
+        JAXBElement<RequestedSecurityTokenType> requestedToken = 
+            QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(requestedTokenType);
+        requestedTokenType.setAny(tokenResponse.getRenewedToken());
+        response.getAny().add(requestedToken);
+        
+        if (returnReferences) {
+            // RequestedAttachedReference
+            TokenReference attachedReference = tokenResponse.getAttachedReference();
+            RequestedReferenceType requestedAttachedReferenceType = null;
+            if (attachedReference != null) {
+                requestedAttachedReferenceType = createRequestedReference(attachedReference, true);
+            } else {
+                requestedAttachedReferenceType = 
+                    createRequestedReference(
+                            tokenResponse.getTokenId(), tokenRequirements.getTokenType(), true
+                    );
+            }
+
+            JAXBElement<RequestedReferenceType> requestedAttachedReference = 
+                QNameConstants.WS_TRUST_FACTORY.createRequestedAttachedReference(
+                        requestedAttachedReferenceType
+                );
+            response.getAny().add(requestedAttachedReference);
+
+            // RequestedUnattachedReference
+            TokenReference unAttachedReference = tokenResponse.getUnAttachedReference();
+            RequestedReferenceType requestedUnattachedReferenceType = null;
+            if (unAttachedReference != null) {
+                requestedUnattachedReferenceType = createRequestedReference(unAttachedReference, false);
+            } else {
+                requestedUnattachedReferenceType = 
+                    createRequestedReference(
+                            tokenResponse.getTokenId(), tokenRequirements.getTokenType(), false
+                    );
+            }
+
+            JAXBElement<RequestedReferenceType> requestedUnattachedReference = 
+                QNameConstants.WS_TRUST_FACTORY.createRequestedUnattachedReference(
+                        requestedUnattachedReferenceType
+                );
+            response.getAny().add(requestedUnattachedReference);
+        }
+        
+        // Lifetime
+        LifetimeType lifetime = createLifetime(tokenResponse.getLifetime());
+        JAXBElement<LifetimeType> lifetimeType = QNameConstants.WS_TRUST_FACTORY.createLifetime(lifetime);
+        response.getAny().add(lifetimeType);
+        
+        return response;
+    }
+
+
+}

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java Tue Mar 13 12:25:13 2012
@@ -62,6 +62,7 @@ import org.apache.cxf.ws.security.sts.pr
 import org.apache.cxf.ws.security.sts.provider.model.EntropyType;
 import org.apache.cxf.ws.security.sts.provider.model.LifetimeType;
 import org.apache.cxf.ws.security.sts.provider.model.OnBehalfOfType;
+import org.apache.cxf.ws.security.sts.provider.model.RenewTargetType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
 import org.apache.cxf.ws.security.sts.provider.model.UseKeyType;
 import org.apache.cxf.ws.security.sts.provider.model.ValidateTargetType;
@@ -260,6 +261,15 @@ public class RequestParser {
             }          
             tokenRequirements.setCancelTarget(cancelTarget);
             LOG.fine("Found CancelTarget token");
+        } else if (QNameConstants.RENEW_TARGET.equals(jaxbElement.getName())) {
+            RenewTargetType renewTargetType = (RenewTargetType)jaxbElement.getValue();
+            ReceivedToken renewTarget = new ReceivedToken(renewTargetType.getAny());
+            if (isTokenReferenced(renewTarget.getToken())) {
+                Element target = fetchTokenElementFromReference(renewTarget.getToken(), wsContext);
+                renewTarget = new ReceivedToken(target);
+            }          
+            tokenRequirements.setRenewTarget(renewTarget);
+            LOG.fine("Found CancelTarget token");
         } else if (QNameConstants.CLAIMS.equals(jaxbElement.getName())) {
             ClaimsType claimsType = (ClaimsType)jaxbElement.getValue();
             RequestClaimCollection requestedClaims = parseClaims(claimsType);

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/TokenRequirements.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/TokenRequirements.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/TokenRequirements.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/TokenRequirements.java Tue Mar 13 12:25:13 2012
@@ -34,6 +34,7 @@ public class TokenRequirements {
     private ReceivedToken onBehalfOf;
     private ReceivedToken actAs;
     private ReceivedToken cancelTarget;
+    private ReceivedToken renewTarget;
     private Lifetime lifetime;
     private RequestClaimCollection claims;
     
@@ -41,6 +42,10 @@ public class TokenRequirements {
         return tokenType;
     }
     
+    public void setTokenType(String tokenType) {
+        this.tokenType = tokenType;
+    }
+    
     public ReceivedToken getCancelTarget() {
         return cancelTarget;
     }
@@ -48,11 +53,15 @@ public class TokenRequirements {
     public void setCancelTarget(ReceivedToken cancelTarget) {
         this.cancelTarget = cancelTarget;
     }
+    
+    public ReceivedToken getRenewTarget() {
+        return renewTarget;
+    }
 
-    public void setTokenType(String tokenType) {
-        this.tokenType = tokenType;
+    public void setRenewTarget(ReceivedToken renewTarget) {
+        this.renewTarget = renewTarget;
     }
-    
+
     public Element getAppliesTo() {
         return appliesTo;
     }

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java Tue Mar 13 12:25:13 2012
@@ -53,7 +53,7 @@ public class SCTCanceller implements Tok
     private boolean verifyProofOfPossession = true;
     
     /**
-     * Return true if this TokenValidator implementation is capable of validating the
+     * Return true if this TokenCanceller implementation is capable of cancelling the
      * ReceivedToken argument.
      */
     public boolean canHandleToken(ReceivedToken targetToken) {

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java Tue Mar 13 12:25:13 2012
@@ -20,7 +20,7 @@ package org.apache.cxf.sts.token.cancell
 
 
 /**
- * This class encapsulates the response from a TokenValidator instance after validating a token.
+ * This class encapsulates the response from a TokenCanceller instance after cancelling a token.
  */
 public class TokenCancellerResponse {
 

Copied: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SCTRenewer.java (from r1300084, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SCTRenewer.java?p2=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SCTRenewer.java&p1=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java&r1=1300084&r2=1300092&rev=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/SCTCanceller.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SCTRenewer.java Tue Mar 13 12:25:13 2012
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.cxf.sts.token.canceller;
+package org.apache.cxf.sts.token.renewer;
 
 import java.util.Arrays;
 import java.util.List;
@@ -32,6 +32,7 @@ import org.apache.cxf.common.logging.Log
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.sts.request.ReceivedToken;
 import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.token.provider.TokenReference;
 import org.apache.cxf.ws.security.sts.provider.STSException;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.trust.STSUtils;
@@ -43,17 +44,34 @@ import org.apache.ws.security.handler.WS
 import org.apache.ws.security.message.token.SecurityContextToken;
 
 /**
- * This class cancels a SecurityContextToken.
+ * This class renews a SecurityContextToken.
  */
-public class SCTCanceller implements TokenCanceller {
+public class SCTRenewer implements TokenRenewer {
 
-    private static final Logger LOG = LogUtils.getL7dLogger(SCTCanceller.class);
+    private static final Logger LOG = LogUtils.getL7dLogger(SCTRenewer.class);
     
     // boolean to enable/disable the check of proof of possession
     private boolean verifyProofOfPossession = true;
+    private long lifetime = 300L;
     
     /**
-     * Return true if this TokenValidator implementation is capable of validating the
+     * 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 TokenRenewer implementation is capable of renewing the
      * ReceivedToken argument.
      */
     public boolean canHandleToken(ReceivedToken targetToken) {
@@ -72,25 +90,25 @@ public class SCTCanceller implements Tok
     }
 
     /**
-     * Cancel a Token using the given TokenCancellerParameters.
+     * Renew a Token using the given TokenRenewerParameters.
      */
-    public TokenCancellerResponse cancelToken(TokenCancellerParameters tokenParameters) {
-        LOG.fine("Trying to cancel a SecurityContextToken");
+    public TokenRenewerResponse renewToken(TokenRenewerParameters tokenParameters) {
+        LOG.fine("Trying to renew a SecurityContextToken");
         TokenRequirements tokenRequirements = tokenParameters.getTokenRequirements();
-        ReceivedToken cancelTarget = tokenRequirements.getCancelTarget();
+        ReceivedToken renewTarget = tokenRequirements.getRenewTarget();
 
-        TokenCancellerResponse response = new TokenCancellerResponse();
-        response.setTokenCancelled(false);
+        TokenRenewerResponse response = new TokenRenewerResponse();
+        response.setTokenRenewed(false);
         
         if (tokenParameters.getTokenStore() == null) {
-            LOG.log(Level.FINE, "A cache must be configured to use the SCTCanceller");
+            LOG.log(Level.FINE, "A cache must be configured to use the SCTRenewer");
             return response;
         }
         
-        if (cancelTarget != null && cancelTarget.isDOMElement()) {
+        if (renewTarget != null && renewTarget.isDOMElement()) {
             try {
-                Element cancelTargetElement = (Element)cancelTarget.getToken();
-                SecurityContextToken sct = new SecurityContextToken(cancelTargetElement);
+                Element renewTargetElement = (Element)renewTarget.getToken();
+                SecurityContextToken sct = new SecurityContextToken(renewTargetElement);
                 String identifier = sct.getIdentifier();
                 SecurityToken token = tokenParameters.getTokenStore().getToken(identifier);
                 if (token == null) {
@@ -104,8 +122,46 @@ public class SCTCanceller implements Tok
                         STSException.INVALID_REQUEST
                     );
                 }
+                // Remove old token from the cache
                 tokenParameters.getTokenStore().remove(token);
-                response.setTokenCancelled(true);
+                
+                // Create a new token corresponding to the old token
+                SecurityToken newToken = new SecurityToken(identifier);
+                newToken.setPrincipal(token.getPrincipal());
+                newToken.setSecret(token.getSecret());
+                if (token.getProperties() != null) {
+                    newToken.setProperties(token.getProperties());
+                }
+                
+                if (lifetime > 0) {
+                    Integer lifetimeInteger = new Integer(Long.valueOf(lifetime).intValue());
+                    tokenParameters.getTokenStore().add(newToken, lifetimeInteger);
+                } else {
+                    tokenParameters.getTokenStore().add(newToken);
+                }
+                
+                response.setTokenRenewed(true);
+                response.setRenewedToken(sct.getElement());
+                
+                // Create the references
+                TokenReference attachedReference = new TokenReference();
+                attachedReference.setIdentifier(sct.getID());
+                attachedReference.setUseDirectReference(true);
+                if (tokenRequirements.getTokenType() != null) {
+                    attachedReference.setWsseValueType(tokenRequirements.getTokenType());
+                }
+                response.setAttachedReference(attachedReference);
+                
+                TokenReference unAttachedReference = new TokenReference();
+                unAttachedReference.setIdentifier(sct.getIdentifier());
+                unAttachedReference.setUseDirectReference(true);
+                if (tokenRequirements.getTokenType() != null) {
+                    unAttachedReference.setWsseValueType(tokenRequirements.getTokenType());
+                }
+                response.setUnattachedReference(unAttachedReference);
+                
+                response.setLifetime(lifetime);
+                
             } catch (WSSecurityException ex) {
                 LOG.log(Level.WARNING, "", ex);
             }
@@ -113,7 +169,7 @@ public class SCTCanceller implements Tok
         return response;
     }
     
-    private boolean matchKey(TokenCancellerParameters tokenParameters, byte[] secretKey) {
+    private boolean matchKey(TokenRenewerParameters tokenParameters, byte[] secretKey) {
         boolean result = false;
         MessageContext messageContext = tokenParameters.getWebServiceContext().getMessageContext();
         final List<WSHandlerResult> handlerResults = 

Copied: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewer.java (from r1300084, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewer.java?p2=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewer.java&p1=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java&r1=1300084&r2=1300092&rev=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/canceller/TokenCancellerResponse.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewer.java Tue Mar 13 12:25:13 2012
@@ -16,22 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.cxf.sts.token.canceller;
+
+package org.apache.cxf.sts.token.renewer;
+
+import org.apache.cxf.sts.request.ReceivedToken;
 
 
 /**
- * This class encapsulates the response from a TokenValidator instance after validating a token.
+ * An interface that can renew a security token.
  */
-public class TokenCancellerResponse {
 
-    private boolean tokenCancelled;
-    
-    public void setTokenCancelled(boolean tokenCancelled) {
-        this.tokenCancelled = tokenCancelled;
-    }
+public interface TokenRenewer {
+
+    /**
+     * boolean for enabling/disabling verification of proof of possession.
+     */
+    void setVerifyProofOfPossession(boolean verifyProofOfPossession);
     
-    public boolean isTokenCancelled() {
-        return tokenCancelled;
-    }
+    /**
+     * Return true if this TokenRenewer implementation is able to renew a token
+     * that corresponds to the given token.
+     */
+    boolean canHandleToken(ReceivedToken cancelTarget);
+
+    /**
+     * Renew a token given a TokenRenewerParameters
+     */
+    TokenRenewerResponse renewToken(TokenRenewerParameters tokenParameters);
     
 }

Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerParameters.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerParameters.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerParameters.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerParameters.java Tue Mar 13 12:25:13 2012
@@ -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.renewer;
+
+import java.security.Principal;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.cache.STSTokenStore;
+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 TokenRenewer instance to
+ * renew 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 TokenRenewerParameters {
+
+    private STSPropertiesMBean stsProperties;
+    private Principal principal;
+    private WebServiceContext webServiceContext;
+    private KeyRequirements keyRequirements;
+    private TokenRequirements tokenRequirements;
+    private STSTokenStore tokenStore;
+    
+    public STSTokenStore getTokenStore() {
+        return tokenStore;
+    }
+
+    public void setTokenStore(STSTokenStore tokenStore) {
+        this.tokenStore = tokenStore;
+    }
+    
+    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/renewer/TokenRenewerResponse.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerResponse.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerResponse.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/TokenRenewerResponse.java Tue Mar 13 12:25:13 2012
@@ -0,0 +1,117 @@
+/**
+ * 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.renewer;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.sts.token.provider.TokenReference;
+
+
+/**
+ * This class encapsulates the response from a TokenRenewer instance after renewing a token.
+ */
+public class TokenRenewerResponse {
+
+    private boolean tokenRenewed;
+    private Element renewedToken;
+    private String tokenId;
+    private long lifetime;
+    private TokenReference attachedReference;
+    private TokenReference unAttachedReference;
+    
+    public void setTokenRenewed(boolean tokenRenewed) {
+        this.tokenRenewed = tokenRenewed;
+    }
+    
+    public boolean isTokenRenewed() {
+        return tokenRenewed;
+    }
+    
+    public void setRenewedToken(Element renewedToken) {
+        this.renewedToken = renewedToken;
+    }
+    
+    public Element getRenewedToken() {
+        return renewedToken;
+    }
+    
+    /**
+     * 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 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;
+    }
+    
+    /**
+     * 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;
+    }
+    
+}

Added: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/RenewSCTUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/RenewSCTUnitTest.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/RenewSCTUnitTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/RenewSCTUnitTest.java Tue Mar 13 12:25:13 2012
@@ -0,0 +1,221 @@
+/**
+ * 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.DefaultInMemoryTokenStore;
+import org.apache.cxf.sts.cache.STSTokenStore;
+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.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.sts.token.renewer.SCTRenewer;
+import org.apache.cxf.sts.token.renewer.TokenRenewer;
+import org.apache.cxf.ws.security.sts.provider.model.RenewTargetType;
+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 renew operation to renew SecurityContextTokens.
+ */
+public class RenewSCTUnitTest extends org.junit.Assert {
+    
+    public static final QName REQUESTED_SECURITY_TOKEN = 
+        QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName();
+    private static final QName QNAME_REQ_SEC_TOKEN = 
+        QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName();
+    
+    private static STSTokenStore tokenStore = new DefaultInMemoryTokenStore();
+    
+    /**
+     * Test to successfully renew a SecurityContextToken
+     */
+    @org.junit.Test
+    public void testRenewSCT() throws Exception {
+        TokenRenewOperation renewOperation = new TokenRenewOperation();
+        renewOperation.setTokenStore(tokenStore);
+        
+        // Add Token Renewer
+        List<TokenRenewer> renewerList = new ArrayList<TokenRenewer>();
+        TokenRenewer sctRenewer = new SCTRenewer();
+        sctRenewer.setVerifyProofOfPossession(false);
+        renewerList.add(sctRenewer);
+        renewOperation.setTokenRenewers(renewerList);
+        
+        // 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");
+        renewOperation.setStsProperties(stsProperties);
+        
+        // Get a SecurityContextToken via the SCTProvider
+        TokenProviderResponse providerResponse = createSCT();
+        Element sct = providerResponse.getToken();
+        Document doc = sct.getOwnerDocument();
+        sct = (Element)doc.appendChild(sct);
+        RenewTargetType renewTarget = new RenewTargetType();
+        renewTarget.setAny(sct);
+        
+        // Mock up a request
+        JAXBElement<RenewTargetType> renewTargetType = 
+            new JAXBElement<RenewTargetType>(
+                QNameConstants.RENEW_TARGET, RenewTargetType.class, renewTarget
+            );
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        request.getAny().add(renewTargetType);
+        
+        // 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);
+        
+        // Renew a token
+        RequestSecurityTokenResponseType response = 
+            renewOperation.renew(request, webServiceContext);
+        assertTrue(validateResponse(response));
+    }
+    
+    /*
+     * 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 RequestedSecurityToken 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_SEC_TOKEN.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.setTokenStore(tokenStore);
+        
+        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/token/renewer/SCTRenewerTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/renewer/SCTRenewerTest.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/renewer/SCTRenewerTest.java (added)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/renewer/SCTRenewerTest.java Tue Mar 13 12:25:13 2012
@@ -0,0 +1,188 @@
+/**
+ * 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.renewer;
+
+import java.util.Properties;
+
+import org.w3c.dom.Document;
+
+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.StaticSTSProperties;
+import org.apache.cxf.sts.cache.DefaultInMemoryTokenStore;
+import org.apache.cxf.sts.cache.STSTokenStore;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+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.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;
+import org.apache.ws.security.message.token.SecurityContextToken;
+
+/**
+ * Some unit tests for renewing a SecurityContextToken via the SCTRenewer.
+ */
+public class SCTRenewerTest extends org.junit.Assert {
+    
+    private static STSTokenStore tokenStore = new DefaultInMemoryTokenStore();
+    
+    /**
+     * Get a (valid) SecurityContextToken and successfully renew it.
+     */
+    @org.junit.Test
+    public void testRenewToken() throws Exception {
+        TokenRenewer sctRenewer = new SCTRenewer();
+        sctRenewer.setVerifyProofOfPossession(false);
+        TokenRenewerParameters renewerParameters = createRenewerParameters();
+        TokenRequirements tokenRequirements = renewerParameters.getTokenRequirements();
+        
+        // Create a RenewTarget consisting of a SecurityContextToken
+        TokenProviderResponse providerResponse = getSecurityContextToken();
+        ReceivedToken renewTarget = new ReceivedToken(providerResponse.getToken());
+        tokenRequirements.setRenewTarget(renewTarget);
+        
+        assertTrue(sctRenewer.canHandleToken(renewTarget));
+        
+        TokenRenewerResponse renewerResponse = sctRenewer.renewToken(renewerParameters);
+        assertTrue(renewerResponse != null);
+        assertTrue(renewerResponse.isTokenRenewed());
+        assertNotNull(renewerResponse.getRenewedToken());
+    }
+    
+    /**
+     * Try to renew an invalid SecurityContextToken
+     */
+    @org.junit.Test
+    public void testRenewInvalidToken() throws Exception {
+        TokenRenewer sctRenewer = new SCTRenewer();
+        sctRenewer.setVerifyProofOfPossession(false);
+        TokenRenewerParameters renewerParameters = createRenewerParameters();
+        TokenRequirements tokenRequirements = renewerParameters.getTokenRequirements();
+        
+        // Create a RenewTarget consisting of a SecurityContextToken
+        Document doc = DOMUtils.createDocument();
+        SecurityContextToken sct = new SecurityContextToken(doc);
+        ReceivedToken cancelTarget = new ReceivedToken(sct.getElement());
+        tokenRequirements.setCancelTarget(cancelTarget);
+        
+        assertTrue(sctRenewer.canHandleToken(cancelTarget));
+        
+        TokenRenewerResponse renewerResponse = sctRenewer.renewToken(renewerParameters);
+        assertTrue(renewerResponse != null);
+        assertFalse(renewerResponse.isTokenRenewed());
+    }
+    
+    private TokenProviderResponse getSecurityContextToken() throws Exception {
+        TokenProvider sctTokenProvider = new SCTProvider();
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(STSUtils.TOKEN_TYPE_SCT_05_12);
+        
+        return sctTokenProvider.createToken(providerParameters);
+    }
+    
+    private TokenRenewerParameters createRenewerParameters() throws WSSecurityException {
+        TokenRenewerParameters parameters = new TokenRenewerParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        parameters.setTokenRequirements(tokenRequirements);
+        
+        KeyRequirements keyRequirements = new KeyRequirements();
+        parameters.setKeyRequirements(keyRequirements);
+        parameters.setTokenStore(tokenStore);
+        
+        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);
+        
+        // Add STSProperties object
+        StaticSTSProperties 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");
+        parameters.setStsProperties(stsProperties);
+        
+        return parameters;
+    }
+    
+    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.setTokenStore(tokenStore);
+        
+        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;
+    }
+    
+    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;
+    }
+    
+    
+}

Added: cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SecurityContextTokenRenewTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SecurityContextTokenRenewTest.java?rev=1300092&view=auto
==============================================================================
--- cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SecurityContextTokenRenewTest.java (added)
+++ cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SecurityContextTokenRenewTest.java Tue Mar 13 12:25:13 2012
@@ -0,0 +1,135 @@
+/**
+ * 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.systest.sts.secure_conv;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.trust.STSClient;
+
+import org.junit.BeforeClass;
+
+/**
+ * In this test case, a CXF client requests a SecurityContextToken from an STS and then renews it. When
+ * renewing the token, the WSDL of the STS has an EndorsingSupportingToken consisting of the 
+ * SecureConversationToken. The client must use the secret associated with the SecurityContextToken it gets 
+ * back from the STS to sign the Timestamp.
+ */
+public class SecurityContextTokenRenewTest extends AbstractBusClientServerTestBase {
+    
+    static final String STSPORT = allocatePort(STSServer.class);
+    
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue(
+                   "Server failed to launch",
+                   // run the server in the same process
+                   // set this to false to fork
+                   launchServer(STSServer.class, true)
+        );
+    }
+
+    @org.junit.Test
+    public void testRenewSecurityContextToken() throws Exception {
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = SecurityContextTokenRenewTest.class.getResource("cxf-client.xml");
+
+        Bus bus = bf.createBus(busFile.toString());
+        SpringBusFactory.setDefaultBus(bus);
+        SpringBusFactory.setThreadDefaultBus(bus);
+        
+        String wsdlLocation = 
+            "https://localhost:" + STSPORT + "/SecurityTokenService/TransportSCT?wsdl";
+        SecurityToken token = 
+            requestSecurityToken(bus, wsdlLocation, true);
+        assertTrue(token.getSecret() != null && token.getSecret().length > 0);
+        
+        // Renew the SecurityContextToken - this should fail as the secret associated with the SCT
+        // is not used to sign some part of the message
+        String port = "{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port";
+        try {
+            renewSecurityToken(bus, wsdlLocation, port, true, token);
+            fail("Failure expected on no proof-of-possession");
+        } catch (Exception ex) {
+            // expected
+        }
+        
+        String endorsingPort = "{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Endorsing_Port";
+        renewSecurityToken(bus, wsdlLocation, endorsingPort, true, token);
+    }
+    
+    private SecurityToken requestSecurityToken(
+        Bus bus, String wsdlLocation, boolean enableEntropy
+    ) throws Exception {
+        STSClient stsClient = new STSClient(bus);
+        stsClient.setWsdlLocation(wsdlLocation);
+        stsClient.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService");
+        stsClient.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port");
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put(SecurityConstants.USERNAME, "alice");
+        properties.put(
+            "ws-security.callback-handler", 
+            "org.apache.cxf.systest.sts.common.CommonCallbackHandler"
+        );
+        properties.put("ws-security.sts.token.properties", "serviceKeystore.properties");
+
+        stsClient.setProperties(properties);
+        stsClient.setSecureConv(true);
+        stsClient.setRequiresEntropy(enableEntropy);
+        stsClient.setKeySize(128);
+        stsClient.setAddressingNamespace("http://www.w3.org/2005/08/addressing");
+
+        return stsClient.requestSecurityToken(null);
+    }
+    
+    private void renewSecurityToken(
+        Bus bus, String wsdlLocation, String port, boolean enableEntropy, SecurityToken securityToken
+    ) throws Exception {
+        STSClient stsClient = new STSClient(bus);
+        stsClient.setWsdlLocation(wsdlLocation);
+        stsClient.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService");
+        stsClient.setEndpointName(port);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put(SecurityConstants.USERNAME, "alice");
+        properties.put(SecurityConstants.SIGNATURE_USERNAME, "myservicekey");
+        properties.put(
+            SecurityConstants.CALLBACK_HANDLER, 
+            "org.apache.cxf.systest.sts.common.CommonCallbackHandler"
+        );
+        properties.put(SecurityConstants.STS_TOKEN_PROPERTIES, "serviceKeystore.properties");
+        properties.put(SecurityConstants.SIGNATURE_PROPERTIES, "serviceKeystore.properties");
+
+        stsClient.setProperties(properties);
+        stsClient.setSecureConv(true);
+        stsClient.setRequiresEntropy(enableEntropy);
+        stsClient.setAddressingNamespace("http://www.w3.org/2005/08/addressing");
+
+        stsClient.renewSecurityToken(securityToken);
+    }
+
+    
+}

Modified: cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/secure_conv/cxf-sts.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/secure_conv/cxf-sts.xml?rev=1300092&r1=1300091&r2=1300092&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/secure_conv/cxf-sts.xml (original)
+++ cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/secure_conv/cxf-sts.xml Tue Mar 13 12:25:13 2012
@@ -53,6 +53,7 @@
 	    <property name="issueOperation" ref="transportIssueDelegate" />
 	    <property name="validateOperation" ref="transportValidateDelegate" />
 	    <property name="cancelOperation" ref="transportCancelDelegate" />
+	    <property name="renewOperation" ref="transportRenewDelegate" />
     </bean>
 
 	<bean id="transportSTSEncryptedProviderBean"
@@ -88,6 +89,12 @@
 		<property name="stsProperties" ref="transportSTSProperties" />
 		<property name="tokenStore" ref="defaultTokenStore" />
 	</bean>
+	
+	<bean id="transportRenewDelegate" class="org.apache.cxf.sts.operation.TokenRenewOperation">
+        <property name="tokenRenewers" ref="transportTokenRenewers" />
+        <property name="stsProperties" ref="transportSTSProperties" />
+        <property name="tokenStore" ref="defaultTokenStore" />
+    </bean>
 
 	<bean id="defaultTokenStore" class="org.apache.cxf.sts.cache.DefaultInMemoryTokenStore">
 	</bean>
@@ -104,6 +111,10 @@
 	<util:list id="transportTokenCancellers">
 		<ref bean="transportSCTCanceller" />
 	</util:list>
+	
+	<util:list id="transportTokenRenewers">
+        <ref bean="transportSCTRenewer" />
+    </util:list>
 
 	<bean id="transportSCTProvider" class="org.apache.cxf.sts.token.provider.SCTProvider">
 	</bean>
@@ -117,6 +128,9 @@
 
 	<bean id="transportSCTCanceller" class="org.apache.cxf.sts.token.canceller.SCTCanceller">
 	</bean>
+	
+	<bean id="transportSCTRenewer" class="org.apache.cxf.sts.token.renewer.SCTRenewer">
+    </bean>
 
 	<bean id="transportService" class="org.apache.cxf.sts.service.StaticService">
 		<property name="endpoints" ref="transportEndpoints" />