通过CXF拦截器的HTTP基本身份验证不起作用 [英] HTTP basic authentication through CXF interceptor not working

查看:100
本文介绍了通过CXF拦截器的HTTP基本身份验证不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Apache CXF为Web服务请求设置HTTP授权标头时遇到麻烦.我在春季设置了客户端:

I'm having some trouble setting the HTTP Authorization header for a web service request using Apache CXF. I have my client setup through 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" />

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

Headers are set through MyHTTPAuthInterceptor like this:

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()))));
}

使用用户名并将两者都设置为"test",日志中的一切似乎都正常:

With username and both set to 'test', everything seems to be OK in the logs:

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

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

However, the server returns a HTTP 401: Unauthorized.

不知道出了什么问题,我通过更改Web服务客户端工厂代码采取了另一种方法.我向客户的渠道中添加了一个基本的授权策略,如下所示:

Not knowing what's going wrong, I took a whole other approach by changing my web service client factory code. I added a basic authorization policy to the client's conduit like this:

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

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

Tested my setup again, same log (different order though):

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

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

Now the server's response is 200 OK!

问题可能会解决,您可能会认为,但是第二种方法对我而言并不真正有用.我的应用程序是一个多租户环境,都具有不同的用户名和密码.通过第二种方法,我无法重用我的客户端.

Problem solved you might think, but the second approach doesn't really work for me. My application is a multi-tenant environment, all with different username and password. With the second approach I cannot reuse my client.

如何使拦截器正常工作?我插错了相位吗?标头的顺序重要吗?如果是这样,我该如何更改?

How can I get my interceptor to work correctly? Am I plugging into the wrong phase? Does the order of the headers matter? If so, how do I change it?

推荐答案

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

I have almost exactly the same setup as yours but I am putting my interceptor in the PRE_PROTOCOL phase. So far, I have not experienced any problem. You might try that.

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

I think POST_PROTOCOL is just too late because too much has already been written to the stream.

这篇关于通过CXF拦截器的HTTP基本身份验证不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