Java JAX-WS客户端基本身份验证
我被迫从web服务中删除CXF。为了消除对身份验证的任何依赖,我设置了一个HttpAuthSupplier类来处理基本身份验证Java JAX-WS客户端基本身份验证,java,spring,jax-ws,Java,Spring,Jax Ws,我被迫从web服务中删除CXF。为了消除对身份验证的任何依赖,我设置了一个HttpAuthSupplier类来处理基本身份验证 public class ExchangeAuthSupplier implements HttpAuthSupplier{ @Override public boolean requiresRequestCaching() { return false; } @Override
public class ExchangeAuthSupplier implements HttpAuthSupplier{
@Override
public boolean requiresRequestCaching() {
return false;
}
@Override
public String getAuthorization(AuthorizationPolicy authPolicy, URL url, Message message, String fullHeader) {
// Lookup authentication information and return appropriate header
}
}
我想知道如何使用常规JAX-WSAPI和Spring做类似的事情…来回答我自己的问题。。。我决定使用处理程序。因此,我创建了一个类似于上述ExchangeAuthSupplier的SOAPHandler:
public class MyAuthenticationHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
final Boolean outInd = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outInd.booleanValue()) {
try {
UserNamePasswordPair userNamePasswordPair = getAuthorization(); // Method to retrieve credentials from somewhere
context.put(BindingProvider.USERNAME_PROPERTY, userNamePasswordPair.getUsername());
context.put(BindingProvider.PASSWORD_PROPERTY, userNamePasswordPair.getPassword());
} catch (final Exception e) {
return false;
}
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
logger.error("error occurred when getting auth.");
return false;
}
@Override
public void close(MessageContext context) {
logger.debug("closing handler for auth...");
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
创建了HandlerResolver以将解析程序添加到链:
public class MyHandlerResolver implements HandlerResolver {
private List<Handler> chain;
public MyHandlerResolver() {
chain = new ArrayList<Handler>();
chain.add(new MyAuthenticationHandler();
}
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
return chain;
}
}
然后在春天,就这样把它连接起来:
<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="Interface to implement"/>
<property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/>
<property name="namespaceUri" value="namespace"/>
<property name="serviceName" value="ServiceName"/>
<property name="endpointAddress" value="/endpoint"/>
<property name="handlerResolver" ref="myHandlerResolver"/>
</bean>
<bean id="myHandlerResolver" class="com.mystuff.ExchangeHandlerResolver"/>
回答我自己的问题。。。我决定使用处理程序。因此,我创建了一个类似于上述ExchangeAuthSupplier的SOAPHandler:
public class MyAuthenticationHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
final Boolean outInd = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outInd.booleanValue()) {
try {
UserNamePasswordPair userNamePasswordPair = getAuthorization(); // Method to retrieve credentials from somewhere
context.put(BindingProvider.USERNAME_PROPERTY, userNamePasswordPair.getUsername());
context.put(BindingProvider.PASSWORD_PROPERTY, userNamePasswordPair.getPassword());
} catch (final Exception e) {
return false;
}
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
logger.error("error occurred when getting auth.");
return false;
}
@Override
public void close(MessageContext context) {
logger.debug("closing handler for auth...");
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
创建了HandlerResolver以将解析程序添加到链:
public class MyHandlerResolver implements HandlerResolver {
private List<Handler> chain;
public MyHandlerResolver() {
chain = new ArrayList<Handler>();
chain.add(new MyAuthenticationHandler();
}
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
return chain;
}
}
然后在春天,就这样把它连接起来:
<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="Interface to implement"/>
<property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/>
<property name="namespaceUri" value="namespace"/>
<property name="serviceName" value="ServiceName"/>
<property name="endpointAddress" value="/endpoint"/>
<property name="handlerResolver" ref="myHandlerResolver"/>
</bean>
<bean id="myHandlerResolver" class="com.mystuff.ExchangeHandlerResolver"/>
对于基本身份验证和Spring的JaxWsPortProxyFactoryBean,您只需使用:
<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="Interface to implement"/>
<property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/>
<property name="namespaceUri" value="namespace"/>
<property name="serviceName" value="ServiceName"/>
<property name="endpointAddress" value="/endpoint"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
对于基本身份验证和Spring的JaxWsPortProxyFactoryBean,您只需使用:
<bean id="myJAXWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="Interface to implement"/>
<property name="wsdlDocumentUrl" value="classpath:/wsdl/theWsdl.wsdl"/>
<property name="namespaceUri" value="namespace"/>
<property name="serviceName" value="ServiceName"/>
<property name="endpointAddress" value="/endpoint"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
向kaczors添加使用Spring的JaxWsPortProxyFactoryBean进行基本身份验证的应答, 如果wsdl或xsd不在类路径中,并且需要从需要基本身份验证的url访问,请创建一个自定义的JaxWsPortProxyFactoryBean,它将启用wsdl url http基本身份验证
public class ExchangeAuthSupplier implements HttpAuthSupplier{
@Override
public boolean requiresRequestCaching() {
return false;
}
@Override
public String getAuthorization(AuthorizationPolicy authPolicy, URL url, Message message, String fullHeader) {
// Lookup authentication information and return appropriate header
}
}
公共类CustomJaxWsPortProxyFactoryBean扩展了JaxWsPortProxyFactoryBean{
@Override
public Service createJaxWsService() {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
getUsername(),
getPassword().toCharArray());
}
});
return super.createJaxWsService();
}
感谢sundaramss of添加到kaczors answer中,使用Spring的JaxWsPortProxyFactoryBean进行基本身份验证, 如果wsdl或xsd不在类路径中,并且需要从需要基本身份验证的url访问,请创建一个自定义的JaxWsPortProxyFactoryBean,它将启用wsdl url http基本身份验证
public class ExchangeAuthSupplier implements HttpAuthSupplier{
@Override
public boolean requiresRequestCaching() {
return false;
}
@Override
public String getAuthorization(AuthorizationPolicy authPolicy, URL url, Message message, String fullHeader) {
// Lookup authentication information and return appropriate header
}
}
公共类CustomJaxWsPortProxyFactoryBean扩展了JaxWsPortProxyFactoryBean{
@Override
public Service createJaxWsService() {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
getUsername(),
getPassword().toCharArray());
}
});
return super.createJaxWsService();
}
感谢sundaramss of允许您使用Spring WS吗?是的,我是…我认为现在最好的方法是实现一个soap处理程序…允许您使用Spring WS吗?是的,我是…我认为现在最好的方法是实现一个soap处理程序…警告:Authenticator.setDefault是静态的,因此如果在同一时间发出两个请求一次,来自一个请求的身份验证将泄漏到另一个请求中。如果您打算使用它,您应该创建一个自定义身份验证程序,该程序使用ThreadLocal来确保每个线程使用独立的信息,但一般来说,我会说避免它更安全。警告:Authenticator.setDefault是静态的,因此如果两个请求是同时,来自一个请求的身份验证将泄漏到另一个请求中。如果您打算使用它,您应该创建一个自定义身份验证程序,它使用ThreadLocal来确保每个线程使用独立的信息,但一般来说,我认为避免它更安全。