0

我不确定我是否对 wssecurity 有正确的理解,所以请按照我需要做的事情的顺序纠正我,我会尝试解释我的问题。

我正在尝试从启用策略的 wsdl 实现 jaxws 客户端,策略如下所示:

   <wsp:Policy wsu:Id="AsymmetricX509TokensWithUntPolicy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                <wsp:Policy>
                    <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp:WssUsernameToken10/>
                        </wsp:Policy>
                    </sp:UsernameToken>
                </wsp:Policy>
            </sp:SupportingTokens>
            <sp:AsymmetricBinding>
                <wsp:Policy>
                    <sp:InitiatorToken>
                        <wsp:Policy>
                            <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                <wsp:Policy>
                                    <sp:WssX509V3Token10/>
                                </wsp:Policy>
                            </sp:X509Token>
                        </wsp:Policy>
                    </sp:InitiatorToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic128/>
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Lax/>
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:IncludeTimestamp/>
                    <sp:ProtectTokens/>
                    <sp:OnlySignEntireHeadersAndBody/>
                </wsp:Policy>
            </sp:AsymmetricBinding>
            <sp:SignedParts>
                <sp:Body/>
                <sp:Header Name="Timestamp" Namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
            </sp:SignedParts>
            <sp:Wss11>
                <wsp:Policy>
                    <sp:MustSupportRefKeyIdentifier/>
                </wsp:Policy>
            </sp:Wss11>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

我成功地创建了一个独立的 cxf 客户端与安全的 web 服务进行通信,主要是因为 cxf 框架中的这些依赖关系

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-ws-security</artifactId>
        <version>3.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-ws-policy</artifactId>
        <version>3.2.1</version>
    </dependency>

这些具有提供标题的自动性质,并在幕后做了很多我不明白的事情,但它确实有效。我的客户端设置很简单:

        Map ctx = ((BindingProvider) webServicePortType).getRequestContext();

    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Properties props = new Properties();
    try (InputStream resourceStream = loader.getResourceAsStream(signaturePropertyFilePath)) {
        props.load(resourceStream);
    } catch (IOException e) {
        throw new RuntimeException(
                "IOException: Unresolvable signature property filepath: " + signaturePropertyFilePath, e);
    }
    props.forEach((k, v) -> {
        ctx.put(k.toString(), v);
    });
    ctx.put(SecurityConstants.CALLBACK_HANDLER, callBackHandler);

    ctx.put(SecurityConstants.SIGNATURE_PROPERTIES, signaturePropertyFilePath);

现在我的问题,我已经看到它工作了,所以我很高兴地将我的客户端移动到在 weblogic 12c 上运行的 web 应用程序,但现在事情出了问题。cxf-rt-ws-policy 良好的自动特性现在消失了,我收到没有导致错误的标头的肥皂请求:

These policy alternatives can not be satisfied: 

{ http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }UsernameToken:收到的令牌不符合令牌包含要求 { http://docs.oasis-open.org/ws- sx/ws-securitypolicy/200702 }AsymmetricBinding:收到的时间戳不符合要求 { http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }InitiatorToken { http://docs.oasis- open.org/ws-sx/ws-securitypolicy/200702 }X509Token:收到的令牌与令牌包含要求不匹配 { http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }IncludeTimestamp { http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }ProtectTokens {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }OnlySignEntireHeadersAndBody { http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702 }SignedParts: { http ://www.w3.org/2003/05/soap-envelope }正文未签名

没有标题的结果。

幸运的是,只要 web 服务没有安全要求,我通常在 weblogic 上运行 cxf 客户端没有任何问题。我工作的独立客户端中没有弹簧或弹簧引导程序,也许 cxf 本身已经调用了弹簧,但我没有帮助。

在 weblogic 上运行时,取自 cxf 框架的“PolicyInterceptorProviderRegistryImpl”停止工作。我怀疑这与 cxf bus-extensions.txt 在容器中运行时的工作方式不同有关。抱歉,在 weblogic 上的 web 应用程序中没有 Spring 可用。但我的独立工作正常,没有任何弹簧。cxf框架上的任何人请帮助!:)

那么为什么它独立工作而不是在容器中运行时。任何人都可以帮忙吗?

提前致谢 :)

4

1 回答 1

0

我设法找到了替代解决方案。在我的独立设备上工作的 ws-security 标头的良好自动注入行为从未与 weblogic 12 一起工作。相反,我不得不手动配置它并使 weblogic 使用 JAXBContextFactory 的不同实现,而不是它自己的 moxy impl。即使 cxf 声称与 moxy 兼容,moxy 也有问题。

  1. 类路径创建以下文件 META-INF/services/javax.xml.bind.JAXBContext
  2. 将文本“com.sun.xml.bind.v2.ContextFactory”添加到文件
  3. 创建签名属性文件:

    security.username=151413  
    security.password=NA   
    security.signature.username=sisprivatekey
    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=changeit
    org.apache.ws.security.crypto.merlin.keystore.private.password=changeit
    org.apache.ws.security.crypto.merlin.keystore.file=KeyStore.jks
    
  4. 创建回调处理程序

        CallbackHandler cpc = new CallbackHandler() {
    
        @Override
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    
            for (int i = 0; i < callbacks.length; i++) {
    
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
    
                if (pc.getUsage() == WSPasswordCallback.SIGNATURE
                        || pc.getUsage() == WSPasswordCallback.DECRYPT) {
    
    
                        pc.setPassword("changeit");
                } else {
                    pc.setPassword("NA");
                }
            }
        }
    
    };
    
  5. 手动设置 wss4j/ws-security:

        Client client = ClientProxy.getClient(webServicePortType);
    
    Map<String, Object> outProps = new HashMap<String, Object>();
    
    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " "
            + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE);
    outProps.put(WSHandlerConstants.USER, user);
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, callBackHandler);
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
    outProps.put(WSHandlerConstants.SIG_PROP_FILE, signaturePropertyFilePath);
    outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
    outProps.put(WSHandlerConstants.SIGNATURE_PARTS,
            "{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp");
    
    client.getOutInterceptors().add(new WSS4JStaxOutInterceptor(outProps));
    
  6. 完毕。

于 2018-01-05T12:44:42.887 回答