Java Web Service Client Basic Authentication

Java Web Service client basic authentication

It turned out that there's a simple, standard way to achieve what I wanted:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

Authenticator myAuth = new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication("german", "german".toCharArray());
}
};

Authenticator.setDefault(myAuth);

No custom "sun" classes or external dependencies, and no manually encode anything.

I'm aware that BASIC security is not, well, secure, but we are also using HTTPS.

JAX-WS Request with Basic Authentication

You would need to change your code to like this:

@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(outboundProperty.booleanValue()){
try{
String authString = parameter.getUser() + ":" + parameter.getPassword();
SOAPMessage soapMessage =context.getMessage();
String authorization = new sun.misc.BASE64Encoder().encode(authString.getBytes());
soapMessage.getMimeHeaders().addHeader("Authorization","Basic " + authorization);
soapMessage.saveChanges();
}catch(Exception e){
log4j.error(e.getMessage(), e);
}
}
return true;
}

Updated:

As explained here you should use Base64Coder from sun.misc.BASE64Encoder() for encoding authString

Also you should always return true from this method otherwise you will block processing of the handler request chain by returning false.

How to perform authentication in a java web service using HttpURLConnection

This line of your code in client side will add the required header for Basic authentication

conn.setRequestProperty ("Authorization", "Basic " + authStringEnc);

In server side, you need to read the "Authorization" header and extract the content

Map<String, List<String>> headers= (Map<String, List<String>>) messageContext
.get(MessageContext.HTTP_REQUEST_HEADERS);

//The header "Basic base64(user:password)
String authHeader = headers.get("Authorization").get(0);

//Remove "Basic "
String authtoken = authorizationHeader.split(" ")[1];

//Decode base64 and read username and password
String token = new String(DatatypeConverter.parseBase64Binary(authtoken));
String tokenS[] = token.split(":");
String username = tokenS [0];
String password = tokenS [1];

I have not tested all the code, but it should work

simple jax-ws-webservice with basic authentication

Found a solution here:

https://today.java.net/pub/a/today/2007/07/03/jax-ws-web-services-without-ee-containers.html

after hours of trial-and-error finally the right searchwords in google :)

JAX-WS Client Basic Authentication

To answer my own question... I decided to go with using Handlers. So I created a SOAPHandler similar to ExchangeAuthSupplier above:

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

Created a HandlerResolver to add the resolvers to a chain:

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

And then in Spring, just hooked it all up like this:

<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"/>

How do I consume a web service protected with HTTP basic authentication using the CXF framework?

This is covered by the JAX-WS Specification. Basically, set the username/password as properties on the request context:

((BindingProvider)proxy).getRequestContext().put(
BindingProvider.USERNAME_PROPERTY, "joe");
((BindingProvider)proxy).getRequestContext().put(
BindingProvider.PASSWORD_PROPERTY, "pswd");

The runtime puts them into the HTTP header.

HTTP Basic Authentication for WEBService call

 HttpTransportProperties.Authenticator
auth = new HttpTransportProperties.Authenticator();
auth.setUsername("username");
auth.setPassword("password");

_serviceClient.getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.BASIC_AUTHENTICATE,auth);

Basic Authorization in Java | Apache CXF

I think you mean Basic Authentication, and you can use BindingProvider, something like:

BindingProvider provider = (BindingProvider) client;
Map<String,Object> rc = provider.getRequestContext();
rc.put(BindingProvider.USERNAME_PROPERTY, userName);
rc.put(BindingProvider.PASSWORD_PROPERTY, password);

You can see a complete example here: https://examples.javacodegeeks.com/enterprise-java/jws/jax-ws-bindingprovider-example/ (look at the client section).



Related Topics



Leave a reply



Submit