Peter Arockiaraj

Can you hear me now?…Good!

Developing CXF WS-Security with Spring & Acegi Security


Introduction

In this article we are going to develop a web service by using Spring with CXF and the Acegi Security. This article provides steps (step by step) to create &  deploy web services by using Spring,CXF andAcegi Security. Please go through below to find sample web services.

Software Requirements

  1. EClipse (Java IDE)- Optional
  2. CXF Jars (Required for Compilation-Download from http://cxf.apache.org/download.html)

The Code

In this example, we are going to create a Hello service. In this example, we are going to use a code-first approach for this service using JAX-WS annotations.

Creating Server Application

Step 1:   Download Following Jar files.

activation.jar

aopalliance-1.0.jar

commons-collections-3.2.jar

commons-lang-2.1.jar

commons-logging-1.1.jar

geronimo-activation-2.0.1.jar

geronimo-annotation_1.0_spec-1.1.jar

geronimo-javamail_1.4_mail-1.2.jar

geronimo-servlet_2.5_spec-1.1.jar

geronimo-ws-metadata_2.0_spec-1.1.1.jar

jaxb-api.jar

jaxb-api-2.0.jar

jaxb-impl-2.0.5.jar

jaxb-xjc.jar

jaxws-api.jar

mail.jar

neethi-2.0.jar

opensaml-1.0.1.jar

saaj-api.jar

saaj-impl.jar

spring-beans-2.0.6.jar

spring-context-2.0.6.jar

spring-core-2.0.6.jar

spring-web-2.0.6.jar

stax-api-1.0.1.jar

velocity-1.5.jar

wsdl4j-1.6.1.jar

wstx-asl-3.2.1.jar

xalan-2[1].6.0.jar

xalan-2[1].7.0.jar

xml-resolver-1.2.jar

xmlsec-1.2.1.jar

cxf-bundle-2.0.4-incubator.jar

XmlSchema-1.3.2.jar

wss4j-1.5.1.jar

acegi-security-1.0.5.jar

spring-dao-2.0.7.jar

Step 2: Create New Java project in eclipse (CXFAcegiSecurity).

Step 3: Create WEB-INF folder inside project folder.

Step 4: Create classes folder inside WEB-INF folder.

Step 5: Create lib folder inside WEB-INF folder.

Step 6: Copy all the jar file into lib folder.

Step 7: Add all jar files into classpath (In Eclipse set java build path->Libraries). Add set Default output folder into CXFAcegiSecurity/WEB-INF/classes

Step 8: Create Remote Interface IHello.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 9: Create Implementation Class IHello_Impl.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService(endpointInterface = “com.sungard.cxf.example.server.IHello”)

public class IHello_Impl implements IHello {

public String sayHello(String value) {

return “You Said” + value;

}

}

Step 10: Create User.java to store User details in java object. Acegi Security Service is using this object.

package com.sungard.cxf.example.server;

public class User {

private String userId;

private String password;

private String role;

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public String getRole() {

return role;

}

public void setRole(String role) {

this.role = role;

}

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public User(String userId, String password, String role) {

super();

this.userId = userId;

this.password = password;

this.role = role;

}

}

Step 11: Create MyGrantedAuthority.java to grand Authority.

package com.sungard.cxf.example.server;

import org.acegisecurity.GrantedAuthority;

public class MyGrantedAuthority implements GrantedAuthority {

private String authority = null;

public MyGrantedAuthority(String authority) {

this.authority = authority;

}

public String getAuthority() {

return authority;

}

}

Step 12: Create MyUserDetails.java class to Store User details.

package com.sungard.cxf.example.server;

import org.acegisecurity.GrantedAuthority;

import org.acegisecurity.userdetails.UserDetails;

public class MyUserDetails implements UserDetails {

private GrantedAuthority[] authorities = null;

private String password = null;

private String username = null;

private String additionalData = null;

public MyUserDetails(GrantedAuthority[] authorities, String password,

String username, String additionalData) {

super();

this.authorities = authorities;

this.password = password;

this.username = username;

this.additionalData = additionalData;

}

public GrantedAuthority[] getAuthorities() {

return authorities;

}

public String getPassword() {

return password;

}

public String getUsername() {

return username;

}

public boolean isAccountNonExpired() {

return true;

}

public boolean isAccountNonLocked() {

return true;

}

public boolean isCredentialsNonExpired() {

return true;

}

public boolean isEnabled() {

return true;

}

}

Step 13: Create MyUserDetailsService.java to load user details. By creating these classes we are customizing Acegi security framework

In this class I have used peter as user. You can use any name.

tUsers.put(“peter”, new User(“peter”, “arockiaraj”, “ROLE_ADMIN”));

package com.sungard.cxf.example.server;

import java.util.HashMap;

import java.util.Map;

import org.acegisecurity.GrantedAuthority;

import org.acegisecurity.userdetails.UserDetails;

import org.acegisecurity.userdetails.UserDetailsService;

import org.acegisecurity.userdetails.UsernameNotFoundException;

import org.springframework.dao.DataAccessException;

public class MyUserDetailsService implements UserDetailsService {

private Map users = init();

private Map init() {

Map tUsers = new HashMap();

tUsers.put(“scott”, new User(“scott”, “tiger”, “ROLE_USER”));

tUsers.put(“harry”, new User(“harry”, “potter”, “ROLE_ADMIN”));

tUsers.put(“frodo”, new User(“frodo”, “baggins”, “ROLE_USER”));

tUsers.put(“peter”, new User(“peter”, “arockiaraj”, “ROLE_ADMIN”));

return tUsers;

}

public UserDetails loadUserByUsername(String s)

throws UsernameNotFoundException, DataAccessException {

User user = (User) users.get(s);

GrantedAuthority authority = new MyGrantedAuthority(user.getRole());

UserDetails userDetails = new MyUserDetails(

new GrantedAuthority[] { authority }, user.getUserId(), user

.getPassword(), “Additional Data”);

return userDetails;

}

}

Step 14:  Create PasswordHandler.java file to handle usernames and passwords.

if (pc.getIdentifer().equals(“satnewpubcert”)) {

pc.setPassword(“satsat”);

}

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordHandler implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

System.out.println(“Enterd PasswordHandler::handle”);

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

if (pc.getIdentifer().equals(“satnewpubcert”)) {

pc.setPassword(“satsat”);

}

System.out.println(“Leaving PasswordHandler::handle”);

}

}

Step 15: Create ValidateUserTokenAcegiInterceptor.java class to handle soap requests. If you have proper Acegi Database setup then in this you have to UserDetailsService instead of MyUserDetailsService class. And MyGrantedAuthority.java, MyUserDetails.java, MyUserDetailsService.java, User.java classes are not required in this project.

package com.sungard.cxf.example.server;

import java.util.Vector;

import javax.servlet.http.HttpServletRequest;

import org.acegisecurity.context.SecurityContextHolder;

import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;

import org.acegisecurity.ui.WebAuthenticationDetails;

import org.apache.cxf.binding.soap.SoapMessage;

import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;

import org.apache.cxf.interceptor.Fault;

import org.apache.cxf.phase.Phase;

import org.apache.ws.security.WSSecurityEngineResult;

import org.apache.ws.security.WSUsernameTokenPrincipal;

import org.apache.ws.security.handler.WSHandlerConstants;

import org.apache.ws.security.handler.WSHandlerResult;

/**

* A WS-Security handler used to validate the user token passed in to the web

* service via the header of the soap packet.

*

* You shouldn’t have to change this class at all unless you want to inspect

* specific properties of the incoming WS-Security message.

*

*/

public class ValidateUserTokenAcegiInterceptor extends AbstractSoapInterceptor {

private MyUserDetailsService userDetailsService=new MyUserDetailsService();

public ValidateUserTokenAcegiInterceptor(String s) {

super(s);

}

public ValidateUserTokenAcegiInterceptor() {

super(Phase.UNMARSHAL);

}

public void handleMessage(SoapMessage message) throws Fault {

boolean userTokenValidated = false;

// if user still has a security context session open from a previous

// request, we probably don’t need to re-auth them

// debug stuff the message has…

// for(String key: message.keySet()) {

// System.out.println(“key: [“+key+”,”+message.get(key)+”]”);

// }

Vector result = (Vector) message

.getContextualProperty(WSHandlerConstants.RECV_RESULTS);

for (int i = 0; i < result.size(); i++) {

WSHandlerResult res = (WSHandlerResult) result.get(i);

for (int j = 0; j < res.getResults().size(); j++) {

WSSecurityEngineResult secRes = (WSSecurityEngineResult) res

.getResults().get(j);

WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes

.getPrincipal();

// hack, we are just doing plain text…

if (principal.getPassword() != null) {

userTokenValidated = true;

} else {

throw new RuntimeException(

“Invalid Security Header: Please use a password”);

}

// old code to make sure all WS-Security headers are passed in

// and aren’t null

/*

* if(!principal.isPasswordDigest() || principal.getNonce() ==

* null || principal.getPassword() == null) { ||

* principal.getCreatedTime() == null) { throw new

* RuntimeException(“Invalid Security Header”); } else {

* userTokenValidated = true; }

*/

if (userTokenValidated) {

HttpServletRequest request = (HttpServletRequest) message

.get(“HTTP.REQUEST”);

request.getSession(true).getId();// hack to make sure we

// get a session id for

// acegi to use – this

// is needed for the

// concurrent filter

// authenticate with acegi

final UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(

principal.getName(), principal.getPassword());

// message.HTTP_REQUEST_METHOD

authReq.setDetails(new WebAuthenticationDetails(request));

SecurityContextHolder.getContext().setAuthentication(

authReq);

System.out

.println(“ValidateUserTokenAcegiInterceptor::handleMessage::principal.getName()=”

+ principal.getName());

userDetailsService.loadUserByUsername(

principal.getName());

}

}

}

if (!userTokenValidated) {

throw new RuntimeException(“Security processing failed”);

}

}

}

Step 16: Create beans.xml file to setup the application context for the server. If you are proper Acegi Database setup then you have to configure data source.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<import resource=”classpath:META-INF/cxf/cxf.xml” />

<import resource=”classpath:META-INF/cxf/cxf-extension-soap.xml” />

<import resource=”classpath:META-INF/cxf/cxf-servlet.xml” />

<jaxws:endpoint id=”helloWorld”

implementor=”com.sungard.cxf.example.server.IHello_Impl”

address=”/HelloService”>

<jaxws:inInterceptors>

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean

/>

<bean

>

<property name=”properties”>

<map>

<entry key=”action”

value=”UsernameToken” />

<entry key=”passwordType” value=”PasswordText” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.PasswordHandler” />

</map>

</property>

</bean>

<bean

/>

</jaxws:inInterceptors>

</jaxws:endpoint>

<bean id=”userDetailsService”

>

</bean>

</beans>

Step 17: Create web.xml file

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<servlet>

<servlet-name>CXFServlet</servlet-name>

<display-name>CXF Servlet</display-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 18: Create ant folder inside project. And Create build.xml file inside ant folder.

<?xml version=”1.0″ encoding=”UTF-8″?>

<project name=”ws” basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”acegisecurity.war”>

<fileset dir=”${basedir}”>

<include name=”**/*.class” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml” />

<exclude name=”**/*build*” />

</fileset>

</jar>

</target>

</project>

Step 19: Run build.xml using Ant.

Step 20: Deploy acegisecurity.war into Web/Application Server (Tomcat/JBoss).

Step 21: Verify application deployed successfully or by using following url.
http://localhost:8080/acegisecurity/HelloService?wsdl

Step 22: Browser will show wsdl file our web service.

Creating Client Application.

Step 1: Create New Java project in Eclipse

Step 2: Create folder Structure as like above application

Step 3: Use same jar files used for Server application.

Step 4: Set all the jars files into classpath.

Step 5: Create Remote Interface in client (IHello.java) (You can use wsdl2java for creating same)

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 6: Create ClientPasswordCallback.java for handling soap request in client side.

pc.setPassword(“arockiaraj”);

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

// set the password for our message.

pc.setPassword(“arockiaraj”);

}

}

Step 7: Create the service factory (AuthServiceFactory.java), which is extremely easy since all the work was done in the Spring file:

package com.sungard.cxf.example.server;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class AuthServiceFactory {

private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

new String[] { “cxfClient.xml” });

public AuthServiceFactory() {

}

public IHello getService() {

return (IHello) context.getBean(“client”);

}

}

Step 8: Create Client.java to invoke the service.

package com.sungard.cxf.example.server;

public final class Client {

private Client() {

}

public static void main(String args[]) throws Exception {

AuthServiceFactory af = new AuthServiceFactory();

IHello client1 = af.getService();

String response1 = client1.sayHello(“Hello”);

System.out.println(“Response: ” + response1);

}

}

Step 9: Create cxfClient.xml to setup the application context for the client.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<bean id=”proxyFactory”

>

<property name=”serviceClass”

value=”com.sungard.cxf.example.server.IHello” />

<property name=”address”

value=”http://localhost:8080/acegisecurity/HelloService&#8221; />

<property name=”inInterceptors”>

<list>

<ref bean=”logIn” />

</list>

</property>

<property name=”outInterceptors”>

<list>

<ref bean=”logOut” />

<ref bean=”saajOut” />

<ref bean=”wss4jOut” />

</list>

</property>

</bean>

<bean id=”client”

factory-bean=”proxyFactory” factory-method=”create” />

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean id=”saajOut”

/>

<bean id=”wss4jOut”

>

<constructor-arg>

<map>

<entry key=”action” value=”UsernameToken” />

<entry key=”user” value=”peter” />

<entry key=”passwordType” value=”PasswordDigest” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.ClientPasswordCallback” />

</map>

</constructor-arg>

</bean>

</beans>

Step 10:  Run Client.java

You will get response like as follows.

Response: You SaidHello

Note:

Client Side:

We Set User name in client cxfClient.xml file. (We can set the same through program also and we can read it xml/properties files. We can pass the same in runtime also)

<entry key=“user” value=“peter”/>

We Set password in ClientPasswordCallback.java class (We can pass same in runtime also)

// set the password for our message.

pc.setPassword(“arockiaraj”);

You can see the In & Outbound Messages in Client Side.

INFO: Outbound Message

—————————

Encoding: UTF-8

Headers: {SOAPAction=[“”], Accept=[*]}

Messages:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”&gt;

<soap:Header>

<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221; soap:mustUnderstand=”1″><wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”UsernameToken-23954271″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”><wsse:Username xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>arsenal</wsse:Username><wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest&#8221; xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>U6FK/CmMuPoKaB+SzgY4VNYed2U=</wsse:Password><wsse:Nonce xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>CdPEvSgU87L+4VR4SZxPQQ==</wsse:Nonce><wsu:Created xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>2008-03-27T12:53:36.713Z</wsu:Created></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ns1:sayHello xmlns:ns1=”http://server.example.cxf.sungard.com/”><arg0>Hello</arg0></ns1:sayHello></soap:Body></soap:Envelope&gt;

————————————–

Mar 27, 2008 6:23:37 PM org.apache.cxf.interceptor.LoggingInInterceptor logging

INFO: Inbound Message

—————————-

Encoding: UTF-8

Headers: {content-type=[text/xml;charset=UTF-8], Date=[Thu, 27 Mar 2008 12:53:37 GMT], Content-Length=[230], SOAPAction=[“”], Server=[Apache-Coyote/1.1]}

Messages:

Message:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”><soap:Body><ns1:sayHelloResponse xmlns:ns1=”http://server.example.cxf.sungard.com/”><return>You SaidHello</return></ns1:sayHelloResponse></soap:Body></soap:Envelope>

————————————–

Server Side:

User Name and password are got validated in PasswordHandler.java file. These values we can read it from xml/properties or from configuration files.

if (pc.getIdentifer().equals(“peter”)) {

pc.setPassword(“arockiaraj”);

}

September 4, 2009 Posted by | Web Services | 2 Comments

Developing CXF WS-Security with SAML


Introduction

In this article we are going to develop a web service by using Spring and CXF with WS-Security (SAML). This article provides steps (step by step) to create &  deploy web services by usingSpring and CXF with WS-Security (SAML). Please go through below to find sample web services.

