使用 UsernameTokenSignature 的 CXF SOAP 服务的正确配置是什么?

What is the correct configuration for a CXF SOAP Service with UsernameTokenSignature?

我正在尝试使用 UsernameTokenSignature 设置 CXF 服务和客户端。起点是现有的、代码优先的服务。不幸的是,我发现的所有示例都使用 WS-Policy,据我所知,在代码优先场景中 CXF 不支持它。

我设法创建了一个客户端,它可以像我期望的那样使用此配置发送消息:

客户:

<jaxws:client id="clientWithUsernameTokenSignature" serviceClass="mypackage.MyServiceInterface" address="http://localhost:8081/ws-security-secured-soap-service/services/Service_v1">
    <jaxws:outInterceptors>
        <ref bean="WSS4JOutInterceptor_UsernameTokenSignature" />
    </jaxws:outInterceptors>
</jaxws:client>

WSS4JOutInterceptor

 <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" id="WSS4JOutInterceptor_UsernameTokenSignature">
    <constructor-arg>
        <map>
            <entry key="action" value="UsernameTokenSignature" />
            <entry key="user" value="Admin" />
            <entry key="passwordCallbackClass" value="mypackage.ClientCallbackHandler" />
        </map>
    </constructor-arg>
</bean>

但是我未能设置服务来正确处理来自该客户端的消息。我试过了:

服务:

<jaxws:endpoint id="soapServ_v3" implementor="#myServiceFacade" address="/MyService_v1">
        <jaxws:inInterceptors>
            <ref bean="WSS4JInInterceptor_UsernameTokenSignature" />
        </jaxws:inInterceptors>
</jaxws:endpoint>

WSS4JInInterceptor

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="WSS4JInInterceptor_UsernameTokenSignature">
    <constructor-arg>
        <map>
            <entry key="action" value="UsernameTokenSignature" />
            <entry key="passwordCallbackClass" value="mypackage.ServerCallbackHandler" />
        </map>
    </constructor-arg>
</bean>

执行此操作时,服务器不接受来自客户端的消息并以安全错误作为响应。 调试发现首先失败的地方是org.apache.wss4j.dom.validate.UsernameTokenValidator的verifyUnknownPassword。 这里 allowUsernameTokenDerivedKeys 设置为 false。我想有一些配置我可以设置为真。

服务器上允许用户名令牌派生密钥的正确配置是什么?

即使我使用调试器将值更改为 true,服务调用仍然失败。在这种情况下,拦截器会在 checkActions 处抛出异常:'An error was discovered processing the header'.

所以我想我还需要配置其他东西。 有人知道如何正确设置吗?

好吧,我终于明白了。布尔值 属性 'allowUsernameTokenNoPassword' 需要设置为 'true' 以便服务器接受没有密码的 UT。然后要通过安全 header 额外检查 'UsernameTokenNoPassword' 需要添加为操作。

工作配置如下所示:

WSS4JInInterceptor:

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="WSS4JInInterceptor_UsernameTokenSignature">
    <constructor-arg>
        <map>
            <entry key="action" value="UsernameTokenSignature UsernameTokenNoPassword" />
            <entry key="allowUsernameTokenNoPassword" value="true" />
            <entry key="passwordCallbackClass" value="mypackage.ServerCallbackHandler" />
        </map>
    </constructor-arg>
</bean>