使用 Apache CXF 进行摘要式身份验证

问题描述 投票:0回答:1

我正在尝试使用 Java 和 Apache 的 cxf 库进行 Web 服务调用,当然,如果可能的话,这应该通过摘要身份验证进行,如果服务器不支持摘要,则基本作为后备。

我有以下代码,从 WSDL 创建一个服务端口,创建一个能够处理身份验证协商的 HTTPConduit,并设置所需的授权类型“Digest”。

MyService myService = new MyService("wsdl-url");
MyServicePort myServicePort = myService.getMyServicePort();

Client client = ClientProxy.getClient(myServicePort);
HTTPConduit http = (HTTPConduit) client.getConduit();

AuthorizationPolicy authPolicy = new AuthorizationPolicy();
authPolicy.setAuthorizationType("Digest");
authPolicy.setUserName("user");
authPolicy.setPassword("myPassword");
http.setAuthorization(authPolicy);

myServicePort.doSomething();

现在,如果服务器仅响应接受摘要身份验证(因此带有标头),则效果非常好:

WWW-Authenticate: Digest realm="...", nonce="...", algorithm=MD5, qop="auth"\r\n

但是还有另一台服务器(服务器实际上是摄像机)通过提供基本和摘要两种身份验证方法进行响应:

WWW-Authenticate: Digest realm="...", nonce="...", stale=FALSE, qop="auth"\r\n
WWW-Authenticate: Basic realm="..."\r\n

它会失败,因为重传没有发送。我猜cxf只是选择了这两种方法中的一种,碰巧这是基本方法,但没有找到基本方法的授权策略,因此失败了。

这是一些堆栈跟踪:

Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Unauthorized' when communicating with http://192.168.x.x/vapix/services
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.doProcessResponseCode(HTTPConduit.java:1600) ~[cxf-rt-transports-http-3.1.8.jar:3.1.8]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1607) ~[cxf-rt-transports-http-3.1.8.jar:3.1.8]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551) ~[cxf-rt-transports-http-3.1.8.jar:3.1.8]

有人知道这是否是 cxf 的错误吗?或者有解决方法吗?我唯一的想法是编写自己的 HttpAuthSupplier,但这可能有点微妙。

谢谢, 西尔万

java apache web-services authentication cxf
1个回答
0
投票

您可以指定 Digest 的授权供应商:

org.apache.cxf.transport.http.auth.DigestAuthSupplier

http.setAuthSupplier( new DigestAuthSupplier() );

之后

http.setAuthorization(authPolicy)

© www.soinside.com 2019 - 2024. All rights reserved.