Software Requirements

  1. EClipse (Java IDE)- Optional
  2. CXF Jars (Required for Compilation-Download from http://cxf.apache.org/download.html)

The Code

In this example, we are going to create a Hello service. In this example, we are going to use a code-first approach for this service using JAX-WS annotations.

Creating Server and Client Certificates

For the Signature and Encryption actions, you’ll need to create a public & private key for the entities involved. You can generate a key pair for the development environment via the following steps. Keep in mind these will not be signed by an external authority like Verisign

Keytool is inbuild tool which is comes with jdk.

Follow the steps to create client and server certificates (Refer following site)

  1. http://pa55word.wordpress.com/

When urgently you need some keystores and truststores to test out some security related java code this is a useful bat file to have. Copy the code below and create a bat file. run it and you got your stuff.

keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass changeit -keypass changeit -dname “CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY”


keytool -export -alias serverkeys -keystore server.keystore -storepass changeit -file server.cer


keytool -genkey -alias clientkeys -keyalg RSA -keystore client.keystore -storepass changeit -keypass changeit -dname “CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, S=MY
STATE, C=MY”


keytool -export -alias clientkeys -keystore client.keystore -storepass changeit -file client.cer


keytool -import -v -keystore client.truststore -storepass changeit -file server.cer


keytool -import -v -keystore server.truststore -storepass changeit -file client.cer

It generates a keystore called server.keystore with password changeit. Then it creates server certificate server.cer.

Then it  generates a keystore called client.keystore with password changeit. Creates a client certificate named client.cer

Next it imports server certificate into client truststore and client certificate into server truststore.

These are self signed certificates. Good for internal use. You can use open ssl
and create certificates. But this bat file is short and sweet for immediate use.
When you paste it you do have to be careful about keywords not getting split up like wordpress does.

Creating Server Application

Step 1:   Download Following Jar files.

activation.jar

aopalliance-1.0.jar

commons-collections-3.2.jar

commons-lang-2.1.jar

commons-logging-1.1.jar

geronimo-activation-2.0.1.jar

geronimo-annotation_1.0_spec-1.1.jar

geronimo-javamail_1.4_mail-1.2.jar

geronimo-servlet_2.5_spec-1.1.jar

geronimo-ws-metadata_2.0_spec-1.1.1.jar

jaxb-api.jar

jaxb-api-2.0.jar

jaxb-impl-2.0.5.jar

jaxb-xjc.jar

jaxws-api.jar

mail.jar

neethi-2.0.jar

opensaml-1.0.1.jar

saaj-api.jar

saaj-impl.jar

spring-beans-2.0.6.jar

spring-context-2.0.6.jar

spring-core-2.0.6.jar

spring-web-2.0.6.jar

stax-api-1.0.1.jar

velocity-1.5.jar

wsdl4j-1.6.1.jar

wstx-asl-3.2.1.jar

xalan-2[1].6.0.jar

xalan-2[1].7.0.jar

xml-resolver-1.2.jar

cxf-bundle-2.0.4-incubator.jar

XmlSchema-1.3.2.jar

wss4j-1.5.1.jar

keyexport.jar

pkcs12import.jar

security-plugin.jar

wss-provider-update.jar

xws-security_jaxrpc.jar

xws-security.jar

xmlsec-1.3.0.jar

Step 2: Create New Java project in eclipse (CXFSAMLSecurity).

Step 3: Create WEB-INF folder inside project folder.

Step 4: Create classes folder inside WEB-INF folder.

Step 5: Create lib folder inside WEB-INF folder.

Step 6: Copy all the jar file into lib folder.

Step 7: Add all jar files into classpath (In Eclipse set java build path->Libraries). Add set Default output folder into CXFSAMLSecurity/WEB-INF/classes

Step 8: Create Remote Interface IHello.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 9: Create Implementation Class IHello_Impl.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService(endpointInterface = “com.sungard.cxf.example.server.IHello”)

public class IHello_Impl implements IHello {

public String sayHello(String value) {

return “You Said” + value;

}

}

Step 10:  Create ServerSecurityEnvironmentHandler.java file to handle usernames and passwords. Here you have to give server certificate, server trust certificate alias name for checking. Password is alias password. Also you have to give client keystore file passwords also.

private String keyStorePassword = “changeit”;

private String trustStorePassword = “changeit”;

else if (callbacks[i] instanceof WSPasswordCallback) {

System.out.println(“handle::WSPasswordCallback”);

WSPasswordCallback cb = (WSPasswordCallback) callbacks[i];

cb.setPassword(“changeit”);

}

package com.sungard.cxf.example.server;

import java.io.IOException;

import java.math.BigInteger;

import java.net.URL;

import java.security.KeyStore;

import java.security.PrivateKey;

import java.security.cert.CertPathBuilder;

import java.security.cert.Certificate;

import java.security.cert.CertificateExpiredException;

import java.security.cert.CertificateNotYetValidException;

import java.security.cert.PKIXBuilderParameters;

import java.security.cert.PKIXCertPathBuilderResult;

import java.security.cert.X509CertSelector;

import java.security.cert.X509Certificate;

import java.text.SimpleDateFormat;

import java.util.Arrays;

import java.util.Calendar;

import java.util.Date;

import java.util.Enumeration;

import java.util.GregorianCalendar;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

//import com.sun.org.apache.xml.internal.security.utils.RFC2253Parser;

import com.sun.xml.wss.impl.callback.CertificateValidationCallback;

import com.sun.xml.wss.impl.callback.DecryptionKeyCallback;

import com.sun.xml.wss.impl.callback.EncryptionKeyCallback;

import com.sun.xml.wss.impl.callback.PasswordValidationCallback;

import com.sun.xml.wss.impl.callback.SignatureKeyCallback;

import com.sun.xml.wss.impl.callback.SignatureVerificationKeyCallback;

import com.sun.xml.wss.impl.callback.TimestampValidationCallback;

import com.sun.xml.wss.impl.misc.SecurityUtil;

/**

* A sample implementation of a CallbackHandler.

*/

public class ServerSecurityEnvironmentHandler implements CallbackHandler {

private KeyStore keyStore;

private KeyStore trustStore;

private String keyStorePassword = “changeit”;

private String trustStorePassword = “changeit”;

private static final UnsupportedCallbackException unsupported = new UnsupportedCallbackException(

null, “Unsupported Callback Type Encountered”);

public ServerSecurityEnvironmentHandler() throws Exception {

initTrustStore();

initKeyStore();

}

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

System.out.println(“Entered::ServerSecurityEnvironmentHandler::handle”);

for (int i = 0; i < callbacks.length; i++) {

System.out.println(“handle::For-1”);

if (callbacks[i] instanceof PasswordValidationCallback) {

System.out.println(“handle::PasswordValidationCallback”);

PasswordValidationCallback cb = (PasswordValidationCallback) callbacks[i];

if (cb.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {

System.out.println(“handle::PlainTextPasswordRequest”);

cb.setValidator(new PlainTextPasswordValidator());

} else if (cb.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {

System.out.println(“handle::DigestPasswordRequest”);

PasswordValidationCallback.DigestPasswordRequest request = (PasswordValidationCallback.DigestPasswordRequest) cb

.getRequest();

String username = request.getUsername();

if (“Ron”.equals(username)) {

request.setPassword(“noR”);

cb

.setValidator(new PasswordValidationCallback.DigestPasswordValidator());

}

} else {

throw unsupported;

}

} else if (callbacks[i] instanceof TimestampValidationCallback) {

System.out.println(“handle::TimestampValidationCallback”);

TimestampValidationCallback cb = (TimestampValidationCallback) callbacks[i];

cb.setValidator(new DefaultTimestampValidator());

} else if (callbacks[i] instanceof SignatureVerificationKeyCallback) {

System.out.println(“handle::SignatureVerificationKeyCallback”);

SignatureVerificationKeyCallback cb = (SignatureVerificationKeyCallback) callbacks[i];

if (cb.getRequest() instanceof SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest) {

System.out.println(“handle::X509SubjectKeyIdentifierBasedRequest”);

// subject keyid request

SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest request = (SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest) cb

.getRequest();

X509Certificate cert = getCertificateFromTrustStore(request

.getSubjectKeyIdentifier());

request.setX509Certificate(cert);

} else if (cb.getRequest() instanceof SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest) {

// issuer serial request

System.out.println(“handle::X509IssuerSerialBasedRequest”);

SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest request = (SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest) cb

.getRequest();

X509Certificate cert = getCertificateFromTrustStore(request

.getIssuerName(), request.getSerialNumber());

request.setX509Certificate(cert);

} else {

throw unsupported;

}

} else if (callbacks[i] instanceof SignatureKeyCallback) {

System.out.println(“handle::SignatureKeyCallback”);

SignatureKeyCallback cb = (SignatureKeyCallback) callbacks[i];

if (cb.getRequest() instanceof SignatureKeyCallback.DefaultPrivKeyCertRequest) {

System.out.println(“handle::DefaultPrivKeyCertRequest”);

// default priv key cert req

SignatureKeyCallback.DefaultPrivKeyCertRequest request = (SignatureKeyCallback.DefaultPrivKeyCertRequest) cb

.getRequest();

getDefaultPrivKeyCert(request);

} else if (cb.getRequest() instanceof SignatureKeyCallback.AliasPrivKeyCertRequest) {

System.out.println(“handle::AliasPrivKeyCertRequest”);

SignatureKeyCallback.AliasPrivKeyCertRequest request = (SignatureKeyCallback.AliasPrivKeyCertRequest) cb

.getRequest();

String alias = request.getAlias();

try {

X509Certificate cert = (X509Certificate) keyStore

.getCertificate(alias);

request.setX509Certificate(cert);

// Assuming key passwords same as the keystore password

PrivateKey privKey = (PrivateKey) keyStore.getKey(

alias, keyStorePassword.toCharArray());

request.setPrivateKey(privKey);

} catch (Exception e) {

System.out.println(“handle::AliasPrivKeyCertRequest::Exception”);

throw new IOException(e.getMessage());

}

} else {

System.out.println(“handle::AliasPrivKeyCertRequest::Exception::own::1”);

throw unsupported;

}

} else if (callbacks[i] instanceof DecryptionKeyCallback) {

DecryptionKeyCallback cb = (DecryptionKeyCallback) callbacks[i];

System.out.println(“handle::DecryptionKeyCallback”);

if (cb.getRequest() instanceof DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest) {

System.out.println(“handle::X509SubjectKeyIdentifierBasedRequest”);

DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest request = (DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest) cb

.getRequest();

byte[] ski = request.getSubjectKeyIdentifier();

PrivateKey privKey = getPrivateKey(ski);

request.setPrivateKey(privKey);

} else if (cb.getRequest() instanceof DecryptionKeyCallback.X509IssuerSerialBasedRequest) {

System.out.println(“handle::X509IssuerSerialBasedRequest”);

DecryptionKeyCallback.X509IssuerSerialBasedRequest request = (DecryptionKeyCallback.X509IssuerSerialBasedRequest) cb

.getRequest();

String issuerName = request.getIssuerName();

BigInteger serialNumber = request.getSerialNumber();

PrivateKey privKey = getPrivateKey(issuerName, serialNumber);

request.setPrivateKey(privKey);

} else if (cb.getRequest() instanceof DecryptionKeyCallback.X509CertificateBasedRequest) {

System.out.println(“handle::X509CertificateBasedRequest”);

DecryptionKeyCallback.X509CertificateBasedRequest request = (DecryptionKeyCallback.X509CertificateBasedRequest) cb

.getRequest();

X509Certificate cert = request.getX509Certificate();

PrivateKey privKey = getPrivateKey(cert);

request.setPrivateKey(privKey);

} else {

System.out.println(“handle::X509CertificateBasedRequest::Exception::own:2”);

throw unsupported;

}

} else if (callbacks[i] instanceof EncryptionKeyCallback) {

EncryptionKeyCallback cb = (EncryptionKeyCallback) callbacks[i];

System.out.println(“handle::EncryptionKeyCallback”);

if (cb.getRequest() instanceof EncryptionKeyCallback.AliasX509CertificateRequest) {

System.out.println(“handle::AliasX509CertificateRequest”);

EncryptionKeyCallback.AliasX509CertificateRequest request = (EncryptionKeyCallback.AliasX509CertificateRequest) cb

.getRequest();

String alias = request.getAlias();

if (alias == null) {

System.out.println(“handle::AliasX509CertificateRequest::read”);

// plugin code here to read the cert from the

// ThreadLocal

} else {

try {

System.out.println(“handle::AliasX509CertificateRequest:try”);

X509Certificate cert = (X509Certificate) trustStore

.getCertificate(alias);

request.setX509Certificate(cert);

} catch (Exception e) {

System.out.println(“handle::AliasX509CertificateRequest::Exception”);

throw new IOException(e.getMessage());

}

}

} else {

System.out.println(“handle::AliasX509CertificateRequest::Exception::own::3”);

throw unsupported;

}

} else if (callbacks[i] instanceof CertificateValidationCallback) {

System.out.println(“handle::CertificateValidationCallback”);

CertificateValidationCallback cb = (CertificateValidationCallback) callbacks[i];

cb.setValidator(new X509CertificateValidatorImpl());

} else if (callbacks[i] instanceof CertificateValidationCallback) {

System.out.println(“handle::CertificateValidationCallback”);

CertificateValidationCallback cb = (CertificateValidationCallback) callbacks[i];

cb.setValidator(new X509CertificateValidatorImpl());

} else if (callbacks[i] instanceof WSPasswordCallback) {

System.out.println(“handle::WSPasswordCallback”);

WSPasswordCallback cb = (WSPasswordCallback) callbacks[i];

System.out.println(“handle::cb.getPassword()”+cb.getPassword());

cb.setPassword(“changeit”);

} else {

System.out.println(“handle::CallBack Class Name::”+callbacks[i].getClass().getName());

System.out.println(“handle::CertificateValidationCallback::Exception::own::4”);

throw unsupported;

}

}

System.out.println(“Leaving::ServerSecurityEnvironmentHandler::handle”);

}

private void initTrustStore() throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::initTrustStore”);

try {

URL truststoreURL = SecurityUtil

.loadFromClasspath(“server-truststore.jks”);

trustStore = KeyStore.getInstance(“JKS”);

trustStore.load(truststoreURL.openStream(), trustStorePassword

.toCharArray());

} catch (Exception e) {

e.printStackTrace();

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::initTrustStore”);

}

private void initKeyStore() throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::initKeyStore”);

try {

URL keystoreURL = SecurityUtil

.loadFromClasspath(“server-keystore.jks”);

keyStore = KeyStore.getInstance(“JKS”);

keyStore.load(keystoreURL.openStream(), keyStorePassword

.toCharArray());

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::initKeyStore”);

}

private X509Certificate getCertificateFromTrustStore(byte[] ski)

throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore”);

try {

Enumeration aliases = trustStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

Certificate cert = trustStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

byte[] keyId = getSubjectKeyIdentifier(x509Cert);

if (keyId == null) {

// Cert does not contain a key identifier

continue;

}

if (Arrays.equals(ski, keyId)) {

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore::1”);

return x509Cert;

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore::2”);

return null;

}

private X509Certificate getCertificateFromTrustStore(String issuerName,

BigInteger serialNumber) throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore::Multiple”);

try {

Enumeration aliases = trustStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

Certificate cert = trustStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

String thisIssuerName = org.apache.xml.security.utils.RFC2253Parser.normalize(x509Cert

.getIssuerDN().getName());

BigInteger thisSerialNumber = x509Cert.getSerialNumber();

if (thisIssuerName.equals(issuerName)

&& thisSerialNumber.equals(serialNumber)) {

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore::Multiple::1”);

return x509Cert;

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getCertificateFromTrustStore::Multiple::2”);

return null;

}

public PrivateKey getPrivateKey(byte[] ski) throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getPrivateKey”);

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

byte[] keyId = getSubjectKeyIdentifier(x509Cert);

if (keyId == null) {

// Cert does not contain a key identifier

continue;

}

if (Arrays.equals(ski, keyId)) {

// Asuumed key password same as the keystore password

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::2”);

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::2”);

return null;

}

public PrivateKey getPrivateKey(String issuerName, BigInteger serialNumber)

throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getPrivateKey::multiple”);

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

String thisIssuerName = org.apache.xml.security.utils.RFC2253Parser.normalize(x509Cert

.getIssuerDN().getName());

BigInteger thisSerialNumber = x509Cert.getSerialNumber();

if (thisIssuerName.equals(issuerName)

&& thisSerialNumber.equals(serialNumber)) {

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::multiple::1”);

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::multiple::1”);

return null;

}

public PrivateKey getPrivateKey(X509Certificate certificate)

throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getPrivateKey::certificate”);

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert != null && cert.equals(certificate))

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::certificate::1”);

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getPrivateKey::certificate::2”);

return null;

}

private void getDefaultPrivKeyCert(

SignatureKeyCallback.DefaultPrivKeyCertRequest request)

throws IOException {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getDefaultPrivKeyCert”);

String uniqueAlias = null;

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String currentAlias = (String) aliases.nextElement();

if (keyStore.isKeyEntry(currentAlias)) {

Certificate thisCertificate = keyStore

.getCertificate(currentAlias);

if (thisCertificate != null) {

if (thisCertificate instanceof X509Certificate) {

if (uniqueAlias == null) {

uniqueAlias = currentAlias;

} else {

// Not unique!

uniqueAlias = null;

break;

}

}

}

}

}

if (uniqueAlias != null) {

request.setX509Certificate((X509Certificate) keyStore

.getCertificate(uniqueAlias));

request.setPrivateKey((PrivateKey) keyStore.getKey(uniqueAlias,

keyStorePassword.toCharArray()));

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getDefaultPrivKeyCert”);

}

private static byte[] getSubjectKeyIdentifier(X509Certificate cert) {

System.out

.println(“Entered::ServerSecurityEnvironmentHandler::getSubjectKeyIdentifier”);

String SUBJECT_KEY_IDENTIFIER_OID = “2.5.29.14”;

byte[] subjectKeyIdentifier = cert

.getExtensionValue(SUBJECT_KEY_IDENTIFIER_OID);

if (subjectKeyIdentifier == null)

return null;

try {

sun.security.x509.KeyIdentifier keyId = null;

sun.security.util.DerValue derVal = new sun.security.util.DerValue(

new sun.security.util.DerInputStream(subjectKeyIdentifier)

.getOctetString());

keyId = new sun.security.x509.KeyIdentifier(derVal.getOctetString());

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getSubjectKeyIdentifier::1”);

return keyId.getIdentifier();

} catch (NoClassDefFoundError ncde) {

if (subjectKeyIdentifier == null)

return null;

byte[] dest = new byte[subjectKeyIdentifier.length – 4];

System.arraycopy(subjectKeyIdentifier, 4, dest, 0,

subjectKeyIdentifier.length – 4);

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getSubjectKeyIdentifier::2”);

return dest;

} catch (java.io.IOException ex) {

// ignore

System.out

.println(“Leaving::ServerSecurityEnvironmentHandler::getSubjectKeyIdentifier::3”);

return null;

}

}

private class PlainTextPasswordValidator implements

PasswordValidationCallback.PasswordValidator {

public boolean validate(PasswordValidationCallback.Request request)

throws PasswordValidationCallback.PasswordValidationException {

System.out.println(“Entered::PlainTextPasswordValidator::validate”);

PasswordValidationCallback.PlainTextPasswordRequest plainTextRequest = (PasswordValidationCallback.PlainTextPasswordRequest) request;

if (“Ron”.equals(plainTextRequest.getUsername())

&& “noR”.equals(plainTextRequest.getPassword())) {

System.out

.println(“Leaving::PlainTextPasswordValidator::validate::true”);

return true;

}

System.out

.println(“Leaving::PlainTextPasswordValidator::validate::false”);

return false;

}

}

private class DefaultTimestampValidator implements

TimestampValidationCallback.TimestampValidator {

public void validate(TimestampValidationCallback.Request request)

throws TimestampValidationCallback.TimestampValidationException {

System.out.println(“Entered::DefaultTimestampValidator::validate”);

// validate timestamp creation and expiration time.

TimestampValidationCallback.UTCTimestampRequest utcTimestampRequest = (TimestampValidationCallback.UTCTimestampRequest) request;

SimpleDateFormat calendarFormatter2 = new SimpleDateFormat(

“yyyy-MM-dd’T’HH:mm:ss’Z'”);

SimpleDateFormat calendarFormatter1 = new SimpleDateFormat(

“yyyy-MM-dd’T’HH:mm:ss’.’SSS’Z'”);

Date created = null;

Date expired = null;

try {

try {

created = calendarFormatter1.parse(utcTimestampRequest

.getCreated());

if (utcTimestampRequest.getExpired() != null)

expired = calendarFormatter1.parse(utcTimestampRequest

.getExpired());

} catch (java.text.ParseException pe) {

created = calendarFormatter2.parse(utcTimestampRequest

.getCreated());

if (utcTimestampRequest.getExpired() != null)

expired = calendarFormatter2.parse(utcTimestampRequest

.getExpired());

}

} catch (java.text.ParseException pe) {

throw new TimestampValidationCallback.TimestampValidationException(

pe.getMessage());

}

long maxClockSkew = utcTimestampRequest.getMaxClockSkew();

long timestampFreshnessLimit = utcTimestampRequest

.getTimestampFreshnessLimit();

// validate creation time

validateCreationTime(created, maxClockSkew, timestampFreshnessLimit);

// validate expiration time

if (expired != null)

validateExpirationTime(expired, maxClockSkew,

timestampFreshnessLimit);

System.out.println(“Leaving::DefaultTimestampValidator::validate”);

}

}

public void validateExpirationTime(Date expires, long maxClockSkew,

long timestampFreshnessLimit)

throws TimestampValidationCallback.TimestampValidationException {

System.out

.println(“Enterd::DefaultTimestampValidator::validateExpirationTime”);

Date currentTime = getGMTDateWithSkewAdjusted(new GregorianCalendar(),

maxClockSkew, false);

if (expires.before(currentTime)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The current time is ahead of the expiration time in Timestamp”);

}

System.out

.println(“Leaving::DefaultTimestampValidator::validateExpirationTime”);

}

public void validateCreationTime(Date created, long maxClockSkew,

long timestampFreshnessLimit)

throws TimestampValidationCallback.TimestampValidationException {

System.out

.println(“Enterd::DefaultTimestampValidator::validateCreationTime”);

Date current = getFreshnessAndSkewAdjustedDate(maxClockSkew,

timestampFreshnessLimit);

System.out.println(“Validate Creation time called current=” + current);

System.out.println(“Validate Creation time called created=” + created);

if (created.before(current)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The creation time is older than ”

+ ” currenttime – timestamp-freshness-limit – max-clock-skew”);

}

Date currentTime = getGMTDateWithSkewAdjusted(new GregorianCalendar(),

maxClockSkew, true);

System.out.println(“Validate Creation time called currentTime=”

+ currentTime);

System.out.println(“Validate Creation time called created=” + created);

if (currentTime.before(created)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The creation time is ahead of the current time.”);

}

System.out

.println(“Leaving::DefaultTimestampValidator::validateCreationTime”);

}

private static Date getFreshnessAndSkewAdjustedDate(long maxClockSkew,

long timestampFreshnessLimit) {

System.out

.println(“Enterd::DefaultTimestampValidator::getFreshnessAndSkewAdjustedDate”);

Calendar c = new GregorianCalendar();

long offset = c.get(Calendar.ZONE_OFFSET);

if (c.getTimeZone().inDaylightTime(c.getTime())) {

offset += c.getTimeZone().getDSTSavings();

}

long beforeTime = c.getTimeInMillis();

long currentTime = beforeTime – offset;

System.out.println(“MaxSkew=” + maxClockSkew + ” freshness=”

+ timestampFreshnessLimit);

long adjustedTime = currentTime – maxClockSkew

– timestampFreshnessLimit;

c.setTimeInMillis(adjustedTime);

System.out

.println(“Leaving::DefaultTimestampValidator::getFreshnessAndSkewAdjustedDate”);

return c.getTime();

}

