如何使用 CXF STS 和 X509v3 BinarySecurityToken

How to use CXF STS and X509v3 BinarySecurityToken

我正在尝试使 CXF STS 使用 509v3 令牌。如果只配置用户名令牌,它工作正常,但在 X509 上失败。

我在 JBOSS EAP 6.3.1

中使用 CXF

Maven 依赖关系

<dependency>
  <groupId>org.apache.cxf.services.sts</groupId>
  <artifactId>cxf-services-sts-core</artifactId>
  <version>2.7.11.redhat-3</version>
</dependency>

<dependency>
  <groupId>org.jboss.ws.cxf</groupId>
  <artifactId>jbossws-cxf-server</artifactId>
  <version>4.3.0.Final-redhat-3</version>
  <scope>provided</scope>
</dependency>

我的 WSDL:

...
 <wsp:Policy wsu:Id="UT_policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <!--  
                Disabled for testing - I use SoapUI for sending the request
                <sp:TransportBinding>
                    <wsp:Policy>
                        <sp:TransportToken>
                            <wsp:Policy>
                                <sp:HttpsToken RequireClientCertificate="false"/>
                            </wsp:Policy>
                        </sp:TransportToken>
                    </wsp:Policy>
                </sp:TransportBinding>              
                -->
                <sp:SupportingTokens>               
                    <wsp:Policy>
                        <wsp:ExactlyOne>
                            <wsp:All>
                                <sp:X509Token IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                                    <wsp:Policy>
                                        <sp:WssX509V3Token10 wsu:Id="token"/>
                                    </wsp:Policy>
                                </sp:X509Token>
                            </wsp:All>
<!--                         
Disabled for Testing. If I activate both, neither work. Somehow CXF ignores the ExactlyOne Element.   
                             <wsp:All>
                                <sp:UsernameToken wsu:Id="BiPROBasicToken"/>
                            </wsp:All>-->
                        </wsp:ExactlyOne>
                    </wsp:Policy>       
                </sp:SupportingTokens>      
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>

示例请求:

<SOAPENV:Envelope xmlns:SOAPENV='http://schemas.xmlsoap.org/soap/envelope/'>
 <SOAPENV:Header>
  <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'>
   <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'>
MIIDMTCCApqgAwI....3aairt
93OqNtk=
</wsse:BinarySecurityToken>
   <Signature xmlns='http://www.w3.org/2000/09/xmldsig#'>
    <SignedInfo>
     <CanonicalizationMethod Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'/>
     <SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>
     <Reference URI='#body'>
      <Transforms>
       <Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/>
      </Transforms>
      <DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>
      <DigestValue>WbLbIc...k=</DigestValue>
     </Reference>
     <Reference URI='#Timestamp'>
      <Transforms>
       <Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/>
      </Transforms>
      <DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>
      <DigestValue>z3q....9w=</DigestValue>
     </Reference>
     <Reference URI='#Token'>
      <Transforms>
       <Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/>
      </Transforms>
      <DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>
      <DigestValue>ypE6U....slo=</DigestValue>
     </Reference>
    </SignedInfo>
    <SignatureValue>lW1....Tc=</SignatureValue>
    <KeyInfo>
     <wsse:SecurityTokenReference>
      <wsse:Reference URI='#Token' ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3'/>
     </wsse:SecurityTokenReference>
    </KeyInfo>
   </Signature>
   <wsu:Timestamp wsu:Id='Timestamp'>
    <wsu:Created>2015-02-09T13:03:11Z</wsu:Created>
    <wsu:Expires>2015-02-09T13:13:13Z</wsu:Expires>
   </wsu:Timestamp>
  </wsse:Security>
 </SOAPENV:Header>
 <SOAPENV:Body wsu:Id='body' xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>
  <wst:RequestSecurityToken xmlns:wst='http://schemas.xmlsoap.org/ws/2005/02/trust'>
   <wst:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</wst:TokenType>
   <wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
  </wst:RequestSecurityToken>
 </SOAPENV:Body>
</SOAPENV:Envelope>

请求有效且无法更改 -> 它是由另一个程序生成的。

响应:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Server</faultcode>
         <faultstring>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</faultstring>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

我不知道,如果我的策略定义有误,或者我的 sts class。

STS Class

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<ServiceMBean> services = new LinkedList<ServiceMBean>();
        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);

    }
}

CXF 不支持没有安全绑定的 X.509 SupportingToken 的概念。当您使用非对称签名时,您应该改用 AsymmetricBinding 安全策略,并使用 SignedParts 策略来涵盖应签名的消息部分。