如何使用 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 策略来涵盖应签名的消息部分。
我正在尝试使 CXF STS 使用 509v3 令牌。如果只配置用户名令牌,它工作正常,但在 X509 上失败。
我在 JBOSS EAP 6.3.1
中使用 CXFMaven 依赖关系
<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 策略来涵盖应签名的消息部分。