private static Date getGMTDateWithSkewAdjusted(Calendar c,

long maxClockSkew, boolean addSkew) {

System.out

.println(“Enterd::DefaultTimestampValidator::getGMTDateWithSkewAdjusted”);

long offset = c.get(Calendar.ZONE_OFFSET);

if (c.getTimeZone().inDaylightTime(c.getTime())) {

offset += c.getTimeZone().getDSTSavings();

}

long beforeTime = c.getTimeInMillis();

long currentTime = beforeTime – offset;

if (addSkew)

currentTime = currentTime + maxClockSkew;

else

currentTime = currentTime – maxClockSkew;

c.setTimeInMillis(currentTime);

System.out

.println(“Leaving::DefaultTimestampValidator::getGMTDateWithSkewAdjusted”);

return c.getTime();

}

private class X509CertificateValidatorImpl implements

CertificateValidationCallback.CertificateValidator {

public boolean validate(X509Certificate certificate)

throws CertificateValidationCallback.CertificateValidationException {

System.out

.println(“Enterd::X509CertificateValidatorImpl::validate”);

if (isSelfCert(certificate)) {

System.out

.println(“Leaving::X509CertificateValidatorImpl::validate::1”);

return true;

}

try {

certificate.checkValidity();

} catch (CertificateExpiredException e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

“X509Certificate Expired”, e);

} catch (CertificateNotYetValidException e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

“X509Certificate not yet valid”, e);

}

X509CertSelector certSelector = new X509CertSelector();

certSelector.setCertificate(certificate);

PKIXBuilderParameters parameters;

CertPathBuilder builder;

try {

parameters = new PKIXBuilderParameters(trustStore, certSelector);

parameters.setRevocationEnabled(false);

builder = CertPathBuilder.getInstance(“PKIX”);

} catch (Exception e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

e.getMessage(), e);

}

try {

PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder

.build(parameters);

} catch (Exception e) {

e.printStackTrace();

System.out

.println(“Leaving::X509CertificateValidatorImpl::validate::2”);

return false;

}

System.out

.println(“Leaving::X509CertificateValidatorImpl::validate::3”);

return true;

}

private boolean isSelfCert(X509Certificate cert)

throws CertificateValidationCallback.CertificateValidationException {

System.out

.println(“Entered::X509CertificateValidatorImpl::isSelfCert”);

try {

if (keyStore == null)

initKeyStore();

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (keyStore.isKeyEntry(alias)) {

X509Certificate x509Cert = (X509Certificate) keyStore

.getCertificate(alias);

if (x509Cert != null) {

if (x509Cert.equals(cert))

System.out

.println(“Leaving::X509CertificateValidatorImpl::isSelfCert::1”);

return true;

}

}

}

System.out

.println(“Leaving::X509CertificateValidatorImpl::isSelfCert::2”);

return false;

} catch (Exception e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

e.getMessage(), e);

}

}

}

private String getContainerHome() {

System.out

.println(“Entered::X509CertificateValidatorImpl::getContainerHome”);

String _home = “”;

String fileSeparator = System.getProperty(“file.separator”);

String contHome = System.getProperty(“catalina.home”);

if (contHome != null) {

String isAS = System.getProperty(“com.sun.aas.instanceRoot”);

if (isAS != null) {

_home = contHome + fileSeparator + “..” + fileSeparator + “..”;

} else {

_home = contHome;

}

} else {

_home = System.getProperty(“jwsdp.home”);

if (_home == null) {

_home = System.getProperty(“as.home”);

}

}

System.out

.println(“Leaving::X509CertificateValidatorImpl::getContainerHome”);

return _home;

}

}

Step 11: Create Interceptor class to handle soap requests ValidateUserTokenInterceptor.java.

package com.sungard.cxf.example.server;

import java.util.Vector;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

import org.apache.ws.security.WSSecurityEngineResult;

import org.apache.ws.security.WSUsernameTokenPrincipal;

import org.apache.ws.security.handler.WSHandlerConstants;

import org.apache.ws.security.handler.WSHandlerResult;

public class ValidateUserTokenInterceptor extends AbstractPhaseInterceptor {

public ValidateUserTokenInterceptor(String s) {

super(s);

}

public ValidateUserTokenInterceptor() {

super(Phase.UNMARSHAL);

}

public void handleMessage(Message message) {

System.out

.println(“Enterd ValidateUserTokenInterceptor::handleMessage”);

boolean userTokenValidated = false;

Vector result = (Vector) message

.getContextualProperty(WSHandlerConstants.RECV_RESULTS);

for (int i = 0; i < result.size(); i++) {

WSHandlerResult res = (WSHandlerResult) result.get(i);

for (int j = 0; j < res.getResults().size(); j++) {

WSSecurityEngineResult secRes = (WSSecurityEngineResult) res

.getResults().get(j);

if (secRes.getPrincipal() != null) {

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::Class”

+ secRes.getPrincipal().getClass());

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::ClassName”

+ secRes.getPrincipal().getClass()

.getName());

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::Name”

+ secRes.getPrincipal().getName());

if (secRes.getPrincipal().getClass().getName().equals(

“org.apache.ws.security.WSUsernameTokenPrincipal”)) {

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::WSUsernameTokenPrincipal”

+ secRes.getPrincipal().getName());

WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes

.getPrincipal();

System.out.println(“principal.isPasswordDigest”

+ principal.isPasswordDigest());

System.out.println(“principal.getNonce()”

+ principal.getNonce());

System.out.println(“principal.getPassword()”

+ principal.getPassword());

System.out.println(“principal.getCreatedTime()”

+ principal.getCreatedTime());

if (principal.getPassword() == null) {

throw new RuntimeException(

“Invalid Security Header”);

} else {

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::userTokenValidated = true”);

userTokenValidated = true;

}

}

}

}

}

if (!userTokenValidated) {

throw new RuntimeException(“Security processing failed::Peter”);

}

System.out

.println(“Leaving ValidateUserTokenInterceptor::handleMessage”);

}

}

Step 12: Create beans.xml file to setup the application context for the server.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<import resource=”classpath:META-INF/cxf/cxf.xml” />

<import resource=”classpath:META-INF/cxf/cxf-extension-soap.xml” />

<import resource=”classpath:META-INF/cxf/cxf-servlet.xml” />

<jaxws:endpoint id=”helloWorld”

implementor=”com.sungard.cxf.example.server.IHello_Impl”

address=”/HelloService”>

<jaxws:inInterceptors>

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean

/>

<bean

>

<property name=”properties”>

<map>

<entry key=”action”

value=”UsernameToken SAMLTokenUnsigned” />

<entry key=”passwordType” value=”PasswordText” />

<entry key=”enableNamespacePrefixOptimization”

value=”true” />

<entry key=”disablePrettyXML” value=”true” />

<entry key=”sendXsiTypes” value=”true” />

<entry key=”sendMultiRefs” value=”true” />

<entry key=”sendXMLDeclaration” value=”true” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.ServerSecurityEnvironmentHandler” />

<entry key=”signaturePropFile”

value=”server_sign.properties”>

</entry>

</map>

</property>

</bean>

<bean

/>

</jaxws:inInterceptors>

</jaxws:endpoint>

</beans>

Step 13: Create server_sign.properties under WEB-INF\classes folder to mention private keystore file details.

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.type=jks

org.apache.ws.security.crypto.merlin.keystore.password=changeit

org.apache.ws.security.crypto.merlin.file=server-keystore.jks

Step 14: Copy all keystore and certificate files under WEB-INF\classes folder.

Step 15: Create web.xml file

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<servlet>

<servlet-name>CXFServlet</servlet-name>

<display-name>CXF Servlet</display-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 16: Create ant folder inside project. And Create build.xml file inside ant folder.

<?xml version=”1.0″ encoding=”UTF-8″?>

<project basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”samlnormalsecurity.war”>

<fileset dir=”${basedir}”>

<include name=”**/*.class” />

<include name=”**/*.jks*” />

<include name=”**/*.properties*” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml” />

<exclude name=”**/*build*” />

</fileset>

</jar>

</target>

</project>

Step 17: Run build.xml using Ant.

Step 18: Deploy samlnormalsecurity.war into Web/Application Server (Tomcat/JBoss).

Step 19: Verify application deployed successfully or by using following url.
http://localhost:8080/samlnormalsecurity/HelloService?wsdl

Step 20: Browser will show wsdl file our web service.

 

Creating Client Application.

Step 1: Create New Java project in Eclipse

Step 2: Create folder Structure as like above application

Step 3: Use same jar files used for Server application.

Step 4: Set all the jars files into classpath.

Step 5: Create Remote Interface in client (IHello.java) (You can use wsdl2java for creating same)

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 6: Create ClientSecurityEnvironmentHandler.java for handling soap request in client side. Here you have set the password what you are given client alias. You have tomention client ketstore passwords also here.

private String keyStorePassword = “changeit”;

private String trustStorePassword = “changeit”;

else if (callbacks[i] instanceof WSPasswordCallback) {

WSPasswordCallback cb = (WSPasswordCallback) callbacks[i];

System.out.println(“cb.getPassword()” + cb.getPassword());

cb.setPassword(“changeit”);

}

package com.sungard.cxf.example.server;

import java.io.IOException;

import java.math.BigInteger;

import java.net.URL;

import java.security.KeyStore;

import java.security.PrivateKey;

import java.security.cert.CertPathBuilder;

import java.security.cert.Certificate;

import java.security.cert.CertificateExpiredException;

import java.security.cert.CertificateNotYetValidException;

import java.security.cert.PKIXBuilderParameters;

import java.security.cert.PKIXCertPathBuilderResult;

import java.security.cert.X509CertSelector;

import java.security.cert.X509Certificate;

import java.text.SimpleDateFormat;

import java.util.Arrays;

import java.util.Calendar;

import java.util.Date;

import java.util.Enumeration;

import java.util.GregorianCalendar;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import javax.xml.ws.BindingProvider;

import org.apache.ws.security.WSPasswordCallback;

import com.sun.xml.wss.impl.callback.CertificateValidationCallback;

import com.sun.xml.wss.impl.callback.DecryptionKeyCallback;

import com.sun.xml.wss.impl.callback.EncryptionKeyCallback;

import com.sun.xml.wss.impl.callback.PasswordCallback;

import com.sun.xml.wss.impl.callback.PasswordValidationCallback;

import com.sun.xml.wss.impl.callback.SignatureKeyCallback;

import com.sun.xml.wss.impl.callback.SignatureVerificationKeyCallback;

import com.sun.xml.wss.impl.callback.TimestampValidationCallback;

import com.sun.xml.wss.impl.callback.UsernameCallback;

import com.sun.xml.wss.impl.misc.SecurityUtil;

/**

* A sample implementation of a CallbackHandler.

*/

public class ClientSecurityEnvironmentHandler implements CallbackHandler {

private KeyStore keyStore;

private KeyStore trustStore;

private String keyStorePassword = “changeit”;

private String trustStorePassword = “changeit”;

private static final UnsupportedCallbackException unsupported = new UnsupportedCallbackException(

null, “Unsupported Callback Type Encountered”);

public ClientSecurityEnvironmentHandler() throws Exception {

System.out.println(“Entered::ClientSecurityEnvironmentHandler”);

initTrustStore();

initKeyStore();

System.out.println(“Leaving::ClientSecurityEnvironmentHandler”);

}

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

System.out.println(“Entered::ClientSecurityEnvironmentHandler::handle”);

for (int i = 0; i < callbacks.length; i++) {

if (callbacks[i] instanceof PasswordValidationCallback) {

PasswordValidationCallback cb = (PasswordValidationCallback) callbacks[i];

if (cb.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {

cb.setValidator(new PlainTextPasswordValidator());

} else if (cb.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {

PasswordValidationCallback.DigestPasswordRequest request = (PasswordValidationCallback.DigestPasswordRequest) cb

.getRequest();

String username = request.getUsername();

if (“Ron”.equals(username)) {

request.setPassword(“noR”);

cb

.setValidator(new PasswordValidationCallback.DigestPasswordValidator());

}

} else {

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::1”);

throw unsupported;

}

} else if (callbacks[i] instanceof TimestampValidationCallback) {

TimestampValidationCallback cb = (TimestampValidationCallback) callbacks[i];

cb.setValidator(new DefaultTimestampValidator());

} else if (callbacks[i] instanceof SignatureVerificationKeyCallback) {

SignatureVerificationKeyCallback cb = (SignatureVerificationKeyCallback) callbacks[i];

if (cb.getRequest() instanceof SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest) {

// subject keyid request

SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest request = (SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest) cb

.getRequest();

X509Certificate cert = getCertificateFromTrustStore(request

.getSubjectKeyIdentifier());

request.setX509Certificate(cert);

} else if (cb.getRequest() instanceof SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest) {

// issuer serial request

SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest request = (SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest) cb

.getRequest();

X509Certificate cert = getCertificateFromTrustStore(request

.getIssuerName(), request.getSerialNumber());

request.setX509Certificate(cert);

} else {

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::2”);

throw unsupported;

}

} else if (callbacks[i] instanceof SignatureKeyCallback) {

SignatureKeyCallback cb = (SignatureKeyCallback) callbacks[i];

if (cb.getRequest() instanceof SignatureKeyCallback.DefaultPrivKeyCertRequest) {

// default priv key cert req

SignatureKeyCallback.DefaultPrivKeyCertRequest request = (SignatureKeyCallback.DefaultPrivKeyCertRequest) cb

.getRequest();

getDefaultPrivKeyCert(request);

} else if (cb.getRequest() instanceof SignatureKeyCallback.AliasPrivKeyCertRequest) {

SignatureKeyCallback.AliasPrivKeyCertRequest request = (SignatureKeyCallback.AliasPrivKeyCertRequest) cb

.getRequest();

String alias = request.getAlias();

try {

X509Certificate cert = (X509Certificate) keyStore

.getCertificate(alias);

request.setX509Certificate(cert);

// Assuming key passwords same as the keystore password

PrivateKey privKey = (PrivateKey) keyStore.getKey(

alias, keyStorePassword.toCharArray());

request.setPrivateKey(privKey);

} catch (Exception e) {

throw new IOException(e.getMessage());

}

} else {

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::3”);

throw unsupported;

}

} else if (callbacks[i] instanceof DecryptionKeyCallback) {

DecryptionKeyCallback cb = (DecryptionKeyCallback) callbacks[i];

if (cb.getRequest() instanceof DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest) {

DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest request = (DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest) cb

.getRequest();

byte[] ski = request.getSubjectKeyIdentifier();

PrivateKey privKey = getPrivateKey(ski);

request.setPrivateKey(privKey);

} else if (cb.getRequest() instanceof DecryptionKeyCallback.X509IssuerSerialBasedRequest) {

DecryptionKeyCallback.X509IssuerSerialBasedRequest request = (DecryptionKeyCallback.X509IssuerSerialBasedRequest) cb

.getRequest();

String issuerName = request.getIssuerName();

BigInteger serialNumber = request.getSerialNumber();

PrivateKey privKey = getPrivateKey(issuerName, serialNumber);

request.setPrivateKey(privKey);

} else if (cb.getRequest() instanceof DecryptionKeyCallback.X509CertificateBasedRequest) {

DecryptionKeyCallback.X509CertificateBasedRequest request = (DecryptionKeyCallback.X509CertificateBasedRequest) cb

.getRequest();

X509Certificate cert = request.getX509Certificate();

PrivateKey privKey = getPrivateKey(cert);

request.setPrivateKey(privKey);

} else {

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::4”);

throw unsupported;

}

} else if (callbacks[i] instanceof EncryptionKeyCallback) {

EncryptionKeyCallback cb = (EncryptionKeyCallback) callbacks[i];

if (cb.getRequest() instanceof EncryptionKeyCallback.AliasX509CertificateRequest) {

EncryptionKeyCallback.AliasX509CertificateRequest request = (EncryptionKeyCallback.AliasX509CertificateRequest) cb

.getRequest();

String alias = request.getAlias();

if (alias == null) {

// plugin code here to read the cert from the

// ThreadLocal

} else {

try {

X509Certificate cert = (X509Certificate) trustStore

.getCertificate(alias);

request.setX509Certificate(cert);

} catch (Exception e) {

throw new IOException(e.getMessage());

}

}

} else {

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::5”);

throw unsupported;

}

} else if (callbacks[i] instanceof CertificateValidationCallback) {

CertificateValidationCallback cb = (CertificateValidationCallback) callbacks[i];

cb.setValidator(new X509CertificateValidatorImpl());

} else if (callbacks[i] instanceof UsernameCallback) {

UsernameCallback cb = (UsernameCallback) callbacks[i];

String username = (String) cb.getRuntimeProperties().get(

BindingProvider.USERNAME_PROPERTY);

System.out.println(“Got Username……… : ” + username);

cb.setUsername(username);

} else if (callbacks[i] instanceof PasswordCallback) {

PasswordCallback cb = (PasswordCallback) callbacks[i];

String password = (String) cb.getRuntimeProperties().get(

BindingProvider.PASSWORD_PROPERTY);

System.out.println(“Got Password……… : ” + password);

cb.setPassword(password);

} else if (callbacks[i] instanceof WSPasswordCallback) {

WSPasswordCallback cb = (WSPasswordCallback) callbacks[i];

System.out.println(“cb.getPassword()” + cb.getPassword());

cb.setPassword(“changeit”);

} else {

System.out.println(callbacks[i].getClass().getName());

System.out

.println(“ClientSecurityEnvironmentHandler::Handle::6”);

throw unsupported;

}

}

}

private void initTrustStore() throws IOException {

try {

URL truststoreURL = SecurityUtil

.loadFromClasspath(“client-truststore.jks”);

trustStore = KeyStore.getInstance(“JKS”);

trustStore.load(truststoreURL.openStream(), trustStorePassword

.toCharArray());

} catch (Exception e) {

throw new IOException(e.getMessage());

}

}

private void initKeyStore() throws IOException {

try {

URL keystoreURL = SecurityUtil

.loadFromClasspath(“client-keystore.jks”);

keyStore = KeyStore.getInstance(“JKS”);

keyStore.load(keystoreURL.openStream(), keyStorePassword

.toCharArray());

} catch (Exception e) {

throw new IOException(e.getMessage());

}

}

private X509Certificate getCertificateFromTrustStore(byte[] ski)

