Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过CXF侦听器的HTTP基本身份验证不起作用_Java_Web Services_Cxf_Basic Authentication - Fatal编程技术网

Java 通过CXF侦听器的HTTP基本身份验证不起作用

Java 通过CXF侦听器的HTTP基本身份验证不起作用,java,web-services,cxf,basic-authentication,Java,Web Services,Cxf,Basic Authentication,使用ApacheCXF为web服务请求设置HTTP授权头时遇到一些问题。我通过spring设置了客户端: <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

使用ApacheCXF为web服务请求设置HTTP授权头时遇到一些问题。我通过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" />
但是,服务器返回HTTP 401:Unauthorized

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

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()))));
}
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("test");
authorizationPolicy.setPassword("test");
authorizationPolicy.setAuthorizationType("Basic");
httpConduit.setAuthorization(authorizationPolicy);
再次测试我的设置,相同的日志(尽管顺序不同):

现在服务器的响应是200 OK

你们可能会想,问题已经解决了,但第二种方法对我来说并不适用。我的应用程序是一个多租户环境,具有不同的用户名和密码。使用第二种方法,我不能重用我的客户机


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

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


我认为POST_协议太迟了,因为已经有太多的内容写入流中。

如果您希望将客户端和身份验证外部化,最好的方法是在spring上下文中设置HttpConductor

 **in your spring context file...**

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       ...

  <bean id="properties" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
    <property name="locations">
        <util:list>
            <value>file:${config.dir}/application.properties</value>
        </util:list>
    </property>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
 </bean>
  ...
  <jaxws:client id="serviceClient" serviceClass="com.your.ServiceClass" address="${webservice.soap.address}" >
    <jaxws:inInterceptors>
        <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" >
            <property name="prettyLogging" value="true" />
        </bean>
    </jaxws:inInterceptors>
    <jaxws:outInterceptors>
        <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" >
            <property name="prettyLogging" value="true" />
        </bean>
    </jaxws:outInterceptors>
  </jaxws:client>
  ...


applicaiton.properties
---------------------
webservices.http.auth.username=userName
webservices.http.auth.password=Password
webservice.soap.address=https://your.service.url/services/service
**在spring上下文文件中**

好的,我必须在这里纠正我自己。我犯了一个错误。它确实有用!非常感谢,特此接受您的答复:)
Headers: {SOAPAction=[""], Authorization=[Basic dGVzdDp0ZXN0], Accept=[*/*]}
 **in your spring context file...**

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       ...

  <bean id="properties" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
    <property name="locations">
        <util:list>
            <value>file:${config.dir}/application.properties</value>
        </util:list>
    </property>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
 </bean>
  ...
  <jaxws:client id="serviceClient" serviceClass="com.your.ServiceClass" address="${webservice.soap.address}" >
    <jaxws:inInterceptors>
        <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" >
            <property name="prettyLogging" value="true" />
        </bean>
    </jaxws:inInterceptors>
    <jaxws:outInterceptors>
        <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" >
            <property name="prettyLogging" value="true" />
        </bean>
    </jaxws:outInterceptors>
  </jaxws:client>
  ...


applicaiton.properties
---------------------
webservices.http.auth.username=userName
webservices.http.auth.password=Password
webservice.soap.address=https://your.service.url/services/service
Ex: if in your WSDL..
    <wsdl-definitions ... targetNamespace="http://your.target.namespace.com/" ...>
    ...
    <wsdl:port binding="tns:YourServiceSoapBinding"
        name="YourServiceImplPort">
        <soap:address location="https://your.service.url/services/service" /> 
...
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
...
<http-conf:conduit name="https://your.service.url/services/service">
    <http-conf:authorization>
        <sec:UserName>${webservices.http.auth.username}</sec:UserName>
        <sec:Password>${webservices.http.auth.password}</sec:Password>
        <sec:AuthorizationType>Basic</sec:AuthorizationType>
    </http-conf:authorization>
</http-conf:conduit>
<http-conf:conduit name="{http://your.target.namespace.com/}YourServiceImplPort.http_conduit">
    <http-conf:authorization>
        <sec:UserName>${webservices.http.auth.username}</sec:UserName>
        <sec:Password>${webservices.http.auth.password}</sec:Password>
        <sec:AuthorizationType>Basic</sec:AuthorizationType>
    </http-conf:authorization>
</http-conf:conduit>