title: How to use CXF STS and X509v3 BinarySecurityToken
body: <p>I am trying to make CXF STS work with 509v3 token. It works fine, if only a  username token is configured, but it fails on X509.</p>
  
  <p>I am using CXF inside of JBOSS EAP 6.3.1</p>
  
  <p><strong>Maven Dependencies</strong></p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;dependency&gt;
    &lt;groupId&gt;org.apache.cxf.services.sts&lt;/groupId&gt;
    &lt;artifactId&gt;cxf-services-sts-core&lt;/artifactId&gt;
    &lt;version&gt;2.7.11.redhat-3&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
    &lt;groupId&gt;org.jboss.ws.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;jbossws-cxf-server&lt;/artifactId&gt;
    &lt;version&gt;4.3.0.Final-redhat-3&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p><strong>My WSDL:</strong></p>
  
  <pre class="lang-xml prettyprint-override"><code>...
   &lt;wsp:Policy wsu:Id="UT_policy"&gt;
          &lt;wsp:ExactlyOne&gt;
              &lt;wsp:All&gt;
                  &lt;!--  
                  Disabled for testing - I use SoapUI for sending the request
                  &lt;sp:TransportBinding&gt;
                      &lt;wsp:Policy&gt;
                          &lt;sp:TransportToken&gt;
                              &lt;wsp:Policy&gt;
                                  &lt;sp:HttpsToken RequireClientCertificate="false"/&gt;
                              &lt;/wsp:Policy&gt;
                          &lt;/sp:TransportToken&gt;
                      &lt;/wsp:Policy&gt;
                  &lt;/sp:TransportBinding&gt;              
                  --&gt;
                  &lt;sp:SupportingTokens&gt;               
                      &lt;wsp:Policy&gt;
                          &lt;wsp:ExactlyOne&gt;
                              &lt;wsp:All&gt;
                                  &lt;sp:X509Token IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"&gt;
                                      &lt;wsp:Policy&gt;
                                          &lt;sp:WssX509V3Token10 wsu:Id="token"/&gt;
                                      &lt;/wsp:Policy&gt;
                                  &lt;/sp:X509Token&gt;
                              &lt;/wsp:All&gt;
  &lt;!--                         
  Disabled for Testing. If I activate both, neither work. Somehow CXF ignores the ExactlyOne Element.   
                               &lt;wsp:All&gt;
                                  &lt;sp:UsernameToken wsu:Id="BiPROBasicToken"/&gt;
                              &lt;/wsp:All&gt;--&gt;
                          &lt;/wsp:ExactlyOne&gt;
                      &lt;/wsp:Policy&gt;       
                  &lt;/sp:SupportingTokens&gt;      
              &lt;/wsp:All&gt;
          &lt;/wsp:ExactlyOne&gt;
      &lt;/wsp:Policy&gt;
  </code></pre>
  
  <p>Example Request:    </p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;SOAPENV:Envelope xmlns:SOAPENV='http://schemas.xmlsoap.org/soap/envelope/'&gt;
   &lt;SOAPENV:Header&gt;
    &lt;wsse:Security xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'&gt;
     &lt;wsse:BinarySecurityToken EncodingType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary' ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3' wsu:Id='Token'&gt;
  MIIDMTCCApqgAwI....3aairt
  93OqNtk=
  &lt;/wsse:BinarySecurityToken&gt;
     &lt;Signature xmlns='http://www.w3.org/2000/09/xmldsig#'&gt;
      &lt;SignedInfo&gt;
       &lt;CanonicalizationMethod Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'/&gt;
       &lt;SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/&gt;
       &lt;Reference URI='#body'&gt;
        &lt;Transforms&gt;
         &lt;Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/&gt;
        &lt;/Transforms&gt;
        &lt;DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/&gt;
        &lt;DigestValue&gt;WbLbIc...k=&lt;/DigestValue&gt;
       &lt;/Reference&gt;
       &lt;Reference URI='#Timestamp'&gt;
        &lt;Transforms&gt;
         &lt;Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/&gt;
        &lt;/Transforms&gt;
        &lt;DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/&gt;
        &lt;DigestValue&gt;z3q....9w=&lt;/DigestValue&gt;
       &lt;/Reference&gt;
       &lt;Reference URI='#Token'&gt;
        &lt;Transforms&gt;
         &lt;Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/&gt;
        &lt;/Transforms&gt;
        &lt;DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/&gt;
        &lt;DigestValue&gt;ypE6U....slo=&lt;/DigestValue&gt;
       &lt;/Reference&gt;
      &lt;/SignedInfo&gt;
      &lt;SignatureValue&gt;lW1....Tc=&lt;/SignatureValue&gt;
      &lt;KeyInfo&gt;
       &lt;wsse:SecurityTokenReference&gt;
        &lt;wsse:Reference URI='#Token' ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3'/&gt;
       &lt;/wsse:SecurityTokenReference&gt;
      &lt;/KeyInfo&gt;
     &lt;/Signature&gt;
     &lt;wsu:Timestamp wsu:Id='Timestamp'&gt;
      &lt;wsu:Created&gt;2015-02-09T13:03:11Z&lt;/wsu:Created&gt;
      &lt;wsu:Expires&gt;2015-02-09T13:13:13Z&lt;/wsu:Expires&gt;
     &lt;/wsu:Timestamp&gt;
    &lt;/wsse:Security&gt;
   &lt;/SOAPENV:Header&gt;
   &lt;SOAPENV:Body wsu:Id='body' xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'&gt;
    &lt;wst:RequestSecurityToken xmlns:wst='http://schemas.xmlsoap.org/ws/2005/02/trust'&gt;
     &lt;wst:TokenType&gt;http://schemas.xmlsoap.org/ws/2005/02/sc/sct&lt;/wst:TokenType&gt;
     &lt;wst:RequestType&gt;http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue&lt;/wst:RequestType&gt;
    &lt;/wst:RequestSecurityToken&gt;
   &lt;/SOAPENV:Body&gt;
  &lt;/SOAPENV:Envelope&gt;
  </code></pre>
  
  <p>The request is valid and can not be changed -> it is generated by another program.</p>
  
  <p><strong>Response:</strong></p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
     &lt;soap:Body&gt;
        &lt;soap:Fault&gt;
           &lt;faultcode&gt;soap:Server&lt;/faultcode&gt;
           &lt;faultstring&gt;These policy alternatives can not be satisfied: 
  {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SupportingTokens
  {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}X509Token&lt;/faultstring&gt;
        &lt;/soap:Fault&gt;
     &lt;/soap:Body&gt;
  &lt;/soap:Envelope&gt;
  </code></pre>
  
  <p>I have no clue, if my policydefinition is wrong, or my sts class.</p>
  
  <p><strong>STS Class</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>package net.example;
  
  import java.util.Arrays;
  import java.util.LinkedList;
  import java.util.List;
  import javax.xml.transform.Source;
  import javax.xml.ws.WebServiceProvider;
  import net.example.STSCallbackHandler;
  import org.apache.cxf.annotations.EndpointProperties;
  import org.apache.cxf.annotations.EndpointProperty;
  import org.apache.cxf.sts.StaticSTSProperties;
  import org.apache.cxf.sts.operation.TokenIssueOperation;
  import org.apache.cxf.sts.operation.TokenValidateOperation;
  import org.apache.cxf.sts.service.ServiceMBean;
  import org.apache.cxf.sts.service.StaticService;
  import org.apache.cxf.sts.token.provider.SCTProvider;
  import org.apache.cxf.sts.token.validator.SCTValidator;
  import org.apache.cxf.sts.token.validator.X509TokenValidator;
  import org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider;
  import org.apache.cxf.ws.security.tokenstore.MemoryTokenStore;
  
  @WebServiceProvider(serviceName = "SecurityTokenService",
          portName = "UT_Port",
          targetNamespace = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
          wsdlLocation = "WEB-INF/wsdl/ws-trust-1.4-service.wsdl")
  @EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.username", value = "mystskey"),
      @EndpointProperty(key = "ws-security.encryption.username", value = "mystskey"),
      @EndpointProperty(key = "ws-security.signature.properties", value = "stsKeystore.properties"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "net.example.STSCallbackHandler") 
  })
  public class SampleSTS extends SecurityTokenServiceProvider {
  
      @Override
      public Source invoke(Source request) {
          return super.invoke(request); //To change body of generated methods, choose Tools | Templates.
      }
  
      public SampleSTS() throws Exception {
          super();
          final StaticSTSProperties props = new StaticSTSProperties();
          props.setCallbackHandlerClass(STSCallbackHandler.class.getName());
  
          //X509?
          props.setSignaturePropertiesFile("stsKeystore.properties");
          props.setSignatureUsername("mystskey");
          //????
          props.setIssuer("mystskey");
  
          final List&lt;ServiceMBean&gt; services = new LinkedList&lt;ServiceMBean&gt;();
          StaticService service = new StaticService();
          service.setEndpoints(Arrays.asList(
                  "http://\\[0:0:0:0:0:0:0:1\\]:(\\d)*/sts4/SecurityService"
          ));
          services.add(service);
  
          final TokenIssueOperation issueOperation = new TokenIssueOperation();
          issueOperation.setServices(services);
          issueOperation.getTokenProviders().add(new SCTProvider());
          issueOperation.setStsProperties(props);
          issueOperation.setTokenStore(new MemoryTokenStore());
  
          final TokenValidateOperation validateOperation = new TokenValidateOperation();
          validateOperation.getTokenValidators().add(new SCTValidator());
          validateOperation.getTokenValidators().add(new X509TokenValidator());
          validateOperation.setStsProperties(props);
  
          this.setIssueOperation(issueOperation);
          this.setValidateOperation(validateOperation);
  
      }
  }
  </code></pre>