throws IOException {

try {

Enumeration aliases = trustStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

Certificate cert = trustStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

byte[] keyId = getSubjectKeyIdentifier(x509Cert);

if (keyId == null) {

// Cert does not contain a key identifier

continue;

}

if (Arrays.equals(ski, keyId)) {

return x509Cert;

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

return null;

}

private X509Certificate getCertificateFromTrustStore(String issuerName,

BigInteger serialNumber) throws IOException {

try {

Enumeration aliases = trustStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

Certificate cert = trustStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

String thisIssuerName = org.apache.xml.security.utils.RFC2253Parser

.normalize(x509Cert.getIssuerDN().getName());

BigInteger thisSerialNumber = x509Cert.getSerialNumber();

if (thisIssuerName.equals(issuerName)

&& thisSerialNumber.equals(serialNumber)) {

return x509Cert;

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

return null;

}

public PrivateKey getPrivateKey(byte[] ski) throws IOException {

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

byte[] keyId = getSubjectKeyIdentifier(x509Cert);

if (keyId == null) {

// Cert does not contain a key identifier

continue;

}

if (Arrays.equals(ski, keyId)) {

// Asuumed key password same as the keystore password

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

return null;

}

public PrivateKey getPrivateKey(String issuerName, BigInteger serialNumber)

throws IOException {

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert == null || !”X.509″.equals(cert.getType())) {

continue;

}

X509Certificate x509Cert = (X509Certificate) cert;

String thisIssuerName = org.apache.xml.security.utils.RFC2253Parser

.normalize(x509Cert.getIssuerDN().getName());

BigInteger thisSerialNumber = x509Cert.getSerialNumber();

if (thisIssuerName.equals(issuerName)

&& thisSerialNumber.equals(serialNumber)) {

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

return null;

}

public PrivateKey getPrivateKey(X509Certificate certificate)

throws IOException {

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (!keyStore.isKeyEntry(alias))

continue;

Certificate cert = keyStore.getCertificate(alias);

if (cert != null && cert.equals(certificate))

return (PrivateKey) keyStore.getKey(alias, keyStorePassword

.toCharArray());

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

return null;

}

private void getDefaultPrivKeyCert(

SignatureKeyCallback.DefaultPrivKeyCertRequest request)

throws IOException {

String uniqueAlias = null;

try {

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String currentAlias = (String) aliases.nextElement();

if (keyStore.isKeyEntry(currentAlias)) {

Certificate thisCertificate = keyStore

.getCertificate(currentAlias);

if (thisCertificate != null) {

if (thisCertificate instanceof X509Certificate) {

if (uniqueAlias == null) {

uniqueAlias = currentAlias;

} else {

// Not unique!

uniqueAlias = null;

break;

}

}

}

}

}

if (uniqueAlias != null) {

request.setX509Certificate((X509Certificate) keyStore

.getCertificate(uniqueAlias));

request.setPrivateKey((PrivateKey) keyStore.getKey(uniqueAlias,

keyStorePassword.toCharArray()));

}

} catch (Exception e) {

throw new IOException(e.getMessage());

}

}

private static byte[] getSubjectKeyIdentifier(X509Certificate cert) {

String SUBJECT_KEY_IDENTIFIER_OID = “2.5.29.14”;

byte[] subjectKeyIdentifier = cert

.getExtensionValue(SUBJECT_KEY_IDENTIFIER_OID);

if (subjectKeyIdentifier == null)

return null;

try {

sun.security.x509.KeyIdentifier keyId = null;

sun.security.util.DerValue derVal = new sun.security.util.DerValue(

new sun.security.util.DerInputStream(subjectKeyIdentifier)

.getOctetString());

keyId = new sun.security.x509.KeyIdentifier(derVal.getOctetString());

return keyId.getIdentifier();

} catch (NoClassDefFoundError ncde) {

if (subjectKeyIdentifier == null)

return null;

byte[] dest = new byte[subjectKeyIdentifier.length – 4];

System.arraycopy(subjectKeyIdentifier, 4, dest, 0,

subjectKeyIdentifier.length – 4);

return dest;

} catch (java.io.IOException ex) {

// ignore

return null;

}

}

private class PlainTextPasswordValidator implements

PasswordValidationCallback.PasswordValidator {

public boolean validate(PasswordValidationCallback.Request request)

throws PasswordValidationCallback.PasswordValidationException {

PasswordValidationCallback.PlainTextPasswordRequest plainTextRequest = (PasswordValidationCallback.PlainTextPasswordRequest) request;

if (“Ron”.equals(plainTextRequest.getUsername())

&& “noR”.equals(plainTextRequest.getPassword())) {

return true;

}

return false;

}

}

private class DefaultTimestampValidator implements

TimestampValidationCallback.TimestampValidator {

public void validate(TimestampValidationCallback.Request request)

throws TimestampValidationCallback.TimestampValidationException {

// validate timestamp creation and expiration time.

TimestampValidationCallback.UTCTimestampRequest utcTimestampRequest = (TimestampValidationCallback.UTCTimestampRequest) request;

SimpleDateFormat calendarFormatter2 = new SimpleDateFormat(

“yyyy-MM-dd’T’HH:mm:ss’Z'”);

SimpleDateFormat calendarFormatter1 = new SimpleDateFormat(

“yyyy-MM-dd’T’HH:mm:ss’.’SSS’Z'”);

Date created = null;

Date expired = null;

try {

try {

created = calendarFormatter1.parse(utcTimestampRequest

.getCreated());

if (utcTimestampRequest.getExpired() != null)

expired = calendarFormatter1.parse(utcTimestampRequest

.getExpired());

} catch (java.text.ParseException pe) {

created = calendarFormatter2.parse(utcTimestampRequest

.getCreated());

if (utcTimestampRequest.getExpired() != null)

expired = calendarFormatter2.parse(utcTimestampRequest

.getExpired());

}

} catch (java.text.ParseException pe) {

throw new TimestampValidationCallback.TimestampValidationException(

pe.getMessage());

}

long maxClockSkew = utcTimestampRequest.getMaxClockSkew();

long timestampFreshnessLimit = utcTimestampRequest

.getTimestampFreshnessLimit();

// validate creation time

validateCreationTime(created, maxClockSkew, timestampFreshnessLimit);

// validate expiration time

if (expired != null)

validateExpirationTime(expired, maxClockSkew,

timestampFreshnessLimit);

}

}

public void validateExpirationTime(Date expires, long maxClockSkew,

long timestampFreshnessLimit)

throws TimestampValidationCallback.TimestampValidationException {

// System.out.println(“Validate Expiration time called”);

Date currentTime = getGMTDateWithSkewAdjusted(new GregorianCalendar(),

maxClockSkew, false);

if (expires.before(currentTime)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The current time is ahead of the expiration time in Timestamp”);

}

}

public void validateCreationTime(Date created, long maxClockSkew,

long timestampFreshnessLimit)

throws TimestampValidationCallback.TimestampValidationException {

// System.out.println(“Validate Creation time called”);

Date current = getFreshnessAndSkewAdjustedDate(maxClockSkew,

timestampFreshnessLimit);

if (created.before(current)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The creation time is older than ”

+ ” currenttime – timestamp-freshness-limit – max-clock-skew”);

}

Date currentTime = getGMTDateWithSkewAdjusted(new GregorianCalendar(),

maxClockSkew, true);

if (currentTime.before(created)) {

throw new TimestampValidationCallback.TimestampValidationException(

“The creation time is ahead of the current time.”);

}

}

private static Date getFreshnessAndSkewAdjustedDate(long maxClockSkew,

long timestampFreshnessLimit) {

Calendar c = new GregorianCalendar();

long offset = c.get(Calendar.ZONE_OFFSET);

if (c.getTimeZone().inDaylightTime(c.getTime())) {

offset += c.getTimeZone().getDSTSavings();

}

long beforeTime = c.getTimeInMillis();

long currentTime = beforeTime – offset;

long adjustedTime = currentTime – maxClockSkew

– timestampFreshnessLimit;

c.setTimeInMillis(adjustedTime);

return c.getTime();

}

private static Date getGMTDateWithSkewAdjusted(Calendar c,

long maxClockSkew, boolean addSkew) {

long offset = c.get(Calendar.ZONE_OFFSET);

if (c.getTimeZone().inDaylightTime(c.getTime())) {

offset += c.getTimeZone().getDSTSavings();

}

long beforeTime = c.getTimeInMillis();

long currentTime = beforeTime – offset;

if (addSkew)

currentTime = currentTime + maxClockSkew;

else

currentTime = currentTime – maxClockSkew;

c.setTimeInMillis(currentTime);

return c.getTime();

}

private class X509CertificateValidatorImpl implements

CertificateValidationCallback.CertificateValidator {

public boolean validate(X509Certificate certificate)

throws CertificateValidationCallback.CertificateValidationException {

if (isSelfCert(certificate)) {

return true;

}

try {

certificate.checkValidity();

} catch (CertificateExpiredException e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

“X509Certificate Expired”, e);

} catch (CertificateNotYetValidException e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

“X509Certificate not yet valid”, e);

}

X509CertSelector certSelector = new X509CertSelector();

certSelector.setCertificate(certificate);

PKIXBuilderParameters parameters;

CertPathBuilder builder;

try {

parameters = new PKIXBuilderParameters(trustStore, certSelector);

parameters.setRevocationEnabled(false);

builder = CertPathBuilder.getInstance(“PKIX”);

} catch (Exception e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

e.getMessage(), e);

}

try {

PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder

.build(parameters);

} catch (Exception e) {

e.printStackTrace();

return false;

}

return true;

}

private boolean isSelfCert(X509Certificate cert)

throws CertificateValidationCallback.CertificateValidationException {

try {

if (keyStore == null)

initKeyStore();

Enumeration aliases = keyStore.aliases();

while (aliases.hasMoreElements()) {

String alias = (String) aliases.nextElement();

if (keyStore.isKeyEntry(alias)) {

X509Certificate x509Cert = (X509Certificate) keyStore

.getCertificate(alias);

if (x509Cert != null) {

if (x509Cert.equals(cert))

return true;

}

}

}

return false;

} catch (Exception e) {

e.printStackTrace();

throw new CertificateValidationCallback.CertificateValidationException(

e.getMessage(), e);

}

}

}

private String getContainerHome() {

String _home = “”;

String fileSeparator = System.getProperty(“file.separator”);

String contHome = System.getProperty(“catalina.home”);

if (contHome != null) {

String isAS = System.getProperty(“com.sun.aas.instanceRoot”);

if (isAS != null) {

_home = contHome + fileSeparator + “..” + fileSeparator + “..”;

} else {

_home = contHome;

}

} else {

_home = System.getProperty(“jwsdp.home”);

if (_home == null) {

_home = System.getProperty(“as.home”);

}

}

return _home;

}

}

Step 7: Create the service factory (AuthServiceFactory.java), which is extremely easy since all the work was done in the Spring file:

package com.sungard.cxf.example.server;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class AuthServiceFactory {

private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

new String[] { “cxfClient.xml” });

public AuthServiceFactory() {

}

public IHello getService() {

return (IHello) context.getBean(“client”);

}

}

Step 8: Create Client.java to invoke the service.

package com.sungard.cxf.example.server;

public final class Client {

private Client() {

}

public static void main(String args[]) throws Exception {

AuthServiceFactory af = new AuthServiceFactory();

IHello client1 = af.getService();

String response1 = client1.sayHello(“Hello”);

System.out.println(“Response: ” + response1);

}

}

Step 9: Create cxfClient.xml to setup the application context for the client.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<bean id=”proxyFactory”

>

<property name=”serviceClass”

value=”com.sungard.cxf.example.server.IHello” />

<property name=”address”

value=”http://localhost:8080/samlnormalsecurity/HelloService&#8221; />

<property name=”inInterceptors”>

<list>

<ref bean=”logIn” />

</list>

</property>

<property name=”outInterceptors”>

<list>

<ref bean=”logOut” />

<ref bean=”saajOut” />

<ref bean=”wss4jOut” />

</list>

</property>

</bean>

<bean id=”client”

factory-bean=”proxyFactory” factory-method=”create” />

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean id=”saajOut”

/>

<bean id=”wss4jOut”

>

<constructor-arg>

<map>

<entry key=”action” value=”UsernameToken SAMLTokenUnsigned” />

<entry key=”user” value=”xws-security-client” />

<entry key=”passwordType” value=”PasswordText” />

<entry key=”samlPropFile” value=”saml2.properties”/>

<entry key=”enableNamespacePrefixOptimization” value=”true”/>

<entry key=”disablePrettyXML” value=”true”/>

<entry key=”sendXsiTypes” value=”true”/>

<entry key=”sendMultiRefs” value=”true”/>

<entry key=”sendXMLDeclaration” value=”true”/>

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.ClientSecurityEnvironmentHandler” />

</map>

</constructor-arg>

</bean>

</beans>

Step 11:  Create client_sign.properties file under WEB-INF\classes folder. To give public keystore file details.

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.type=jks

org.apache.ws.security.crypto.merlin.keystore.password=changeit

org.apache.ws.security.crypto.merlin.keystore.alias=xws-security-client

org.apache.ws.security.crypto.merlin.file=client-keystore.jks

Step 12:  Create saml2.properties file under WEB-INF\classes folder. To give public keystore file details.

org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.SAMLIssuerImpl

org.apache.ws.security.saml.issuer.cryptoProp.file=client_sign.properties

org.apache.ws.security.saml.issuer=www.example.com

org.apache.ws.security.saml.subjectNameId.name=xws-security-client

org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com

org.apache.ws.security.saml.authenticationMethod=password

org.apache.ws.security.saml.confirmationMethod=senderVouches

org.apache.ws.security.saml.issuer.key.name=xws-security-client

org.apache.ws.security.saml.issuer.key.password=changeit

Step 13:  Copy keystore and certificates in WEB-INF\classes folder. (Or set it in classpath)

Step 14:  Run Client.java

You will get response like as follows.

Response: You SaidHello

Note:

Client Side:

We Set User name in client cxfClient.xml file. That is public alias name.  (We can set the same through program also and we can read it xml/properties files. We can pass the same in runtime also)

<entry key=”user” value=”xws-security-client” />

We Set password in ClientSecurityEnvironmentHandler.java class (We can pass same in runtime also)

// set the password for our message.

pc.setPassword(“changeit”);

You can see the In & Outbound Messages in Client Side. As like as follows. This will go with signature.

INFO: Outbound Message

—————————

Encoding: UTF-8

Headers: {SOAPAction=[“”], Accept=[*]}

Messages:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”&gt;

<soap:Header>

<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221; soap:mustUnderstand=”1″><Assertion xmlns=”urn:oasis:names:tc:SAML:1.0:assertion” xmlns:saml=”urn:oasis:names:tc:SAML:1.0:assertion” xmlns:samlp=”urn:oasis:names:tc:SAML:1.0:protocol” AssertionID=”b58cef8ed07e7a8c1be2d099e73ba075″ IssueInstant=”2008-04-04T05:13:59.068Z” Issuer=”www.example.com” MajorVersion=”1″ MinorVersion=”1″><AuthenticationStatement AuthenticationInstant=”2008-04-04T05:13:58.896Z” AuthenticationMethod=”urn:oasis:names:tc:SAML:1.0:am:password”><Subject><NameIdentifier NameQualifier=”www.example.com”>xws-security-client</NameIdentifier><SubjectConfirmation><ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</ConfirmationMethod></SubjectConfirmation></Subject></AuthenticationStatement></Assertion><wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”UsernameToken-24451742″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”><wsse:Username xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>xws-security-client</wsse:Username><wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText&#8221; xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>changeit</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ns1:sayHello xmlns:ns1=”http://server.example.cxf.sungard.com/”><arg0>Hello</arg0></ns1:sayHello></soap:Body></soap:Envelope&gt;

————————————–

Apr 4, 2008 10:44:10 AM org.apache.cxf.interceptor.LoggingInInterceptor logging

INFO: Inbound Message

—————————-

Encoding: UTF-8

Headers: {Content-Length=[230], Date=[Fri, 04 Apr 2008 05:14:10 GMT], SOAPAction=[“”], Server=[Apache-Coyote/1.1], content-type=[text/xml;charset=UTF-8]}

Messages:

Message:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”><soap:Body><ns1:sayHelloResponse xmlns:ns1=”http://server.example.cxf.sungard.com/”><return>You SaidHello</return></ns1:sayHelloResponse></soap:Body></soap:Envelope>

————————————–

September 4, 2009 Posted by | Web Services | 5 Comments

Developing CXF WS-Security with Signature(Certificates)


Creating Server and Client Certificates

For the Signature and Encryption actions, you’ll need to create a public & private key for the entities involved. You can generate a key pair for the development environment via the following steps. Keep in mind these will not be signed by an external authority like Verisign

Keytool is inbuild tool which is comes with jdk.

Step1 :  First Create private keystore by using Java Keytool.

keytool -genkey -alias satnewprivkey -keystore satnewprivkeystore -dname “cn=satnewprivkey” -keypass satsat -storepass satsat -keyalg RSA

Step 2: Create public keystore

keytool -genkey -alias satnewpubcert -keystore satnewpubcertkeystore -dname “cn=satnewpubcert” -keypass satsat -storepass satsat -keyalg RSA

Step 3: Print created private keystore by running following command.

keytool -list -keystore satnewprivkeystore

Above command will ask password. Type “satsat” (This is keystore password which we are given while creating private keystore.)

This will give output like as follows after giving password.

Enter keystore password:

Keystore type: JKS

Keystore provider: SUN

Your keystore contains 1 entry

satnewprivkey, Mar 26, 2008, PrivateKeyEntry,

Certificate fingerprint (MD5): 46:BB:AF:49:1B:13:45:13:DB:E8:DF:96:96:D7:F3:CD

Step 4: Print created public keystore by running following command.

keytool -list -keystore satnewpubcertkeystore

Above command will ask password. Type “satsat” (This is keystore password which we are given while creating public keystore.)

This will give output like as follows after giving password.

Enter keystore password:

Keystore type: JKS

Keystore provider: SUN

Your keystore contains 1 entry

satnewpubcert, Mar 26, 2008, PrivateKeyEntry,

Certificate fingerprint (MD5): 62:50:10:D8:3A:E8:17:56:88:8E:14:C7:86:A6:4B:4F

Step 5: Export private keystore file by using following command.

keytool -export -keystore satnewprivkeystore -alias satnewprivkey -storepass satsat –rfc

This will give output like as follows.

—–BEGIN CERTIFICATE—–

MIIBpzCCARCgAwIBAgIER+o+UDANBgkqhkiG9w0BAQUFADAYMRYwFAYDVQQDEw1zYXRuZXdwcml2

a2V5MB4XDTA4MDMyNjEyMTUxMloXDTA4MDYyNDEyMTUxMlowGDEWMBQGA1UEAxMNc2F0bmV3cHJp

dmtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAhVpc7/Zw+vxfFFmuP18/4rHP5goeKgIt

jP7uAyMmd4gF8cP0vjUehWOYjVOPEGyoP3K6TXS0/RKA1uUVV5Hjk3A5fFWwjSZ/SVIpKDj1ob29

sfojEY4aEAdLI0dqe2jy+bYpg/hU0j1R3VpYlCip39VnYfZHViC8hZj4FoLqjJMCAwEAATANBgkq

hkiG9w0BAQUFAAOBgQABIFTiJp5XzPpNhS/tVx4nS7X33BzaYI90hY8ZZubuj8SCybhV2fFKC+MS

ZtM1gvPTLEdBLVvM2yixfIRA/2yHPAX0O4Y4t0/I59eUYknI9GgNAIaDbZMGE7NqqPr8ilJBAeKq

P4v+IQEmI7VaX8SSpOA0wUZqs76LfhKQ1GLL9A==

—–END CERTIFICATE—–

Step 6: Make private keystore file certified by using following command.

keytool -selfcert -alias satnewprivkey -keystore satnewprivkeystore -keypass satsat -storepass satsat

Step 7: Make public keystore file certified by using following command.

keytool -selfcert -alias satnewpubcert -keystore satnewpubcertkeystore -keypass satsat -storepass satsat

Step 8: Export public keytore into private keystore file. After running following command public keystore will be exported into private keystore file.

keytool -export -keystore satnewpubcertkeystore -alias satnewpubcert -storepass satsat -file satnewpubcert

This will give output as like as follows

Certificate stored in file <satnewpubcert>

Step 9: Print public certificate by using following command.

keytool -printcert -file satnewpubcert

This will give output as like as follows

Owner: CN=satnewpubcert

Issuer: CN=satnewpubcert

Serial number: 47ea3e8e

Valid from: Wed Mar 26 17:46:14 GMT+05:30 2008 until: Tue Jun 24 17:46:14 GMT+05:30 2008

Certificate fingerprints:

MD5:  D6:24:38:53:47:96:C6:D6:D3:D3:6B:3E:B6:74:CD:8E

SHA1: C7:61:E9:6A:6E:FB:F6:B0:8B:52:C3:0F:C2:03:49:D3:1D:41:36:58

Signature algorithm name: SHA1withRSA

Version: 3

Step 10: Make public certificate as trusted by using following command.

keytool -import -alias satnewpubcert -trustcacerts -file satnewpubcert -keystore satnewprivkeystore -storepass satsat

This command will ask question to trust certificate give yes.

You will get output as like as follows.

Owner: CN=satnewpubcert

Issuer: CN=satnewpubcert

Serial number: 47ea3e8e

Valid from: Wed Mar 26 17:46:14 GMT+05:30 2008 until: Tue Jun 24 17:46:14 GMT+05:30 2008

Certificate fingerprints:

MD5:  D6:24:38:53:47:96:C6:D6:D3:D3:6B:3E:B6:74:CD:8E

SHA1: C7:61:E9:6A:6E:FB:F6:B0:8B:52:C3:0F:C2:03:49:D3:1D:41:36:58

