java - 通过 CXF 拦截器的 HTTP 基本身份验证不起作用

标签 java web-services cxf basic-authentication

我在使用 Apache CXF 为 Web 服务请求设置 HTTP 授权 header 时遇到了一些问题。我在 Spring 设置了客户端:

<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

<bean id="myHTTPAuthInterceptor" class="my.app.MyHTTPAuthInterceptor" autowire="constructor" />

<bean id="webServiceFactory" class="my.app.WebServiceFactory">
    <property name="wsdlLocation" value="classpath:/my/app/webservice.wsdl" />
    <property name="serviceURL">
        <jee:jndi-lookup jndi-name="webservice/url" />
    </property>
    <property name="inInterceptors">
        <list>
            <ref bean="loggingInInterceptor" />
        </list>
    </property>
    <property name="outInterceptors">
        <list>
            <ref bean="loggingOutInterceptor" />
            <ref bean="myHTTPAuthInterceptor" />
        </list>
    </property>
</bean>

<bean id="myWebService" factory-bean="webServiceFactory" factory-method="getInstance" />

header 是通过 MyHTTPAuthInterceptor 设置的,如下所示:

public MyHTTPAuthInterceptor(ConfigDao configDao)
{
    super(Phase.POST_PROTOCOL);

    this.configDao = configDao;
}

@Override
public void handleMessage(Message message) throws Fault
{
    Map<String, List<?>> headers = (Map<String, List<?>>) message.get(Message.PROTOCOL_HEADERS);

    String authString = configDao.getUsername() + ":" + config.getPassword();
    headers.put("Authorization", Collections.singletonList("Basic " + new String(Base64.encodeBase64(authString.getBytes()))));
}

将用户名和两者都设置为“测试”,日志中的一切似乎都正常:

Headers: {SOAPAction=[""], Accept=[*/*], Authorization=[Basic dGVzdDp0ZXN0]}

但是,服务器返回 HTTP 401:未经授权。

由于不知道出了什么问题,我采用了另一种方法,即更改我的 Web 服务客户端工厂代码。我像这样向客户的管道添加了基本授权策略:

HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("test");
authorizationPolicy.setPassword("test");
authorizationPolicy.setAuthorizationType("Basic");
httpConduit.setAuthorization(authorizationPolicy);

再次测试了我的设置,相同的日志(尽管顺序不同):

Headers: {SOAPAction=[""], Authorization=[Basic dGVzdDp0ZXN0], Accept=[*/*]}

现在服务器的响应是 200 OK!

您可能认为问题已解决,但第二种方法对我来说并不适用。我的应用程序是一个 Multi-Tenancy 环境,都有不同的用户名和密码。使用第二种方法,我无法重用我的客户。

如何让我的拦截器正常工作?我是否插入了错误的相位?标题的顺序重要吗?如果是这样,我该如何更改它?

最佳答案

我的设置几乎与您的完全相同,但我将拦截器置于 PRE_PROTOCOL 阶段。到目前为止,我还没有遇到任何问题。你可以试试看。

我认为 POST_PROTOCOL 太迟了,因为已经向流中写入了太多内容。

关于java - 通过 CXF 拦截器的 HTTP 基本身份验证不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11984319/

相关文章:

Android Web 服务、REST 还是 SOAP WSDL?

java | CXF JAXRS 非 Spring 客户端

java - Android webview chromium 异常 - ContextResult::kFatalFailure: 支持的制服或变量太少

java - double 移动小数点

rest - WCF RESTFul 服务中的异常处理

java - 如何通过maven获取cxf 3.0.0-milestone1包

java - 在 JAVA 中从 WADL URL 生成休息客户端

java - Maven 添加位于本地存储库上的依赖项

java - 我需要在添加新组件时动态调整 JPanel 的大小

visual-studio - 在Visual Studio 2019中添加Web引用发生了什么?