我正在尝试开发一个由WS-Trust "IssuedToken"策略保护的fuse CXF服务,正如安全令牌服务的官方文档中所解释的那样。我按照文档中解释的那样做了所有事情,并与一些fuse和CXF官方示例进行了交叉检查。
一切似乎都很好,但是当我使用SoapUI并且没有令牌调用服务时,而不是接收错误(因为缺少令牌),调用通过并返回结果,好像根本没有实现任何保护。
我尝试在"独立模式"(外部保险丝)下运行相同的代码,就像在CXF"sts"示例中所做的那样,并且保护工作。当然,在这种情况下,我使用了一个不同的pom文件和一个类(Server.java)以及一个spring文件(wssec-server.xml)来引导服务,但其他一切都是相同的。
那么是什么阻止了安全设置的工作呢?
Ubuntu 14.04.5 LTS版本:6.2.1.084
来源。请记住,整个尝试是从许多我还没有完全理解的例子中拼贴出来的,所以一些说明可能在这里放错了地方。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>rst-abc</groupId>
<artifactId>mock-fuse-service-secure-b</artifactId>
<version>2</version>
<packaging>bundle</packaging>
<name>MockFuseServiceSecureB</name>
<repositories>
<repository>
<id>fuse-public-repository</id>
<name>FuseSource Community Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
<repository>
<id>fusesource.ea</id>
<name>JBoss Community Early Access Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/ea</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>fuse-public-repository</id>
<name>FuseSource Community Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<cxf-version>3.0.4.redhat-621084</cxf-version>
<version.maven-surefire-plugin>2.15</version.maven-surefire-plugin>
<version.maven-bundle-plugin>2.3.7</version.maven-bundle-plugin>
<skipTests>true</skipTests>
<!-- the version of the BOM, defining all the dependency versions -->
<fabric.version>1.2.0-SNAPSHOT</fabric.version>
<!-- fabric8 deploy profile configuration -->
<fabric8.profile>quickstarts-cxf-soap</fabric8.profile>
<fabric8.parentProfiles>feature-cxf</fabric8.parentProfiles>
<fabric8.features>fabric-cxf cxf-jaxws</fabric8.features>
<!-- the version of the JBoss Fuse BOM, defining all the dependency versions -->
<jboss.fuse.bom.version>6.2.1.redhat-084</jboss.fuse.bom.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.fuse.bom</groupId>
<artifactId>jboss-fuse-parent</artifactId>
<version>${jboss.fuse.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<finalName>shared</finalName>
<plugins>
<!-- Skip Test by default and enable them only in Test profile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven-surefire-plugin}</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${version.maven-bundle-plugin}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>
javax.jws,
javax.xml.bind,
javax.xml.bind.annotation,
javax.xml.namespace, javax.xml.ws,
javax.wsdl,
org.osgi.service.blueprint,
io.fabric8.cxf.endpoint,
javax.security.auth.callback,
org.apache.cxf.interceptor.security,
org.apache.cxf.transport.http,
io.fabric8.cxf,
org.apache.cxf, org.apache.cxf.endpoint, org.apache.cxf.frontend, org.apache.cxf.interceptor,
org.apache.cxf.jaxws, org.apache.cxf.message, org.apache.cxf.phase
</Import-Package>
<Import-Service>org.apache.aries.blueprint.NamespaceHandler;
osgi.service.blueprint.namespace=http://cxf.apache.org/transports/http/configuration
</Import-Service>
<Export-Package>it.rst.abc</Export-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.0.4.redhat-621084</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>target/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/wsdl/hello_world.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/hello_world.wsdl</wsdlLocation>
<frontEnd>jaxws21</frontEnd>
<extraargs>
<extraarg>-impl</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
<additionalJvmArgs>-Djavax.xml.accessExternalSchema=jar:file,file</additionalJvmArgs>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>1.2.0.redhat-621084</version>
</plugin>
</plugins>
</build>
</project>
hello_world.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://abc.rst.it/hello_world"
xmlns:x1="http://abc.rst.it/hello_world/types"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://www.w3.org/ns/ws-policy"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
xmlns:wsaw="http://www.w3.org/2005/08/addressing"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="HelloWorld"
targetNamespace="http://abc.rst.it/hello_world">
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://abc.rst.it/hello_world/types" targetNamespace="http://abc.rst.it/hello_world/types" elementFormDefault="qualified">
<simpleType name="MyStringType">
<restriction base="string">
<maxLength value="30"/>
</restriction>
</simpleType>
<element name="greetMe">
<complexType>
<sequence>
<element name="requestType" type="tns:MyStringType"/>
</sequence>
</complexType>
</element>
<element name="greetMeResponse">
<complexType>
<sequence>
<element name="responseType" type="string"/>
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<wsdl:message name="greetMeRequest">
<wsdl:part element="x1:greetMe" name="in"/>
</wsdl:message>
<wsdl:message name="greetMeResponse">
<wsdl:part element="x1:greetMeResponse" name="out"/>
</wsdl:message>
<wsdl:portType name="Greeter">
<wsdl:operation name="greetMe">
<wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
<wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
<wsp:PolicyReference URI="#AsymmetricSAML2Policy"/>
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="greetMe">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="greetMeRequest">
<soap:body use="literal"/>
<wsp:PolicyReference URI="#Input_Policy"/>
</wsdl:input>
<wsdl:output name="greetMeResponse">
<soap:body use="literal"/>
<wsp:PolicyReference URI="#Output_Policy"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MockSecureService">
<wsdl:port binding="tns:Greeter_SOAPBinding" name="MockPort">
<soap:address location="http://0.0.0.0:9001/cxf/HelloWorldSecure"/>
</wsdl:port>
</wsdl:service>
<wsp:Policy wsu:Id="AsymmetricSAML2Policy">
<wsp:ExactlyOne>
<wsp:All>
<wsam:Addressing wsp:Optional="false">
<wsp:Policy/>
</wsam:Addressing>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:IssuedToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<sp:RequestSecurityTokenTemplate>
<t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
<t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey</t:KeyType>
</sp:RequestSecurityTokenTemplate>
<wsp:Policy>
<sp:RequireInternalReference/>
</wsp:Policy>
<sp:Issuer>
<wsaw:Address>http://localhost:8080/SecurityTokenService/
</wsaw:Address>
</sp:Issuer>
</sp:IssuedToken>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
<wsp:Policy>
<sp:WssX509V3Token10/>
<sp:RequireIssuerSerialReference/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefIssuerSerial/>
<sp:MustSupportRefThumbprint/>
<sp:MustSupportRefEncryptedKey/>
</wsp:Policy>
</sp:Wss11>
<sp:Trust13>
<wsp:Policy>
<sp:MustSupportIssuedTokens/>
<sp:RequireClientEntropy/>
<sp:RequireServerEntropy/>
</wsp:Policy>
</sp:Trust13>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="Input_Policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="Output_Policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
<sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</wsdl:definitions>
blueprint.xml
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd">
<jaxws:endpoint
xmlns:s="http://abc.rst.it/hello_world"
id="server"
implementor="it.rst.abc.GreeterImpl"
endpointName="s:MockPort"
serviceName="s:MockSecureService"
wsdlLocation="classpath:wsdl/hello_world.wsdl"
address="http://0.0.0.0:9001/cxf/HelloWorldSecure">
<jaxws:properties>
<entry key="ws-security.username" value="myservicekey"/>
<entry key="ws-security.password" value="skpass"/>
<entry key="ws-security.signature.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.encryption.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.signature.username" value="myservicekey"/>
</jaxws:properties>
</jaxws:endpoint>
</blueprint>
serviceKeystore.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=sspass
org.apache.ws.security.crypto.merlin.keystore.alias=myservicekey
org.apache.ws.security.crypto.merlin.keystore.file=keys/servicestore.jks
GreeterImpl.java
package it.rst.abc;
import it.rst.abc.hello_world.Greeter;
import java.util.logging.Logger;
@javax.jws.WebService(name = "Greeter", serviceName = "MockSecureService",
targetNamespace = "http://abc.rst.it/hello_world",
wsdlLocation = "classpath:wsdl/hello_world.wsdl")
public class GreeterImpl implements Greeter {
private static final Logger LOG =
Logger.getLogger(GreeterImpl.class.getPackage().getName());
public String greetMe(String me) {
LOG.info("Executing operation greetMe");
System.out.println("Executing operation greetMe");
System.out.println("Message received: " + me + "n");
return "Hello " + me;
}
}
对于"独立"示例(按预期工作),我使用了以下内容(我删除了一些字符以使这篇文章保持在SO限制内):
pom-standalone.xml
<?xml ... ?>
<project xmlns=...>
<modelVersion...
<properties>
<cxf.version>${project.version}</cxf.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/wsdl/hello_world.wsdl</wsdl>
<frontEnd>jaxws21</frontEnd>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>demo.wssec.server.Server</mainClass>
<arguments>
<argument>${basedir}/src/main/resources/wssec-server.xml</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.14.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
<exclusion>
<artifactId>logkit</artifactId>
<groupId>logkit</groupId>
</exclusion>
<exclusion>
<artifactId>avalon-framework</artifactId>
<groupId>avalon-framework</groupId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
...other log4j dependencies here...
</dependencies>
</project>
Server.java
package demo.wssec.server;
import java.io.File;
import java.net.URL;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
public class Server {
protected Server(URL busURL) throws Exception {
SpringBusFactory bf = new SpringBusFactory();
Bus bus = bf.createBus(busURL.toString());
BusFactory.setDefaultBus(bus);
}
public static void main(String args[]) throws Exception {
URL busURL;
File busFile = new File(args[0]);
if (busFile.exists()) {
busURL = busFile.toURI().toURL();
} else {
busURL = new URL(args[0]);
}
new Server(busURL);
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
}
}
wssec-server.xml
<?xml ... ?>
<beans xmlns=...>
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
<jaxws:endpoint
xmlns:s="http://abc.rst.it/hello_world"
id="server"
implementor="it.rst.abc.GreeterImpl"
endpointName="s:MockPort"
serviceName="s:MockSecureService"
wsdlLocation="classpath:wsdl/hello_world.wsdl"
address="http://0.0.0.0:9001/SoapcxContext/HelloWorldSecure">
<jaxws:properties>
<entry key="ws-security.signature.username" value="myservicekey"/>
<entry key="ws-security.username" value="myservicekey"/>
<entry key="ws-security.password" value="skpass"/>
<entry key="ws-security.signature.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.encryption.properties" value="serviceKeystore.properties"/>
</jaxws:properties>
</jaxws:endpoint>
</beans>
然后用
启动服务器mvn -f pom-standalone.xml -Pserver
,当我与SoapUI连接时,我得到以下(预期)错误:
MessageAddressingHeaderRequired:表示消息寻址属性的必需标头不存在
代码正确。缺少的是卡拉夫的正确配置。通过发出
features:list | grep cxf-ws-security
可以检查该特性是否已安装。要安装它,只需输入
features:install cxf-ws-security
我在README中找到了解决方案。cxf/secure-soap保险丝快速入门的Md。整个fuse cxf安全指南都没有提到它!而且,当一个受保护的服务的保护库丢失时,它在不受保护的情况下工作,并且日志中没有任何消息,这是相当奇怪的。