Signature algorithm name: SHA1withRSA

Version: 3

Trust this certificate? [no]:  yes

Certificate was added to keystore

Step 11: Print created private keystore by running following command.

keytool -list -keystore satnewprivkeystore

Above command will ask password. Type “satsat” (This is keystore password which we are given while creating private keystore.)

This will give output like as follows after giving password. Now you can private keystore has public certificate entry also.

Enter keystore password:

Keystore type: JKS

Keystore provider: SUN

Your keystore contains 2 entries

satnewprivkey, Mar 26, 2008, PrivateKeyEntry,

Certificate fingerprint (MD5): 00:86:1C:32:26:01:00:C2:FB:15:FE:EC:B5:17:03:E2

satnewpubcert, Mar 26, 2008, trustedCertEntry,

Certificate fingerprint (MD5): D6:24:38:53:47:96:C6:D6:D3:D3:6B:3E:B6:74:CD:8E

Step 12: Change store type JKS by using following command.

keytool -list -v -keystore satnewprivkeystore -storepass satsat -storetype JKS

This will give output like as follows.

Keystore type: JKS

Keystore provider: SUN

Your keystore contains 2 entries

Alias name: satnewprivkey

Creation date: Mar 26, 2008

Entry type: PrivateKeyEntry

Certificate chain length: 1

Certificate[1]:

Owner: CN=satnewprivkey

Issuer: CN=satnewprivkey

Serial number: 47ea3e86

Valid from: Wed Mar 26 17:46:06 GMT+05:30 2008 until: Tue Jun 24 17:46:06 GMT+05:30 2008

Certificate fingerprints:

MD5:  00:86:1C:32:26:01:00:C2:FB:15:FE:EC:B5:17:03:E2

SHA1: 45:33:11:1A:5E:9D:66:C9:55:7A:73:08:64:DE:63:BD:1C:C0:F9:41

Signature algorithm name: SHA1withRSA

Version: 3

*******************************************

*******************************************

Alias name: satnewpubcert

Creation date: Mar 26, 2008

Entry type: trustedCertEntry

Owner: CN=satnewpubcert

Issuer: CN=satnewpubcert

Serial number: 47ea3e8e

Valid from: Wed Mar 26 17:46:14 GMT+05:30 2008 until: Tue Jun 24 17:46:14 GMT+05:30 2008

Certificate fingerprints:

MD5:  D6:24:38:53:47:96:C6:D6:D3:D3:6B:3E:B6:74:CD:8E

SHA1: C7:61:E9:6A:6E:FB:F6:B0:8B:52:C3:0F:C2:03:49:D3:1D:41:36:58

Signature algorithm name: SHA1withRSA

Version: 3

*******************************************

*******************************************

Creating Server Application

Step 1:   Download Following Jar files.

activation.jar

aopalliance-1.0.jar

commons-collections-3.2.jar

commons-lang-2.1.jar

commons-logging-1.1.jar

geronimo-activation-2.0.1.jar

geronimo-annotation_1.0_spec-1.1.jar

geronimo-javamail_1.4_mail-1.2.jar

geronimo-servlet_2.5_spec-1.1.jar

geronimo-ws-metadata_2.0_spec-1.1.1.jar

jaxb-api.jar

jaxb-api-2.0.jar

jaxb-impl-2.0.5.jar

jaxb-xjc.jar

jaxws-api.jar

mail.jar

neethi-2.0.jar

opensaml-1.0.1.jar

saaj-api.jar

saaj-impl.jar

spring-beans-2.0.6.jar

spring-context-2.0.6.jar

spring-core-2.0.6.jar

spring-web-2.0.6.jar

stax-api-1.0.1.jar

velocity-1.5.jar

wsdl4j-1.6.1.jar

wstx-asl-3.2.1.jar

xalan-2[1].6.0.jar

xalan-2[1].7.0.jar

xml-resolver-1.2.jar

xmlsec-1.2.1.jar

cxf-bundle-2.0.4-incubator.jar

XmlSchema-1.3.2.jar

wss4j-1.5.1.jar

Step 2: Create New Java project in eclipse (CXFServerSecurity).

Step 3: Create WEB-INF folder inside project folder.

Step 4: Create classes folder inside WEB-INF folder.

Step 5: Create lib folder inside WEB-INF folder.

Step 6: Copy all the jar file into lib folder.

Step 7: Add all jar files into classpath (In Eclipse set java build path->Libraries). Add set Default output folder into CXFServerSecurity/WEB-INF/classes

Step 8: Create Remote Interface IHello.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 9: Create Implementation Class IHello_Impl.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService(endpointInterface = “com.sungard.cxf.example.server.IHello”)

public class IHello_Impl implements IHello {

public String sayHello(String value) {

return “You Said” + value;

}

}

Step 10:  Create PasswordHandler.java file to handle usernames and passwords. Here you have to give public certificate alias name for checking. Password is alias password.

if (pc.getIdentifer().equals(“satnewpubcert”)) {

pc.setPassword(“satsat”);

}

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordHandler implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

System.out.println(“Enterd PasswordHandler::handle”);

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

if (pc.getIdentifer().equals(“satnewpubcert”)) {

pc.setPassword(“satsat”);

}

System.out.println(“Leaving PasswordHandler::handle”);

}

}

Step 11: Create Interceptor class to handle soap requests ValidateUserTokenInterceptor.java.

package com.sungard.cxf.example.server;

import java.util.Vector;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

import org.apache.ws.security.WSSecurityEngineResult;

import org.apache.ws.security.WSUsernameTokenPrincipal;

import org.apache.ws.security.handler.WSHandlerConstants;

import org.apache.ws.security.handler.WSHandlerResult;

public class ValidateUserTokenInterceptor extends AbstractPhaseInterceptor {

public ValidateUserTokenInterceptor(String s) {

super(s);

}

public ValidateUserTokenInterceptor() {

super(Phase.UNMARSHAL);

}

public void handleMessage(Message message) {

System.out

.println(“Enterd ValidateUserTokenInterceptor::handleMessage”);

boolean userTokenValidated = false;

Vector result = (Vector) message

.getContextualProperty(WSHandlerConstants.RECV_RESULTS);

for (int i = 0; i < result.size(); i++) {

WSHandlerResult res = (WSHandlerResult) result.get(i);

for (int j = 0; j < res.getResults().size(); j++) {

WSSecurityEngineResult secRes = (WSSecurityEngineResult) res

.getResults().get(j);

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::Class”

+ secRes.getPrincipal().getClass());

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::ClassName”

+ secRes.getPrincipal().getClass().getName());

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::Name”

+ secRes.getPrincipal().getName());

if (secRes.getPrincipal().getClass().getName().equals(

“org.apache.ws.security.WSUsernameTokenPrincipal”)) {

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::WSUsernameTokenPrincipal”

+ secRes.getPrincipal().getName());

WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes

.getPrincipal();

if (!principal.isPasswordDigest()

|| principal.getNonce() == null

|| principal.getPassword() == null

|| principal.getCreatedTime() == null) {

throw new RuntimeException(“Invalid Security Header”);

} else {

System.out

.println(“ValidateUserTokenInterceptor::handleMessage::userTokenValidated = true”);

userTokenValidated = true;

}

}

}

}

if (!userTokenValidated) {

throw new RuntimeException(“Security processing failed”);

}

System.out

.println(“Leaving ValidateUserTokenInterceptor::handleMessage”);

}

}

Step 12: Create beans.xml file to setup the application context for the server.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<import resource=”classpath:META-INF/cxf/cxf.xml” />

<import resource=”classpath:META-INF/cxf/cxf-extension-soap.xml” />

<import resource=”classpath:META-INF/cxf/cxf-servlet.xml” />

<jaxws:endpoint id=”helloWorld”

implementor=”com.sungard.cxf.example.server.IHello_Impl”

address=”/HelloService”>

<jaxws:inInterceptors>

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean

/>

<bean

>

<property name=”properties”>

<map>

<entry key=”action”

value=”UsernameToken Signature” />

<entry key=”passwordType” value=”PasswordText” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.PasswordHandler” />

<entry key=”signaturePropFile”

value=”server_sign.properties”>

</entry>

</map>

</property>

</bean>

<bean

/>

</jaxws:inInterceptors>

</jaxws:endpoint>

</beans>

Step 13: Create server_sign.properties under WEB-INF\classes folder to mention private keystore file details.

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.type=jks

org.apache.ws.security.crypto.merlin.keystore.password=satsat

org.apache.ws.security.crypto.merlin.file=satnewprivkeystore

Step 14: Copy all keystore and certificate files under WEB-INF\classes folder.

Step 15: Create web.xml file

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<servlet>

<servlet-name>CXFServlet</servlet-name>

<display-name>CXF Servlet</display-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 16: Create ant folder inside project. And Create build.xml file inside ant folder.

<?xml version=”1.0″ encoding=”UTF-8″?>

<project basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”securityservice.war”>

<fileset dir=”${basedir}”>

<include name=”**/*.class” />

<include name=”**/*sat*” />

<include name=”**/*.properties*” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml” />

<exclude name=”**/*build*” />

</fileset>

</jar>

</target>

</project>

Step 17: Run build.xml using Ant.

Step 18: Deploy securityservice.war into Web/Application Server (Tomcat/JBoss).

Step 19: Verify application deployed successfully or by using following url.
http://localhost:8080/securityservice/HelloService?wsdl

Step 20: Browser will show wsdl file our web service.

WSDL file

Creating Client Application.

Step 1: Create New Java project in Eclipse

Step 2: Create folder Structure as like above application

Step 3: Use same jar files used for Server application.

Step 4: Set all the jars files into classpath.

Step 5: Create Remote Interface in client (IHello.java) (You can use wsdl2java for creating same)

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 6: Create ClientPasswordCallback.java for handling soap request in client side. Here you have set the password what you are given public alias.

pc.setPassword(“satsat”);

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

// set the password for our message.

pc.setPassword(“satsat”);

}

}

Step 7: Create the service factory (AuthServiceFactory.java), which is extremely easy since all the work was done in the Spring file:

package com.sungard.cxf.example.server;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class AuthServiceFactory {

private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

new String[] { “cxfClient.xml” });

public AuthServiceFactory() {

}

public IHello getService() {

return (IHello) context.getBean(“client”);

}

}

Step 8: Create Client.java to invoke the service.

package com.sungard.cxf.example.server;

public final class Client {

private Client() {

}

public static void main(String args[]) throws Exception {

AuthServiceFactory af = new AuthServiceFactory();

IHello client1 = af.getService();

String response1 = client1.sayHello(“Hello”);

System.out.println(“Response: ” + response1);

}

}

Step 9: Create cxfClient.xml to setup the application context for the client.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<bean id=”proxyFactory”

>

<property name=”serviceClass”

value=”com.sungard.cxf.example.server.IHello” />

<property name=”address”

value=”http://localhost:8080/securityservice/HelloService&#8221; />

<property name=”inInterceptors”>

<list>

<ref bean=”logIn” />

</list>

</property>

<property name=”outInterceptors”>

<list>

<ref bean=”logOut” />

<ref bean=”saajOut” />

<ref bean=”wss4jOut” />

</list>

</property>

</bean>

<bean id=”client”

factory-bean=”proxyFactory” factory-method=”create” />

<bean id=”logIn”

/>

<bean id=”logOut”

/>

<bean id=”saajOut”

/>

<bean id=”wss4jOut”

>

<constructor-arg>

<map>

<entry key=”action” value=”UsernameToken Signature” />

<entry key=”user” value=”satnewpubcert” />

<entry key=”passwordType” value=”PasswordDigest” />

<entry key=”signaturePropFile”

value=”client_sign.properties” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.ClientPasswordCallback” />

</map>

</constructor-arg>

</bean>

</beans>

Step 11:  Create client_sign.properties file under WEB-INF\classes folder. To give public keystore file details.

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.type=jks

org.apache.ws.security.crypto.merlin.keystore.password=satsat

org.apache.ws.security.crypto.merlin.keystore.alias=satnewpubcert

org.apache.ws.security.crypto.merlin.file=satnewpubcertkeystore

Step 12:  Copy keystore and certificates in WEB-INF\classes folder. (Or set it in classpath)

Step 13:  Run Client.java

You will get response like as follows.

Response: You SaidHello

Note:

Client Side:

We Set User name in client cxfClient.xml file. That is public alias name.  (We can set the same through program also and we can read it xml/properties files. We can pass the same in runtime also)

<entry key=“user” value=“satnewpubcert”/>

We Set password in ClientPasswordCallback.java class (We can pass same in runtime also)

// set the password for our message.

pc.setPassword(“satsat”);

You can see the In & Outbound Messages in Client Side. As like as follows. This will go with signature.

INFO: Outbound Message

—————————

Encoding: UTF-8

Headers: {SOAPAction=[“”], Accept=[*]}

Messages:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”&gt;

<soap:Header>

<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221; soap:mustUnderstand=”1″><ds:Signature xmlns:ds=”http://www.w3.org/2000/09/xmldsig#&#8221; Id=”Signature-7859095″>

<ds:SignedInfo xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<ds:CanonicalizationMethod Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#&#8221; xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”/&gt;

<ds:SignatureMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#rsa-sha1&#8243; xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”/&gt;

<ds:Reference URI=”#id-26564976″ xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<ds:Transforms xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<ds:Transform Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#&#8221; xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”/&gt;

</ds:Transforms>

<ds:DigestMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#sha1&#8243; xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”/&gt;

<ds:DigestValue xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>rU2PYdKHS7wdWvzrSl4fiH90AQc=</ds:DigestValue&gt;

</ds:Reference>

</ds:SignedInfo>

<ds:SignatureValue xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

UU0q/hQFWYrOMt+iPHiuuc0ffb6iqbJu1A115gGO4DHlt850pRQVMJGxn1f+XQaxjLjJRqzYa1lC

HQdZyavkLwpMWK1M/VLCn/2M9sS/c64wEIrLhE8vq9jO31O1Ms17KamgdvV9ThpR3sD4BUg3Q3Q1

vyi5+YVroHBBgqtVmFg=

</ds:SignatureValue>

<ds:KeyInfo xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<wsse:SecurityTokenReference xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”STRId-29118152″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”><ds:X509Data xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<ds:X509IssuerSerial xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;

<ds:X509IssuerName xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>CN=satnewpubcert</ds:X509IssuerName&gt;

<ds:X509SerialNumber xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>1206533774</ds:X509SerialNumber&gt;

</ds:X509IssuerSerial>

</ds:X509Data></wsse:SecurityTokenReference>

</ds:KeyInfo>

</ds:Signature><wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”UsernameToken-7189308″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”><wsse:Username xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>satnewpubcert</wsse:Username><wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest&#8221; xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>MSsmgsLBGcV+gKRTWBRsKKTrpQw=</wsse:Password><wsse:Nonce xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>q/4pOweIQLxL+VWqik5Pag==</wsse:Nonce><wsu:Created xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>2008-03-26T13:26:12.813Z</wsu:Created></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”id-26564976″><ns1:sayHello xmlns:ns1=”http://server.example.cxf.sungard.com/”><arg0>Hello</arg0></ns1:sayHello></soap:Body></soap:Envelope&gt;

————————————–

Mar 26, 2008 6:56:14 PM org.apache.cxf.interceptor.LoggingInInterceptor logging

INFO: Inbound Message

—————————-

Encoding: UTF-8

Headers: {content-type=[text/xml;charset=UTF-8], Date=[Wed, 26 Mar 2008 13:26:14 GMT], Content-Length=[230], SOAPAction=[“”], Server=[Apache-Coyote/1.1]}

Messages:

Message:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”><soap:Body><ns1:sayHelloResponse xmlns:ns1=”http://server.example.cxf.sungard.com/”><return>You SaidHello</return></ns1:sayHelloResponse></soap:Body></soap:Envelope>

————————————–

Server Side:

User Name and password are got validated in PasswordHandler.java file. These values we can read it from xml/properties or from configuration files. Identifier value is public alias name and password is public alias password.

if (pc.getIdentifer().equals(“satnewpubcert”)) {

pc.setPassword(“satsat”);

}

September 4, 2009 Posted by | Web Services | 5 Comments

Developing CXF Web services with WS-Security


Creating Server Application

Step 1:   Download Following Jar files.

activation.jar

aopalliance-1.0.jar

commons-collections-3.2.jar

commons-lang-2.1.jar

commons-logging-1.1.jar

geronimo-activation-2.0.1.jar

geronimo-annotation_1.0_spec-1.1.jar

geronimo-javamail_1.4_mail-1.2.jar

geronimo-servlet_2.5_spec-1.1.jar

geronimo-ws-metadata_2.0_spec-1.1.1.jar

jaxb-api.jar

jaxb-api-2.0.jar

jaxb-impl-2.0.5.jar

jaxb-xjc.jar

jaxws-api.jar

mail.jar

neethi-2.0.jar

opensaml-1.0.1.jar

saaj-api.jar

saaj-impl.jar

spring-beans-2.0.6.jar

spring-context-2.0.6.jar

spring-core-2.0.6.jar

spring-web-2.0.6.jar

stax-api-1.0.1.jar

velocity-1.5.jar

wsdl4j-1.6.1.jar

wstx-asl-3.2.1.jar

xalan-2[1].6.0.jar

xalan-2[1].7.0.jar

xml-resolver-1.2.jar

xmlsec-1.2.1.jar

cxf-bundle-2.0.4-incubator.jar

XmlSchema-1.3.2.jar

wss4j-1.5.1.jar

Step 2: Create New Java project in eclipse (CXFServer).

Step 3: Create WEB-INF folder inside project folder.

Step 4: Create classes folder inside WEB-INF folder.

Step 5: Create lib folder inside WEB-INF folder.

Step 6: Copy all the jar file into lib folder.

Step 7: Add all jar files into classpath (In Eclipse set java build path->Libraries). Add set Default output folder into CXFServer/WEB-INF/classes

Step 8: Create Remote Interface IHello.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 9: Create Implementation Class IHello_Impl.java

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService(endpointInterface = “com.sungard.cxf.example.server.IHello”)

public class IHello_Impl implements IHello {

public String sayHello(String value) {

return “You Said” + value;

}

}

Step 10:  Create PasswordHandler.java file to handle usernames and passwords.

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordHandler implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

System.out.println(“Enterd PasswordHandler::handle”);

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

if (pc.getIdentifer().equals(“arsenal”)) {

pc.setPassword(“gunners”);

}

System.out.println(“Leaving PasswordHandler::handle”);

}

}

Step 11: Create Interceptor class to handle soap requests ValidateUserTokenInterceptor.java.

package com.sungard.cxf.example.server;

import java.util.Vector;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

import org.apache.ws.security.WSSecurityEngineResult;

import org.apache.ws.security.WSUsernameTokenPrincipal;

import org.apache.ws.security.handler.WSHandlerConstants;

import org.apache.ws.security.handler.WSHandlerResult;

public class ValidateUserTokenInterceptor extends AbstractPhaseInterceptor {

public ValidateUserTokenInterceptor(String s) {

super(s);

}

public ValidateUserTokenInterceptor(){

super(Phase.UNMARSHAL);

}

public void handleMessage(Message message) {

System.out.println(“Enterd ValidateUserTokenInterceptor::handleMessage”);

boolean userTokenValidated = false;

Vector result = (Vector) message

.getContextualProperty(WSHandlerConstants.RECV_RESULTS);

for (int i = 0; i < result.size(); i++) {

WSHandlerResult res = (WSHandlerResult) result.get(i);

for (int j = 0; j < res.getResults().size(); j++) {

WSSecurityEngineResult secRes = (WSSecurityEngineResult) res

.getResults().get(j);

WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.getPrincipal();

if (!principal.isPasswordDigest()

|| principal.getNonce() == null

|| principal.getPassword() == null

|| principal.getCreatedTime() == null) {

throw new RuntimeException(“Invalid Security Header”);

} else {

userTokenValidated = true;

}

}

}

if (!userTokenValidated) {

throw new RuntimeException(“Security processing failed”);

}

System.out.println(“Leaving ValidateUserTokenInterceptor::handleMessage”);

}

}

