Perşembe, Şubat 25, 2010

adding custom header to webservice calls and solution to saaj problem

I have an application running on weblogic 10.3 that calls several other webservices. Everything was working like a charm until i need to add a SOAP Header to one of the these webservice calls. The SOAP header that i had to add is a custom security header defined as;


<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>__username__</wsse:Username>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>


To add this header to webservice call i write the following code;


import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;
....
private static final String SECURITY_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String MY_USERNAME = "my_username";
....
private void addUsernameSecurityHeader(UserService service) throws SOAPException {
SOAPFactory soapFactory = SOAPFactory.newInstance();

QName securityQName = new QName(SECURITY_NAMESPACE, "Security");
SOAPElement security = soapFactory.createElement(securityQName);

QName tokenQName = new QName(SECURITY_NAMESPACE, "UsernameToken");
SOAPElement token = soapFactory.createElement(tokenQName);

QName userQName = new QName(SECURITY_NAMESPACE, "Username");
SOAPElement username = soapFactory.createElement(userQName);
username.addTextNode(MY_USERNAME);

token.addChildElement(username);
security.addChildElement(token);
Header header = Headers.create(security);
((WSBindingProvider)servis).setOutboundHeaders(header);
}

after adding header to webservice calls following annoying problem popped up;


com.sun.xml.internal.messaging.saaj.soap.LocalStrings != com.sun.xml.messaging.saaj.soap.LocalStrings


some of the pages on the web tell this is a java bug some other says this is a saaj version problem. Whatever, after working more than 8 hours i end up with the following solution;

1. download saaj-impl-1.3.3.jar
2. create an endorsed folder under the JAVA_HOME/lib and copy the new saaj-impl.jar to here. (Be sure weblogic server uses this directory to run application server instances)

I tried this solution with weblogic 10.3.0 and 10.3.2 and it's works ...

Pazartesi, Şubat 22, 2010

Adding basic authentication mechanism to JAX-WS web services under Weblogic 10.3

all of us know writing web services with JAX-WS is a piece of cake. But adding basic authentication to these web services under Weblogic 10.3 might be a little annoying. Here is the basic steps to add basic authentication:

first we need to add following configuration to web.xml file of our application;

<security-constraint>
<web-resource-collection>
<web-resource-name>protect</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<!-- role name with access -->
<role-name>DEFINED_WEBLOGIC_ROLE</role-name>
</auth-constraint>
</security-constraint>
<!-- BASIC authentication -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>myrealm</realm-name>
</login-config>
<!-- Define security roles -->
<security-role>
<description>Role</description>
<role-name>DEFINED_WEBLOGIC_ROLE</role-name>
</security-role>

after that we need to add following configuration to weblogic.xml file

<security-role-assignment>
<role-name>DEFINED_WEBLOGIC_ROLE</role-name>
<principal-name>DEFINED_WEBLOGIC_USER</principal-name>
</security-role-assignment>

and that's the all of the modifications we have to make in our application. Now we need to define role (DEFINED_WEBLOGIC_ROLE) and user (DEFINED_WEBLOGIC_USER) in the weblogic by using management console and following Security Realms -> myrealm -> Users and Groups -> Users/Groups menu steps. Don't forget to add the new created user to the group you just defined.

After restarting your server and application you can check security configuration by using following code
UserOperations userOperations = (new UserOperationsService()).getUserOperationsPort();
BindingProvider provider = (BindingProvider) userOperations;
provider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "username");
provider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");

or using soapui, you can set username and password in the Aut tab of the request as shown the picture below;