Step 12: Create beans.xml file to setup the application context for the server.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<import resource=”classpath:META-INF/cxf/cxf.xml” />

<import resource=”classpath:META-INF/cxf/cxf-extension-soap.xml” />

<import resource=”classpath:META-INF/cxf/cxf-servlet.xml” />

<jaxws:endpoint id=”helloWorld”

implementor=”com.sungard.cxf.example.server.IHello_Impl”

address=”/HelloService”>

<jaxws:inInterceptors>

<bean

/>

<bean

>

<property name=”properties”>

<map>

<entry key=”action” value=”UsernameToken” />

<entry key=”passwordType” value=”PasswordText” />

<entry key=”passwordCallbackClass”

value=”com.sungard.cxf.example.server.PasswordHandler” />

</map>

</property>

</bean>

<bean

/>

</jaxws:inInterceptors>

</jaxws:endpoint>

</beans>

Step 13: Create web.xml file

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<servlet>

<servlet-name>CXFServlet</servlet-name>

<display-name>CXF Servlet</display-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 14: Create ant folder inside project. And Create build.xml file inside ant folder.

<?xml version=”1.0″ encoding=”UTF-8″?>

<project basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”helloservice.war”>

<fileset dir=”${basedir}”>

<include name=”**/*.class” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml” />

<exclude name=”**/*build*” />

</fileset>

</jar>

</target>

</project>

Step 15: Run build.xml using Ant.

Step 16: Deploy helloservice.war into Web/Application Server (Tomcat/JBoss).

Step 17: Verify application deployed successfully or by using following url.
http://localhost:8080/helloservice/HelloService?wsdl

Step 18: Browser will show wsdl file our web service.

WSDL file

Creating Client Application.

Step 1: Create New Java project in Eclipse

Step 2: Create folder Structure as like above application

Step 3: Use same jar files used for Server application.

Step 4: Set all the jars files into classpath.

Step 5: Create Remote Interface in client (IHello.java) (You can use wsdl2java for creating same)

package com.sungard.cxf.example.server;

import javax.jws.WebService;

@WebService

public interface IHello {

public String sayHello(String value);

}

Step 6: Create ClientPasswordCallback.java for handling soap request in client side.

package com.sungard.cxf.example.server;

import java.io.IOException;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler {

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

// set the password for our message.

pc.setPassword(“gunners”);

}

}

Step 7: Create the service factory (AuthServiceFactory.java), which is extremely easy since all the work was done in the Spring file:

package com.sungard.cxf.example.server;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class AuthServiceFactory {

private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

new String[] { “cxfClient.xml” });

public AuthServiceFactory() {

}

public IHello getService() {

return (IHello) context.getBean(“client”);

}

}

Step 8: Create Client.java to invoke the service.

package com.sungard.cxf.example.server;

public final class Client {

private Client() {

}

public static void main(String args[]) throws Exception {

AuthServiceFactory af = new AuthServiceFactory();

IHello client1 = af.getService();

String response1 = client1.sayHello(“Hello”);

System.out.println(“Response: ” + response1);

}

}

Step 9: Create cxfClient.xml to setup the application context for the client.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<bean id=”proxyFactory”>

<property name=”serviceClass” value=”com.sungard.cxf.example.server.IHello”/>

<property name=”address” value=”http://localhost:8080/helloservice/HelloService”/&gt;

<property name=”inInterceptors”>

<list>

<ref bean=”logIn” />

</list>

</property>

<property name=”outInterceptors”>

<list>

<ref bean=”logOut” />

<ref bean=”saajOut” />

<ref bean=”wss4jOut” />

</list>

</property>

</bean>

<bean id=”client” factory-bean=”proxyFactory” factory-method=”create” />

<bean id=”logIn” />

<bean id=”logOut” />

<bean id=”saajOut” />

<bean id=”wss4jOut”>

<constructor-arg>

<map>

<entry key=”action” value=”UsernameToken” />

<entry key=”user” value=”arsenal” />

<entry key=”passwordType” value=”PasswordDigest” />

<entry key=”passwordCallbackClass” value=”com.sungard.cxf.example.server.ClientPasswordCallback” />

</map>

</constructor-arg>

</bean>

</beans>

Step 10:  Run Client.java

You will get response like as follows.

Response: You SaidHello

Note:

Client Side:

We Set User name in client cxfClient.xml file. (We can set the same through program also and we can read it xml/properties files. We can pass the same in runtime also)

<entry key=“user” value=“arsenal” />

We Set password in ClientPasswordCallback.java class (We can pass same in runtime also)

// set the password for our message.

pc.setPassword(“gunners”);

You can see the In & Outbound Messages in Client Side. As like as follows.

INFO: Outbound Message

—————————

Encoding: UTF-8

Headers: {SOAPAction=[“”], Accept=[*]}

Messages:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”&gt;

<soap:Header>

<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221; soap:mustUnderstand=”1″><wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221; wsu:Id=”UsernameToken-9702276″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”><wsse:Username xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>arsenal</wsse:Username><wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest&#8221; xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>3bQTW92CrAxUt9rgqvqyY4pfJi8=</wsse:Password><wsse:Nonce xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>hxV58wDgiNTf4tcypfiN6Q==</wsse:Nonce><wsu:Created xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>2008-03-25T11:04:15.111Z</wsu:Created></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ns1:sayHello xmlns:ns1=”http://server.example.cxf.sungard.com/”><arg0>Hello</arg0></ns1:sayHello></soap:Body></soap:Envelope&gt;

————————————–

Mar 25, 2008 4:34:15 PM org.apache.cxf.interceptor.LoggingInInterceptor logging

INFO: Inbound Message

—————————-

Encoding: UTF-8

Headers: {content-type=[text/xml;charset=UTF-8], Date=[Tue, 25 Mar 2008 11:04:15 GMT], Content-Length=[230], SOAPAction=[“”], Server=[Apache-Coyote/1.1]}

Messages:

Message:

Payload: <soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”><soap:Body><ns1:sayHelloResponse xmlns:ns1=”http://server.example.cxf.sungard.com/”><return>You SaidHello</return></ns1:sayHelloResponse></soap:Body></soap:Envelope>

————————————–

Server Side:

User Name and password are got validated in PasswordHandler.java file. These values we can read it from xml/properties or from configuration files.

if (pc.getIdentifer().equals(“arsenal”)) {

pc.setPassword(“gunners”);

}

September 4, 2009 Posted by | Web Services | 6 Comments

RESTful web services using the Jersey framework


Brief Description

This sample application provides the below services

  • Displays the list of employees in the organization
  • Append new employee to the system
  • Get the specific employee information based on the employee id

Restful Web Service:

REpresentational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URLs. Web service clients that want to use these resources access a particular representation by transferring application content using a small globally defined set of remote methods that describe the action to be performed on the resource. REST is an analytical description of the existing web architecture, and thus the interplay between the style and the underlying HTTP protocol appears seamless.

Jersey Framework:

Jersey is the open source (under the CDDL license) JAX-RS (JSR 311) Reference Implementation for building RESTful Web services. But, it is also more than the Reference Implementation. Jersey provides additional APIs and extension points (SPIs) so that developers may extend Jersey to suite their needs.

Jersey is currently available as an early access implementation. Jersey cannot go to version 1.0 until JAX-RS reaches the final release and is an approved JSR. Until that point Jersey will track the JSR 311 API and will regularly update according to 311 Expert Group agreed snapshots of the API.

Latest Jersey snapshot can be downloaded from https://jersey.dev.java.net/files/documents/7056/73619/jersey-0.4-ea.zip

Follow the below Steps to create a sample RESTful application

Step1: Create a web project with the below directory structure

Folder Structure

Step2: Create a java file to make it as a RESTful web service

In this sample application we have taken the EmployeeService.java as the web service.
Below is the code for the EmployeeService.java

package com.peter.sample;

import javax.ws.rs.ConsumeMime;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.UriParam;
import javax.ws.rs.UriTemplate;
import javax.ws.rs.WebApplicationException;
import com.sun.ws.rest.api.representation.FormURLEncodedProperties;

/**
*
* @author Peter Arockiaraj Employee service
*
*/

@UriTemplate(“/employee”)
public class EmployeeService {

@HttpMethod(“GET”)
@ProduceMime(“text/html”)
public String listEmployees() {
String result = “Satyam Employee list”;

result += ”
“;
for (Employee employee : Employee.EMPLOYEE_LIST) {
result += ”
“;
result += ”

“;
result += ”

“;
}
result += ”

” + employee.getId() + “ ” + employee.getName() + “ ” + employee.getDesignation() + “

“;
return result;
}

@HttpMethod(“GET”)
@UriTemplate(“/{id}”)
@ProduceMime(“text/json”)
public String listEmployee(@UriParam(“id”)
String idString) {
int id = 0;
try {
id = Integer.parseInt(idString);
} catch (NumberFormatException e) {
throw new WebApplicationException(405);
}
try {
return Employee.getEmployee(id).toJson();
} catch (IndexOutOfBoundsException e) {
throw new WebApplicationException(404);
}
}

@HttpMethod(“GET”)
@UriTemplate(“/new”)
@ProduceMime(“text/html”)
public String formForEmployee() {
String result = “Create New Employee”;
result += “”;
result += “Name :
“;
result += “Designation :
“;
result += “”;
return result;
}

@UriTemplate(“/add”)
@HttpMethod(“POST”)
@ProduceMime(“text/plain”)
@ConsumeMime(“text/html”)
public String addEmployee(FormURLEncodedProperties formData) {
String name = formData.get(“name”);
String designation = formData.get(“designation”);
if ((name == null) || (designation == null)) {
throw new WebApplicationException(405);
} else {
Employee.addEmployee(name, designation);
}
return “Added OK”;
}

}

EmployeeService uses Employee.java
package com.peter.sample;

import java.util.ArrayList;
import java.util.List;

/**
*
* @author Peter Arockiaraj
* A model class for this very simple Jersey REST example.
*
*/
public class Employee {

/**
* In memory list. In a real world example this might
* be backed by a database
*/
public static List EMPLOYEE_LIST = new ArrayList();

/**
* Method to get the Employee Details based on the Employee ID
* @param id
* @return Employee
*/
public static Employee getEmployee(int id) {
return EMPLOYEE_LIST.get(id);
}

/**
* Method to add the new employee details to the Employee List
* @param Name
* @param Designation
*/
public static void addEmployee(String Name, String Designation) {
EMPLOYEE_LIST.add(new Employee(EMPLOYEE_LIST.size(), Name, Designation));
}

/**
* Create some data
*/
static {
EMPLOYEE_LIST.add(new Employee(71503,”Hari”,”Business Analyst”));
EMPLOYEE_LIST.add(new Employee(14352,”Mathew”,”Business Analyst”));
EMPLOYEE_LIST.add(new Employee(17689,”Vamsi”,”Business Analyst”));
EMPLOYEE_LIST.add(new Employee(36157,”Naveen”,”Business Analyst”));
}

private int id;
private String name;
private String designation;

/**
* Creates an Employee Instance
* @param id
* @param name
* @param designation
*/
public Employee(int id, String name, String designation) {
super();
this.id = id;
this.name = name;
this.designation = designation;
}

/**
* @return
*/
public String toJson() {
String result = “{ ‘id’ : ” + this.id + ” , “;
result += ” ‘Name’ : ” + this.name + ” , “;
result += “‘Designation’ : ” + this.designation + ” }”;
return result;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDesignation() {
return designation;
}

public void setDesignation(String designation) {
this.designation = designation;
}

}

Step4: Create a webresouce class
package com.peter.sample;
import com.sun.ws.rest.api.core.DefaultResourceConfig;

/**
*
* @author Peter Arockiaraj
* WebResource definition for the Employee Service example.
*/
public class WebResources extends DefaultResourceConfig {

public WebResources() {
getResourceClasses().add(EmployeeService.class);
// getResourceClasses().add(OtherService.class);
// can add any number of Web services here.
}
}

Step3: Make sure that the below jars files in the classpath
• jeesey.jar
• jsr311-api.jar
• jettison-1.0-RC1.jar

Step4: create the web.xml with the following code
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app version=”2.5″ xmlns=”http://java.sun.com/xml/ns/javaee&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd”&gt;

<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.ws.rest.impl.container.servlet.ServletAdaptor</servlet-class>
<init-param>
<param-name>webresourceclass</param-name>
<param-value>com.satyam.adms.WebResources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>

<session-config>
<session-timeout>
30
</session-timeout>
</session-config>

</web-app>

Step5: Build the war file and deploy in the web server.
Step6: Below are the URLs to access the application
http://localhost:8080/EmployeeProject/resources/employee : To view the list of employees
http://localhost:8080/EmployeeProject/resources/employee/new : To append the new employee
http://localhost:8080/EmployeeProject/resources/employee/1 : To get the employee id =1 info

September 3, 2009 Posted by | Web Services | Leave a comment

Developing Web Services By Using Spring and CXF


Step 1:  Download Following Jar files.

Open up your favorite IDE and create a new project. The first thing we need to do is add the necessary CXF dependencies to the project. You can find these dependencies in the CXF distribution in the lib directory.

commons-logging-1.1.jar

geronimo-activation_1.1_spec-1.0-M1.jar (or Sun’s Activation jar)

geronimo-annotation_1.0_spec-1.1.jar (JSR 250)

geronimo-javamail_1.4_spec-1.0-M1.jar (or Sun’s JavaMail jar)

geronimo-servlet_2.5_spec-1.1-M1.jar (or Sun’s Servlet jar)

geronimo-ws-metadata_2.0_spec-1.1.1.jar (JSR 181)

jaxb-api-2.0.jar

jaxb-impl-2.0.5.jar

jaxws-api-2.0.jar

neethi-2.0.jar

saaj-api-1.3.jar

saaj-impl-1.3.jar

stax-api-1.0.1.jar

wsdl4j-1.6.1.jar

wstx-asl-3.2.1.jar

XmlSchema-1.2.jar

xml-resolver-1.2.jar

The Spring jars:

aopalliance-1.0.jar

spring-core-2.0.4.jar

spring-beans-2.0.4.jar

spring-context-2.0.4.jar

spring-web-2.0.4.jar

And the CXF jar:

cxf-2.0-incubator.jar

Step 2:  Create Following Folder Structure

Folder Structure

Step 3:  Create Following classes

  1. Address
  2. AddressType
  3. IAddressService
  4. AddressService

Address.java

package com.sungard.adms.address.ws;

public class Address {

private String name;

private String doorno;

private String road;

private String buildingName;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getRoad() {

return road;

}

public void setRoad(String road) {

this.road = road;

}

public String getBuildingName() {

return buildingName;

}

public void setBuildingName(String buildingName) {

this.buildingName = buildingName;

}

public String getDoorno() {

return doorno;

}

public void setDoorno(String doorno) {

this.doorno = doorno;

}

}

AddressType.java

package com.sungard.adms.address.ws;

public enum AddressType {

HEBBALOFFICE,

ELECTRONIC_CITY,

ESTEEM_TOWERS,

LANGFORD_ROAD

}

IAddressService.java

package com.sungard.adms.address.ws;

/**

* CXF sample interface.

*

*/

@WebService

public interface IAddressService {

public Address getAddress(AddressType adsType);

}

AddressService.java

package com.sungard.adms.address.ws;

import java.util.HashMap;

/**

* This is the Implementation Class for IAddressService. Our Business Logic will

* be present here.

*

* @author PA71448

*

*/

@WebService(endpointInterface = “com.sungard.adms.address.ws.IAddressService”)

public class AddressService implements IAddressService {

private HashMap<AddressType, Address> addressList = new HashMap<AddressType, Address>();

/**

* Default Constructor for this service.

*/

public AddressService() {

Address bhr = new Address();

bhr.setBuildingName(“Kirloskar Business Park”);

bhr.setName(“Sungard”);

bhr.setRoad(“Hyderabad Road”);

bhr.setDoorno(“338”);

addressList.put(AddressType.HEBBALOFFICE, bhr);

Address bsd = new Address();

bsd.setBuildingName(“Electronic City”);

bsd.setName(“Sungard”);

bsd.setRoad(“Hosur Road”);

bsd.setDoorno(“143”);

addressList.put(AddressType.ELECTRONIC_CITY, bsd);

Address bet = new Address();

bet.setBuildingName(“Esteem Towers”);

bet.setName(“Sungard”);

bet.setRoad(“Railway Parallel Road”);

bet.setDoorno(“6”);

addressList.put(AddressType.ESTEEM_TOWERS, bet);

Address bla = new Address();

bla.setBuildingName(“LangFord Avenue”);

bla.setName(“Sungard”);

bla.setRoad(“LangFord Road”);

bla.setDoorno(“653”);

addressList.put(AddressType.LANGFORD_ROAD, bla);

}

@Override

public Address getAddress(AddressType adsType) {

return addressList.get(adsType);

}

}

Step 4:  Create beans.xml file in WEB-INF folder

beans.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xmlns:jaxws=”http://cxf.apache.org/jaxws&#8221;

xsi:schemaLocation=”

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd”&gt;

<import resource=”classpath:META-INF/cxf/cxf.xml” />

<import resource=”classpath:META-INF/cxf/cxf-extension-soap.xml” />

<import resource=”classpath:META-INF/cxf/cxf-servlet.xml” />

<jaxws:endpoint

id=”helloWorld”

implementor=”com.sungard.adms.address.ws.AddressService”

address=”/AddressService” />

</beans>

Step 5:  Create web.xml file in WEB-INF folder

web.xml

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<servlet>

<servlet-name>CXFServlet</servlet-name>

<display-name>CXF Servlet</display-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 6:  Copy All class files with folder structure in WEB-INF classes Folder

Step 7:

Create ant directory in project root folder

Create build.xml file

build.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<project name=”ws” basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”cxfaddressservice.war”  >

<fileset dir=”${basedir}”>

<include name=”**/*.class”/>

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar”/>

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml”/>

<exclude name=”**/*build*”/>

</fileset>

</jar>

</target>

</project>

Step 8: Run ant build

Step 9: Deploy the war file in application server/web server

Step 10: Check application deployed properly or not by using following url. This url will show the wsdl file for this web service application.

http://localhost:8080/cxfaddressservice/AddressService?wsdl

WSDL file

Developing Web Services Client by Using JWSDP

Step 1: Download Following Jar files.

jaxrpc-impl.jar

jaxrpc-spi.jar

activation.jar

mail.jar

dom.jar

sax.jar

xalan.jar

xercesImpl.jar

saaj-impl.jar

FastInfoset.jar

saajImpl.jar

jsr173_api.jar

Step 2: Create a j2EE project AddressWSClient

Step 3: Create folders src, classes, lib ,wsdl under project root folder.

Step 4: Create file config.xml inside the project root as

config.xml

<?xml version=”1.0″ encoding=

“UTF-8″?>

<configuration xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/config”&gt;

<wsdl location=

“wsdl\AddressService.wsdl”

packageName=

“com.sungard.adms.address.client.gen” />

</configuration>

Step 5: Copy the .wsdl from http://localhost:8080/cxfaddressservice/AddressService?wsdl into AddressWSClient/wsdl

Step 6: Generate client side stubs by executing…

wscompile -verbose -gen -d classes -s src -keep config.xml

Step 7: Copy all jar file into lib (Add them to build path)

Step 8: Create class AddressClient.java as

AddressClient.java

package com.sungard.adms.address.client.gen;

import java.net.MalformedURLException;

import java.net.URL;

import java.rmi.RemoteException;

import javax.xml.namespace.QName;

import javax.xml.rpc.Service;

import javax.xml.rpc.ServiceException;

import javax.xml.rpc.ServiceFactory;

/**

* @author Peter Arockiaraj

*

* TODO To change the template for this generated type comment go to

* Window – Preferences – Java – Code Style – Code Templates

*/

public class AddressClient {

public static void main(String[] args) throws ServiceException,RemoteException,MalformedURLException{

try{

System.setProperty(“javax.xml.soap.MessageFactory”, “com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl”);

//System.setProperty(“javax.xml.soap.SOAPFactory”,”com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl”);

//System.setProperty(“javax.xml.rpc.ServiceFactory”,”com.sun.xml.rpc.client.ServiceFactoryImpl”);

//System.setProperty(“javax.xml.soap.SOAPConnectionFactory”,”javax.xml.soap.SOAPConnectionFactory”);

//System.setProperty(“javax.xml.parsers.DocumentBuilderFactory”,”com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl”);

AddressServiceService_Impl impl =

new AddressServiceService_Impl();

IAddressService ws = impl.getAddressServicePort();

Address result = ws.getAddress(AddressType.HEBBALOFFICE);

System.out.println(“Direct Call Output\n”);

System.out.println(“Company Name:\t”+result.getName());

System.out.println(“Door No:\t”+result.getDoorno());

System.out.println(“Building Name:\t”+result.getBuildingName());

System.out.println(“Road Name:\t”+result.getRoad());

System.out.println(“Dynamic WS call”);

URL url = new URL(“http://localhost:8080/cxfaddressservice/AddressService?wsdl&#8221;);

QName qname = new QName(“http://ws.address.adms.sungard.com/&#8221;,”AddressServiceService”);

ServiceFactory factory = ServiceFactory.newInstance();

Service service = factory.createService(url,qname);

IAddressService hello = (IAddressService) service.getPort(IAddressService.class);

Address dynaddress=ws.getAddress(AddressType.ESTEEM_TOWERS);

System.out.println(“\nDynamic Call Output\n”);

System.out.println(“Company Name:\t”+dynaddress.getName());

System.out.println(“Door No:\t”+dynaddress.getDoorno());

System.out.println(“Building Name:\t”+dynaddress.getBuildingName());

System.out.println(“Road Name:\t”+dynaddress.getRoad());

}catch(Exception se){

System.out.println(“ServiceException ” + se.getMessage());

}

}

}

Step 9: Run AddressClient.java as a normal java application.

Client Output

Developing Simple Web Services Client by Using Flex

Step 1: Create New Flex Project in Flex Builder.

Step 2:  Open Main Application MXML.

Step 3: Copy & Paste Following Code.

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; xmlns=”*” layout=”absolute”

creationComplete=”userRequest.returnRecords()” height=”249″ width=”538″>

<mx:Form x=”22″ y=”10″ width=”493″>

<mx:HBox>

<mx:Label text=”Address Code”/>

<mx:TextInputfont-size:10.0pt;font-family:”Courier New”;mso-fareast-font-family:”Times New Roman”; color:#990000″>addresscode”/>

</mx:HBox>

<mx:HBox>

<mx:DataGridfont-size:10.0pt;font-family:”Courier New”; mso-fareast-font-family:”Times New Roman”;color:#990000″>dgUserRequest” x=”22″ y=”128″>

<mx:columns>

<mx:DataGridColumn headerText=”Building Name” dataField=”buildingName”/>

<mx:DataGridColumn headerText=”Door Number” dataField=”doorno”/>

<mx:DataGridColumn headerText=”Name” dataField=”name”/>

<mx:DataGridColumn headerText=”Road Name” dataField=”road”/>

</mx:columns>

</mx:DataGrid>

</mx:HBox>

<mx:Button label=”Submit” click=”clickHandler()”/>

</mx:Form>

<mx:WebService

id=”userRequest”

wsdl=”http://localhost:8080/cxfaddressservice/AddressService?wsdl”&gt;

<mx:operation name=”getAddress” resultFormat=”object” result=”insertCFCHandler(event)”

fault=”mx.controls.Alert.show(event.fault.faultString)”/>

</mx:WebService>

<mx:Script>

<![CDATA[

import mx.rpc.events.ResultEvent;

private function insertCFCHandler(e:ResultEvent):void

{

dgUserRequest.dataProvider = e.result;

}

private function clickHandler():void

{

userRequest.getAddress(addresscode.text);

}

]]>

</mx:Script>

</mx:Application>

Step 4:  Run Application.

FlexOutput

September 2, 2009 Posted by | Web Services | Leave a comment

Developing Web Services by Using Spring and XFire


Step 1:  Download Following Jar files.

required jars

Step 2:  Create Following Folder Structure

Folder Structure

Step 3:  Create Following classes

  1. Address
  2. AddressType
  3. IAddressService
  4. AddressService

Address.java

package com.sungard.adms.address.ws;

public class Address {

private String name;

private String doorno;

private String road;

private String buildingName;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getRoad() {

return road;

}

public void setRoad(String road) {

this.road = road;

}

public String getBuildingName() {

return buildingName;

}

public void setBuildingName(String buildingName) {

this.buildingName = buildingName;

}

public String getDoorno() {

return doorno;

}

public void setDoorno(String doorno) {

this.doorno = doorno;

}

}

AddressType.java

package com.sungard.adms.address.ws;

public enum AddressType {

HEBBALOFFICE,

ELECTRONIC_CITY,

ESTEEM_TOWERS,

LANGFORD_ROAD

}

IAddressService.java

package com.sungard.adms.address.ws;

/** XFire sample interface.

*

*/

public interface IAddressService {

public Address getAddress(AddressType adsType);

}

AddressService.java

package com.sungard.adms.address.ws;

import java.util.HashMap;

/**

* This is the Implementation Class for IAddressService. Our Business Logic will

* be present here.

*

* @author PA71448

*

*/

public class AddressService implements IAddressService {

private HashMap<AddressType, Address> addressList = new HashMap<AddressType, Address>();

/**

* Default Constructor for this service.

*/

public AddressService() {

Address bhr = new Address();

bhr.setBuildingName(“Kirloskar Business Park”);

bhr.setName(“Sungard”);

bhr.setRoad(“Hyderabad Road”);

bhr.setDoorno(“338”);

addressList.put(AddressType.HEBBALOFFICE, bhr);

Address bsd = new Address();

bsd.setBuildingName(“Electronic City”);

bsd.setName(“Sungard”);

bsd.setRoad(“Hosur Road”);

bsd.setDoorno(“143”);

addressList.put(AddressType.ELECTRONIC_CITY, bsd);

Address bet = new Address();

bet.setBuildingName(“Esteem Towers”);

bet.setName(“Sungard”);

bet.setRoad(“Railway Parallel Road”);

bet.setDoorno(“6”);

addressList.put(AddressType.ESTEEM_TOWERS, bet);

Address bla = new Address();

bla.setBuildingName(“LangFord Avenue”);

bla.setName(“Sungard”);

bla.setRoad(“LangFord Road”);

bla.setDoorno(“653”);

addressList.put(AddressType.LANGFORD_ROAD, bla);

}

@Override

public Address getAddress(AddressType adsType) {

return addressList.get(adsType);

}

}

Step 4:  Create applicationContext.xml file in WEB-INF folder

applicationContext.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”&gt;

<beans>

<bean/>

</beans>

Step 5: Create xfire-servlet.xml file in WEB-INF folder

xfire-servlet.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”&gt;

<beans>

<bean class=”org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>

<property>

<map>

<entry key=”/AddressService”>

<ref bean=”getAddress”/>

</entry>

</map>

</property>

</bean>

<!– Declare a parent bean with all properties common to both services –>

<bean class=”org.codehaus.xfire.spring.remoting.XFireExporter”>

<property>

<ref bean=”xfire.serviceFactory”/>

</property>

<property>

<ref bean=”xfire”/>

</property>

<property>

<ref bean=”addressService”/>

</property>

<property>

<value>com.sungard.adms.address.ws.IAddressService</value>

</property>

</bean>

</beans>

Step 6:  Create web.xml file in WEB-INF folder

web.xml

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext.xml

classpath:org/codehaus/xfire/spring/xfire.xml</param-value>

</context-param>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<servlet>

<servlet-name>xfire</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>xfire</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 7:  Copy All class files with folder structure in WEB-INF classes Folder

Step 8:

Create ant directory in project root folder

Create build.xml file

build.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<project name=”ws” basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”address.war”  >

<fileset dir=”${basedir}”>

<include name=”**/*.class”/>

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar”/>

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml”/>

<exclude name=”**/*build*”/>

</fileset>

</jar>

</target>

</project>

Step 9: Run ant build

Step 10: Deploy the war file in application server/web server

Step 11: Check application deployed properly or not by using following url. This url will show the wsdl file for this web service application.

http://localhost:8080/address/AddressService?wsdl

WSDL file

Developing Web Services Client By Using Spring and XFire

Step 1: Download Following Jar files.

required jars

Step 2:  Create Following Folder Structure

Folder Structure

Step 3: Create following classes

  1. Address
  2. AddressType
  3. IAddressService
  4. WSClient
  5. MyApplicationClient  (This is normal Java Application client. Not a web Client)

WsClient.java

package com.sungard.adms.address.ws.client;

import java.io.IOException;

import java.net.MalformedURLException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import org.codehaus.xfire.XFire;

import org.codehaus.xfire.XFireFactory;

import org.codehaus.xfire.client.XFireProxyFactory;

import org.codehaus.xfire.service.Service;

import org.codehaus.xfire.service.binding.ObjectServiceFactory;

import com.sungard.adms.address.ws.Address;

import com.sungard.adms.address.ws.AddressType;

import com.sungard.adms.address.ws.IAddressService;

/**

* Servlet working as a Web services client.

*

*/

public class WsClient extends HttpServlet {

private static Logger log = Logger.getLogger(WsClient.class);

/*

* doGet():

*/

protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

// get request parameters

String addType = req.getParameter(“addressType”);

// use default values wherever needed

AddressType addrType;

if (addType == null)

addrType = AddressType.HEBBALOFFICE;

else

addrType = AddressType.valueOf(addType);

// invoke callWebService()

log.debug(“doGet(): call web service now. “);

Address responseGot = null;

try {

responseGot = callWebService(AddressType.HEBBALOFFICE);

} catch (Exception e) {

e.printStackTrace();

}

// prepare the response page

resp.setContentType(“text/html”);

java.io.PrintWriter out = resp.getWriter();

out.println(“<html>”);

out

.println(“<head><title>Sungard Bangalore – Address Service</title></head><body>”);

out.println(“<h2>Sungard Bangalore – Address Service </h2>”);

out.println(“<B>Service Request</B>” + “<br>” + “Address – ” + addType

+ “<TABLE>” + “<TR><TD>Name: </TD><TD>” + responseGot.getName()

+ “</TD></TR>” + “<TR><TD>Door Number: </TD><TD>”

+ responseGot.getDoorno() + “</TD></TR>”

+ “<TR><TD>Building Name: </TD><TD>”

+ responseGot.getBuildingName() + “<br>” + “</TD></TR>”

+ “<TR><TD>Road: </TD><TD>” + responseGot.getRoad()

+ “</TD></TR>” + “</TABLE>”);

}

/*

* call the web service

*

*/

public static Address callWebService(AddressType addtype)

throws MalformedURLException, Exception {

// create a metadata of the service

Service serviceModel = new ObjectServiceFactory()

.create(IAddressService.class);

System.out.println(“callSoapServiceLocal(): got service model.”);

// create a proxy for the deployed service

XFire xfire = XFireFactory.newInstance().getXFire();

XFireProxyFactory factory = new XFireProxyFactory(xfire);

String serviceUrl = “http://localhost:8080/address/AddressService&#8221;;

IAddressService client = null;

try {

client = (IAddressService) factory.create(serviceModel, serviceUrl);

} catch (MalformedURLException e) {

e.printStackTrace();

}

// invoke the service

Address address = null;

try {

address = client.getAddress(addtype);

} catch (Exception e) {

e.printStackTrace();

}

// return the response

return address;

}

/*

* doPost():

*/

protected void doPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

doGet(req, resp);

}

static String SPACE = “&nbsp; &nbsp;”;

}

MyApplicationClient.java

package com.sungard.adms.address.ws.client;

import java.net.MalformedURLException;

import org.codehaus.xfire.XFire;

import org.codehaus.xfire.XFireFactory;

import org.codehaus.xfire.client.XFireProxyFactory;

import org.codehaus.xfire.service.Service;

import org.codehaus.xfire.service.binding.ObjectServiceFactory;

import com.sungard.adms.address.ws.Address;

import com.sungard.adms.address.ws.AddressType;

import com.sungard.adms.address.ws.IAddressService;

public class MyApplicationClient {

public static void main(String[] args) {

try{

Address address=MyApplicationClient.callWebService(AddressType.LANGFORD_ROAD);

System.out.println(address.getName());

System.out.println(address.getDoorno());

System.out.println(address.getBuildingName());

System.out.println(address.getRoad());

}catch(Exception e){

e.printStackTrace();

}

}

public static Address callWebService(AddressType addtype)

throws MalformedURLException, Exception{

//create a metadata of the service

Service serviceModel = new ObjectServiceFactory().create(IAddressService.class);

//create a proxy for the deployed service

XFire xfire = XFireFactory.newInstance().getXFire();

XFireProxyFactory factory = new XFireProxyFactory(xfire);

String serviceUrl = “http://localhost:8080/address/AddressService&#8221;;

IAddressService client = null;

try {

client = (IAddressService) factory.create(serviceModel, serviceUrl);

} catch (MalformedURLException e) {

e.printStackTrace();

}

//invoke the service

Address address = null;

try {

address = client.getAddress(addtype);

} catch (Exception e){

e.printStackTrace();

}

//return the response

return address;

}

}

Step 4: Copy all the class files in WEB-INF/classes folder with package folder structure.

Step 5: Create web.xml file in WEB-INF folder

web.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE web-app PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN” “http://java.sun.com/dtd/web-app_2_3.dtd”&gt;

<web-app id=”WebApp_ID”>

<display-name>WebServices using XFire</display-name>

<servlet>

<servlet-name>WsClient</servlet-name>

<display-name>WsClientServlet</display-name>

<description></description>

<servlet-class>com.sungard.adms.address.ws.client.WsClient</servlet-class>

</servlet>

<servlet>

<servlet-name>XFireServlet</servlet-name>

<display-name>XFire Servlet</display-name>

<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/servlet/XFireServlet/*</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/services/*</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>WsClient</servlet-name>

<url-pattern>/ws</url-pattern>

</servlet-mapping>

</web-app>

Step 6: Create addressclient.war file by using ant script.

Step 7: deploy the client application in AppServer/WebServer.

Step 8: Run the client by using following url

http://localhost:8080/addressclient/ws?addressType=HEBBALOFFICE

addressType value you can give any one of the Enumerator value(AddressType)

Client Output

Step 9: Or Run MyApplicationClient as a normal java application.

September 2, 2009 Posted by | Web Services | Leave a comment

Developing Web services Using Spring Framework


Required Softwares:

  1. JAXB
  2. Tomcat Server

Step 1: Download Following Jar files.

Open up your favorite IDE and create a new project StudentWS. The first thing we need to do is add the necessary Spring dependencies to the project.

acegi-security-1.0.6.jar

activation.jar

activation-1.1.1.jar

ant-dotnet-1.0.jar

axiom-api-1.2.8.jar

axiom-impl-1.2.8.jar

bcel-5.1.jar

bcprov-jdk14-140.jar

castor-1.2.jar

commons-collections-3.2.jar

commons-httpclient-3.1.jar

commons-io-1.3.1.jar

commons-lang-2.1.jar

commons-logging-1.1.1.jar

dom4j-1.6.1.jar

isorelax-20030108.jar

jaxb1-impl.jar

jaxb-api-2.1.jar

jaxb-impl-2.1.5.jar

jaxb-libs-1.0.6.jar

jaxb-xjc.jar

jaxen-1.1.1.jar

jchardet-1.0.jar

jdom-1.0.jar

jibx-bind-1.1.6a.jar

jibx-run-1.1.6a.jar

jms-1.1.jar

jsr173_1.0_api.jar

junit-4.4.jar

log4j-1.2.15.jar

mail-1.4.1.jar

maven-ant-tasks-2.0.7.jar

opensaml-1.1.jar

oro-2.0.8.jar

plexus-utils-1.1.jar

plexus-velocity-1.1.3.jar

relaxngDatatype-20020414.jar

saaj-api-1.3.jar

saaj-impl-1.3.2.jar

servlet-api-2.5.jar

slf4j-api-1.3.1.jar

spring-aop-2.5.6.jar

spring-beans-2.5.6.jar

spring-context-2.5.6.jar

spring-core-2.5.6.jar

spring-jdbc-2.5.6.jar

spring-jms-2.5.6.jar

spring-orm-2.5.6.jar

spring-oxm-1.5.6.jar

spring-oxm-tiger-1.5.6.jar

spring-security-core-2.0.2.jar

spring-test.jar

spring-tx-2.5.6.jar

spring-web-2.5.6.jar

spring-webmvc-2.5.6.jar

spring-ws-1.5.6-all.jar

spring-ws-1.5.6-sources.jar

spring-ws-archetype-1.5.4.jar

spring-ws-core-1.5.6.jar

spring-ws-core-tiger-1.5.6.jar

spring-ws-security-1.5.6.jar

spring-ws-support-1.5.6.jar

spring-xml-1.5.6.jar

stax-api-1.0.1.jar

velocity-1.5.jar

velocity-dep-1.4.jar

wsdl4j-1.6.1.jar

wss4j-1.5.5.jar

wstx-asl-3.2.7.jar

xalan-2.7.0.jar

xbean-2.2.0.jar

xercesImpl-2.8.1.jar

xml-apis-1.3.04.jar

XmlSchema-1.4.3.jar

xmlsec-2.0.jar

xom-1.1.jar

xpp3-1.1.3.4.O.jar

xsdlib-20060615.jar

xstream-1.3.jar

xws-security-2.0-FCS.jar

Step 2: Create Following Folder Structure

Spring Folder Structure

Step 3: Create .xsd file to design your request and response objects.

studentregistration.xsd

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>

<xs:schema xmlns=”http://studentregistration.banner.sungardhe.com&#8221;

xmlns:xs=”http://www.w3.org/2001/XMLSchema&#8221;

targetNamespace=”http://studentregistration.banner.sungardhe.com&#8221;

elementFormDefault=”unqualified” attributeFormDefault=”unqualified”>

<xs:element name=”StudentRegistrationRequest”>

<xs:complexType>

<xs:sequence minOccurs=”1″>

<xs:element ref=”University” />

<xs:element ref=”Registrant” />

</xs:sequence>

<xs:attribute name=”version” type=”xs:string”

use=”optional” />

</xs:complexType>

</xs:element>

<xs:element name=”StudentRegistrationResponse”>

<xs:complexType>

<xs:sequence>

<xs:element ref=”RegistrationCode” />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name=”University”>

<xs:complexType>

<xs:choice>

<xs:element ref=”UniversityId” />

<xs:element ref=”UniversityName” />

<xs:element ref=”CourseName” />

</xs:choice>

</xs:complexType>

</xs:element>

<xs:element name=”UniversityName”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”25″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”CourseName”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”25″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”UniversityId”>

<xs:simpleType>

<xs:restriction base=”xs:int” />

</xs:simpleType>

</xs:element>

<xs:element name=”Registrant”>

<xs:complexType>

<xs:sequence>

<xs:element ref=”FirstName” />

<xs:element minOccurs=”0″ maxOccurs=”1″

ref=”MiddleName” />

<xs:element ref=”LastName” />

<xs:element ref=”Email” />

<xs:element ref=”Phone” />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name=”FirstName”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”25″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”MiddleName”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”15″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”LastName”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”75″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”Email”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”100″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”Phone”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”100″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name=”RegistrationCode”>

<xs:simpleType>

<xs:restriction base=”xs:string”>

<xs:maxLength value=”50″ />

</xs:restriction>

</xs:simpleType>

</xs:element>

</xs:schema>

Step 4: Create .xjb file for customizing your JAXB Bindings.

For More Information: http://java.sun.com/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html

studentregistration.xjb

<jxb:bindings version=”1.0″ xmlns:jxb=”http://java.sun.com/xml/ns/jaxb&#8221;

xmlns:xjc=”http://java.sun.com/xml/ns/jaxb/xjc&#8221;

xmlns:xs=”http://www.w3.org/2001/XMLSchema”&gt;

<jxb:bindings schemaLocation=”studentregistration.xsd” node=”/xs:schema”>

<jxb:schemaBindings>

<jxb:package name=”com.sungardhe.banner.studentregistration.jaxb” />

</jxb:schemaBindings>

</jxb:bindings>

</jxb:bindings>

Step 5: Create new folder ‘resources’ Under src folder.

Step 6: Copy .xsd and .xjb files into resource Directory.

Step 7: compile .xsd file using xjc compiler from src folder.

xjc resources\studentregistration.xsd -b resources\studentregistration.xjb

XJC Output

Step 8: Create following Interface and class under com.sungardhe.banner.ws.student Package.

  1. MarshallingStudentService
  2. StudentEndpoint

MarshallingStudentService.java

package com.sungardhe.banner.ws.student;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationRequest;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationResponse;

/**

*

* @author PeterA

*

*/

public interface MarshallingStudentService {

/**

* NameSpace URL

*/

public final static String NAMESPACE = “http://studentregistration.banner.sungardhe.com&#8221;;

/**

* Request Object Element Name.

*/

public final static String GET_PERSONS_REQUEST = “StudentRegistrationRequest”;

/**

* Gets Student Request.

*

* @param request

* @return

*/

public StudentRegistrationResponse getPersons(

StudentRegistrationRequest request);

}

StudentEndpoint.java

package com.sungardhe.banner.ws.student;

import org.springframework.ws.server.endpoint.annotation.Endpoint;

import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

import com.sungardhe.banner.studentregistration.jaxb.ObjectFactory;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationRequest;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationResponse;

/**

*

* @author PeterA

*

*/

@Endpoint

public class StudentEndpoint implements MarshallingStudentService {

/**

* Gets Student Request from web services client.

*

* @param request

* @return

*/

@PayloadRoot(localPart = GET_PERSONS_REQUEST, namespace = NAMESPACE)

public StudentRegistrationResponse getPersons(

StudentRegistrationRequest request) {

/* Printing Requested Student name. */

System.out.println(“Requested Student Name::”

+ request.getRegistrant().getFirstName() + ” ”

+ request.getRegistrant().getMiddleName() + ” ”

+ request.getRegistrant().getLastName());

/* Printing Requested Student E-Mail. */

System.out.println(“Requested Student Email::”

+ request.getRegistrant().getEmail());

/* Printing Requested Student Phone. */

System.out.println(“Requested Student Phone::”

+ request.getRegistrant().getPhone());

/* Printing Requested Student Applied University ID. */

System.out.println(“Applied University ID::”

+ request.getUniversity().getUniversityId());

/* Printing Requested Student Applied University Name. */

System.out.println(“Applied University Name::”

+ request.getUniversity().getUniversityName());

/* Printing Requested Student Applied Course Name. */

System.out.println(“Applied Course Name::”

+ request.getUniversity().getCourseName());

/* Creating ObjectFactory Object for creating response object. */

ObjectFactory objectFactory = new ObjectFactory();

/*

* Creating Response Object.

*/

StudentRegistrationResponse response = objectFactory

.createStudentRegistrationResponse();

/*

* Populating Response Object.

*/

response

.setRegistrationCode(“Student Registration Done: Registration Code:: SR567432”);

/*

* Returning Response Object.

*/

return response;

}

}

Step 9: Create spring-ws-servlet.xml file under WEB-INF folder.

spring-ws-servlet.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd”&gt;

<bean />

<bean id=”marshaller”

>

<property name=”contextPath”

value=”com.sungardhe.banner.studentregistration.jaxb” />

</bean>

<bean id=”unmarshaller”

>

<property name=”contextPath”

value=”com.sungardhe.banner.studentregistration.jaxb” />

</bean>

<bean id=”service”

>

<property name=”builder”>

<bean

>

<property name=”schema”

value=”/WEB-INF/classes/resources/studentregistration.xsd” />

<property name=”portTypeName” value=”services” />

<property name=”locationUri”

value=”http://localhost:8080/StudentWS/&#8221; />

<property name=”targetNamespace”

value=”http://studentregistration.banner.sungardhe.com&#8221; />

</bean>

</property>

</bean>

<bean

>

<description>

An endpoint mapping strategy that looks for @Endpoint and

@PayloadRoot annotations.

</description>

</bean>

<bean

>

<description>

Enables the MessageDispatchServlet to invoke methods

requiring OXM marshalling.

</description>

<constructor-arg ref=”marshaller” />

</bean>

</beans>

Step 10: Create web.xml file under WEB-INF Folder.

web.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<web-app xmlns=”http://java.sun.com/xml/ns/j2ee&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&#8221;

version=”2.4″>

<display-name>Archetype Created Web Application</display-name>

<servlet>

<servlet-name>spring-ws</servlet-name>

<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>spring-ws</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

Step 11: Create build.xml file under ant folder.

build.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<project name=”ws” basedir=”../” default=”archive”>

<target name=”archive”>

<jar destfile=”StudentWS.war”>

<fileset dir=”${basedir}”>

<include name=”**/*.class” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.jar” />

</fileset>

<fileset dir=”${basedir}”>

<include name=”**/*.xml” />

<include name=”**/*.xsd” />

<include name=”**/*.xjb” />

<exclude name=”**/*build*” />

</fileset>

</jar>

</target>

</project>

Step 12: run build.xml using ant to generate StudentWS.war file.

Step 13: Run Tomcat server.

Step 14: Deploy StudentWS.war file into $TomcatHome/webapps folder.

Step 15: Check application deployed properly or not by using following url. This url will show the wsdl file for this web service application.

http://localhost:8080/StudentWS/service.wsdl

WSDL file

Developing Simple Web Services Client by Using Sping

Step 1: Create Following class files.

  1. StudentClient.java
  2. ApplicationClient.java

StudentClient.java

import org.springframework.ws.client.core.WebServiceTemplate;

import com.sungardhe.banner.studentregistration.jaxb.Registrant;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationRequest;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationResponse;

import com.sungardhe.banner.studentregistration.jaxb.University;

public class StudentClient {

private WebServiceTemplate webServiceTemplate;

public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {

this.webServiceTemplate = webServiceTemplate;

}

public StudentRegistrationResponse send() {

StudentRegistrationRequest request = new StudentRegistrationRequest();

Registrant registrant = new Registrant();

registrant.setFirstName(“Jesus”);

registrant.setLastName(“Chirst”);

registrant.setMiddleName(“Joseph”);

registrant.setEmail(“Jesus@god.com”);

registrant.setPhone(“9876543210”);

University university = new University();

university.setUniversityId(12345);

university.setUniversityName(“Holy University”);

university.setCourseName(“Service”);

request.setRegistrant(registrant);

request.setUniversity(university);

request.setVersion(“1.0”);

return ((StudentRegistrationResponse) webServiceTemplate

.marshalSendAndReceive(request));

}

}

ApplicationClient.java

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationResponse;

public class ApplicationClient {

public static void main(String[] args) {

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(

“applicationContext.xml”);

StudentClient mc = (StudentClient) ctx.getBean(“studentclient”);

StudentRegistrationResponse obj = mc.send();

System.out.println(obj.getRegistrationCode());

}

}

Step 2: Create applicationContext.xml file and place this file in classpath.

applicationContext.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”&gt;

<bean id=”studentclient” class=”StudentClient”>

<property name=”webServiceTemplate” ref=”webServiceTemplate” />

</bean>

<bean id=”messageFactory”

/>

<bean id=”webServiceTemplate”

>

<constructor-arg ref=”messageFactory” />

<property name=”marshaller” ref=”marshaller” />

<property name=”unmarshaller” ref=”marshaller” />

<property name=”defaultUri”

value=”http://localhost:8080/StudentWS&#8221; />

</bean>

<bean id=”marshaller”

>

<property name=”classesToBeBound”>

<list>

<value>

com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationRequest

</value>

<value>

com.sungardhe.banner.studentregistration.jaxb.StudentRegistrationResponse

</value>

</list>

</property>

</bean>

</beans>

Step 3: Run ApplicationClient.java as a normal java application.

Client Output

Step 4: Check server console it displays Request Object.

Server Console Output

September 2, 2009 Posted by | Web Services | 4 Comments

Developing Simple Web Services by Using JWSDP


Developing Simple Web Services by Using JWSDP

Step 1: Start new J2EE project WebServices.

Step 2: Create directories WEB-INF/src (Source), WEB-INF/classes ( .class files), WEB-INF/ lib (jars) and WEB-INF/wsdl.

Step 3: Create new interface com.j2ee.ws.Hello as

package com.ws.j2ee;

import java.rmi.Remote;

import java.rmi.RemoteException;

/**

* @author Peter Arockiaraj

*/

public interface Hello extends Remote {

public String sayHello(String name)throws RemoteException;

}

Step 4: Create a class HelloWS that implements the above interface

package com.ws.j2ee;

import java.rmi.RemoteException;

/**

* @author Peter Arockiaraj

*/

public class HelloWS implements Hello{

/* (non-Javadoc)

* @see com.ws.j2ee.Hello#sayHello(java.lang.String)

*/

public String sayHello(String name) throws RemoteException {

// TODO Auto-generated method stub

return “Hello ” + name;

}

}

Step 5: Create config.xml file inside WEB-INF with the following contents

<?xml version=”1.0″ encoding=”UTF-8″?>

<configuration xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/config”&gt;

<service name=”HelloService”

targetNamespace=”http://com.ws.j2ee/jws/hello&#8221;

typeNamespace=”http://com.ws.j2ee/jws/hello/types&#8221;

packageName=”com.ws.j2ee”>

<interface name=”com.ws.j2ee.Hello”/>

</service>

</configuration>

Step 6: Generate WSDL and Tie classes using wscompile using the following command

wscompile -classpath ./WEB-INF/classes -gen:server -f:rpcliteral -mapping META-INF/jaxrpc-mapping.xml -keep META-INF/config.xml

This generates a WSDL file for  RPC Literal messaging and a jaxrpc-mapping file and server side tie files.

Step 7: Copy  jaxrpc-mapping.xml into WEB-INF

Step 8: Copy HelloService.wsdl into WEB-INF/wsdl

Step 9: Copy the following files  from

jwsdp/jax-rpc/lib/jaxrpc-impl.jar into WEB-INF/lib

jwsdp/jax-rpc/lib/jaxrpc-spi.jar into WEB-INF/lib

jboss/server/default/lib/activation.jar into WEB-INF/lib

jwsdp/jaxp/dom.jar into WEB-INF/lib

jwsdp/jaxp/sax.jar into WEB-INF/lib

jwsdp/jaxp/xalan.jar into WEB-INF/lib

jwsdp/jaxp/xercesImpl.jar into WEB-INF/lib

Step 10: Add the .jar files into build path.

Step 11: Create web.xml in WEB-INF directory.

<?xml version=”1.0″ encoding=”UTF-8″?>

<web-app xmlns=”http://java.sun.com/xml/ns/j2ee&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&#8221;

version=”2.4″>

<servlet>

<servlet-name>HelloService</servlet-name>

<servlet-class>com.ws.j2ee.HelloWS</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>HelloService</servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

</web-app>

Step 12: Create webservices.xml file inside WEB-INF as

<?xml version=”1.0″ encoding=”UTF-8″?>

<webservices xmlns=”http://java.sun.com/xml/ns/j2ee&#8221;

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;

xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd&#8221; version=”1.1″>

<webservice-description>

<webservice-description-name>HelloService</webservice-description-name>

<wsdl-file>WEB-INF/wsdl/HelloService.wsdl</wsdl-file>

<jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>

<port-component>

<port-component-name>Hello</port-component-name>

<wsdl-port>HelloPort</wsdl-port>

<service-endpoint-interface>com.ws.j2ee.Hello</service-endpoint-interface>

<service-impl-bean>

<servlet-link>HelloService</servlet-link>

</service-impl-bean>

</port-component>

</webservice-description>

</webservices>

Step 13: Create a package with following structure ( call it hellows-rpc.war)

WEB-INF/classes/*.class files

WEB-INF/lib/*.jar files

WEB-INF/wsdl/HelloService.wsdl file

WEB-INF/web.xml,. jaxrpc-mapping.xml , config.xml file

Step 14: Run Build and Create hellows-rpc.war.

Step 15: Copy file into deploy dir of jBOSS.

Step 16: After the web service is deployed, the wsdl file is produces at default/data/wsdl and is published at

http://localhost:8080/hellows-rpc/hello?wsdl

Writing a WS Client

Step 1: Create a j2EE project HelloWSClient

Step 2: Create Folder structure src, classes, lib ,wsdl.

Step 3: Create file config.xml inside the project root as

<?xml version=”1.0″ encoding=

“UTF-8″?>

<configuration xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/config”&gt;

<wsdl location=

“wsdl\HelloService.wsdl”

packageName=

“com.ws.clients.gen” />

</configuration>

Step 4: Copy the .wsdl from http://localhost:8080/hellows-rpc/hello?wsdl into HelloWSClient/wsdl

Step 5: Generate client side stubs by executing…

wscompile -verbose -gen -d classes -s src -keep config.xml

Step 6: Copy the following files  from

jwsdp/jax-rpc/lib/jaxrpc-impl.jar into lib

jwsdp/jax-rpc/lib/jaxrpc-spi.jar into lib

jboss/server/default/lib/activation.jar into lib

jboss/server/default/lib/mail.jar into lib

jwsdp/jaxp/dom.jar into lib

jwsdp/jaxp/sax.jar into lib

jwsdp/jaxp/xalan.jar into lib

jwsdp/jaxp/xercesImpl.jar into lib

jwsdp/saaj/saaj-impl.jar into lib

jwsdp/fastinfoset/lib/FastInfoset.jar into lib

jwsdp/saaj/lib/saajImpl.jar into lib

jwsdp/sjsxp/lib/jsr173_api.jar into lib

Step 7: Add them to build path

Step 8: Create class  HelloClient.java as

package com.ws.clients;

import java.net.MalformedURLException;

import java.net.URL;

import java.rmi.RemoteException;

import javax.xml.namespace.QName;

import javax.xml.rpc.Service;

import javax.xml.rpc.ServiceException;

import javax.xml.rpc.ServiceFactory;

import com.ws.clients.gen.Hello;

import com.ws.clients.gen.HelloService_Impl;

/**

* @author Peter Arockiaraj

*/

public class HelloClient {

public static void main(String[] args) throws ServiceException,RemoteException,MalformedURLException{

System.out.println(“Hello Web Service Client”);

try{

System.setProperty(“javax.xml.soap.MessageFactory”, “com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl”);

//System.setProperty(“javax.xml.soap.SOAPFactory”,”com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl”);

//System.setProperty(“javax.xml.rpc.ServiceFactory”,”com.sun.xml.rpc.client.ServiceFactoryImpl”);

//System.setProperty(“javax.xml.soap.SOAPConnectionFactory”,”javax.xml.soap.SOAPConnectionFactory”);

//System.setProperty(“javax.xml.parsers.DocumentBuilderFactory”,”com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl”);

HelloService_Impl impl =

new HelloService_Impl();

Hello ws = impl.getHelloPort();

String result = ws.sayHello(“test”);

System.out.println(“WS output is ” + result);

System.out.println(“Dynamic WS call”);

URL url = new URL (“http://localhost:8080/hellows-rpc/hello?wsdl&#8221;);

QName qname = new QName(“http://com.ws.j2ee/jws/hello&#8221;,”HelloService”);

ServiceFactory factory = ServiceFactory.newInstance();

Service service = factory.createService(url,qname);

Hello hello = (Hello) service.getPort(Hello.class);

System.out.println(“hello.hello(” + “test” + “)”);

System.out.println(“output:” + hello.sayHello(“test”));

}catch(Exception se){

System.out.println(“ServiceException ” + se.getMessage());

}

}

}

Step 9: Execute HelloClient.clas

Output is as

Hello Web Service Client

WS output is Hello test

Dynamic WS call

ServiceException null

SOAP request:

<?xml version=”1.0″ encoding=”UTF-8″?>

<env:Envelope xmlns:env=”http://schemas.xmlsoap.org/soap/envelope/&#8221; xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:enc=”http://schemas.xmlsoap.org/soap/encoding/&#8221; xmlns:ns0=”http://com.ws.j2ee/jws/hello”&gt;

<env:Body>

<ns0:sayHello>

<String_1>test</String_1>

</ns0:sayHello>

</env:Body>

</env:Envelope>

SOAP Response:

<?xml version=”1.0″ encoding=”UTF-8″?>

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/&#8221; xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”&gt;

<soapenv:Body>

<ns1:sayHelloResponse xmlns:ns1=”http://com.ws.j2ee/jws/hello”&gt;

<result>Hello test</result>

</ns1:sayHelloResponse>

</soapenv:Body>

</soapenv:Envelope>

DOCUMENT based web services:

Step 1: Regenerate the server wsdls and Tie classes using…

wscompile -classpath ./WEB-INF/classes -gen:server -f:documentliteral -mapping jaxrpc-mapping.xml -keep WEB-INF/config.xml

Copy jaxrpc-mapping file and HelloService.wsdl as before.

Step 2: Package it as hellows-doc.war and deploy it.

Client side

Step 1: Take the wsdl from http://loocalhost:8080/hellows-doc/hello?wsdl and generate client stubs.

Step 2: Run

wscompile -verbose -gen -d classes -s src -keep config.xml

Step 3: Modify HelloClient.java as

package com.ws.clients;

import java.net.MalformedURLException;

import java.net.URL;

import java.rmi.RemoteException;

import javax.xml.namespace.QName;

import javax.xml.rpc.Service;

import javax.xml.rpc.ServiceException;

import javax.xml.rpc.ServiceFactory;

import com.ws.clients.gen.Hello;

import com.ws.clients.gen.HelloService_Impl;

/**

* @author Peter Arockiaraj

*/

public class HelloClient {

public static void main(String[] args) throws ServiceException,RemoteException,MalformedURLException{

System.out.println(“Hello Web Service Client”);

try{

System.setProperty(“javax.xml.soap.MessageFactory”, “com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl”);

//System.setProperty(“javax.xml.soap.SOAPFactory”,”com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl”);

//System.setProperty(“javax.xml.rpc.ServiceFactory”,”com.sun.xml.rpc.client.ServiceFactoryImpl”);

//System.setProperty(“javax.xml.soap.SOAPConnectionFactory”,”javax.xml.soap.SOAPConnectionFactory”);

//System.setProperty(“javax.xml.parsers.DocumentBuilderFactory”,”com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl”);

HelloService_Impl impl =

new HelloService_Impl();

Hello ws = impl.getHelloPort();

String result = ws.sayHello(“test”);

System.out.println(“WS output is ” + result);

System.out.println(“Dynamic WS call”);

URL url = new URL(“http://localhost:8080/hellows-doc/hello?wsdl&#8221;);

QName qname = new QName(“http://com.ws.j2ee/jws/hello&#8221;,”HelloService”);

ServiceFactory factory = ServiceFactory.newInstance();

Service service = factory.createService(url,qname);

Hello hello = (Hello) service.getPort(Hello.class);

System.out.println(“hello.hello(” + “test” + “)”);

System.out.println(“output:” + hello.sayHello(“test”));

}catch(Exception se){

System.out.println(“ServiceException ” + se.getMessage());

}

}

}

Step 4: Execute HelloClient.java

Output is

Hello Web Service Client

WS output is Hello test

Dynamic WS call

ServiceException null

SOAP request:

<?xml version=”1.0″ encoding=”UTF-8″?>

<env:Envelope xmlns:env=”http://schemas.xmlsoap.org/soap/envelope/&#8221; xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:enc=”http://schemas.xmlsoap.org/soap/encoding/&#8221; xmlns:ns0=”http://com.ws.j2ee/jws/hello/types”&gt;

<env:Body>

<ns0:sayHello>

<String_1>test</String_1>

</ns0:sayHello>

</env:Body>

</env:Envelope>

SOAP response:

<?xml version=”1.0″ encoding=”UTF-8″?>

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/&#8221; xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”&gt;

<soapenv:Body>

<ns1:sayHelloResponse xmlns:ns1=”http://com.ws.j2ee/jws/hello/types”&gt;

<result>Hello test</result>

</ns1:sayHelloResponse>

</soapenv:Body>

</soapenv:Envelope>

September 2, 2009 Posted by | Web Services | 1 Comment