Showing posts with label Apache Axis2. Show all posts
Showing posts with label Apache Axis2. Show all posts

Tuesday, February 04, 2014

Publicly Listed Apache Axis2 Services

Google and other search engines constantly crawl the web. This allows some interesting search terms where the search engine would allow one to find directory listings of various items. This is an interesting case where people one researcher was able to find SCM directories.
With this in mind ... try googling for the following term:
"Available services" "Service EPR"
This gives a set of publicly hosted Apache Axis2 WAR distributions. Quite a few of them still had the default version service. Interestingly, the service listings includes faulty services, which displays the full path of those faulty service archive (.aar) files. Due to obvious differences in the presented path values this "feature" also discloses whether the host system is a UNIX based system or a Windows system. This maybe something to think about when managing service your deployments.

Sunday, February 02, 2014

Maven Archetype to Create an Apache Axis2 Service

This is a simple archetype that will create a simple axis2 service for you. The generated project includes a "setup" script and a "start" script. These hosts the built service in the simple HTTP server that is available with Apache Axis2 binary distribution.

Sunday, November 27, 2011

Axis2 : Starting with a WSDL

If you are ever given a WSDL and asked create your own client and service you can follow the following steps.

Sometime back I wrote an Axis2 hello world tutorial which started with a simple Java class and used a generated client to invoke the service operation. But here we start with a given wsdl file.

You will need the following :

  • Axis2 binary distribution

  • Apache Ant (installed)

  • JDK (installed)


Generate service
Use WSDL2Java to generate service code as follows :

$ /path/to/axis2-binary-distro/bin/wsdl2java.sh -ss -sd -uw -uri service.wsdl -o service/code/dir/path

Complete Service
This is where you will add the business logic to the generated service.
Locate the file Skeleton.java file in the service/code/dir/path/src/... directory and complete the methods that you find. They are generated to throw UnsupportedOperationException.
Host Service
Do
$ ant
in the service/code/dir/path/ directory. This will generate an .aar file in service/code/dir/path/build/lib/ directory. Drop this file into /path/to/axis2-binary-distro/repository/services directory. And start axis2 server with :

$ /path/to/axis2-binary-distro/bin/axis2server.sh

Make sure service is working by pointing the browser to :
http://localhost:8080/axis2/services/service?wsdl
Generate Client
Now you can use the WSDL2Java tool once again to generate a client for the service.

/path/to/axis2-binary-distro/bin/wsdl2java.sh -uw -uri http://localhost:8080/axis2/services/service?wsdl -o client/dir/

Test
The code generated in the previous step provides a Stub.java file which provides the required methods to invoke operations of the hosted service. Now you can simply create an instance of this stub and invoke the service.

Thursday, June 19, 2008

Back after a while ...

Hmm ... I've been away from blogging for more than a month ... so here's a recap of what I couldn't blog about :



Well ... thats it for now ... :-) ...

Monday, February 11, 2008

Access a Restricted EJB Method as a Web Service with UsernameToken Authentication

What if we need to expose an EJB as a web service? No problem ... we can simply use the org.apache.axis2.rpc.receivers.ejb.EJBMessageReceiver provided by Axis2. But what if the EJB's methods are access restricted?

I figured out that it is very easy to write a custom wrapper web service to expose such a protected EJB and use standard UsernameToken authentication on it.

Following are the steps I followed to try this out:

Step 1 : Basic EJB sample with OpenEJB

First I followed this "hello world" sample using OpenEJB and setup the OpenEJB container and deployed the EJB.

Step 2 : Modified "HelloBean" to restrict access to "sayHello" method


@RolesAllowed({"committer"})
public String sayHello() {
return "Hello World!!!";
}


Now only users with committer role can access this method.
The users used by the default login module implementation are listed in "conf/users.properties" of the OpenEJB distribution.

Step 3 : Develop and deploy a service to wrap the EJB


We basically have to write a service that is a client to this EJB. I engaged Rampart on this service and configured it with WS-SecurityPolicy to expect a UsernameToken. And then obtained the user name and password from security processing results and used those credentials in invoking the EJB.

Have a look at the following service class :


package org.acme;

import java.io.IOException;
import java.util.Properties;
import java.util.Vector;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.axis2.context.MessageContext;
import org.apache.ws.security.WSConstants;
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 SimpleEJBService implements CallbackHandler {

public String sayHello() throws Exception {


Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
props.put(Context.PROVIDER_URL, "ejbd://127.0.0.1:4201");

//Obtain the principal
WSUsernameTokenPrincipal principal = getPrincipal();


//Set the username and password
props.put(Context.SECURITY_PRINCIPAL, principal.getName());
props.put(Context.SECURITY_CREDENTIALS, principal.getPassword());


Context ctx = new InitialContext(props);
Object ref = ctx.lookup("HelloBeanRemote");

//Invoke method
Hello h = (Hello)PortableRemoteObject.narrow(ref, Hello.class);
String result = h.sayHello();
return result;

}

/*
* Traverse the security processing results of rampart and pick the UsernameToken information.
*/
private WSUsernameTokenPrincipal getPrincipal() {
MessageContext msgCtx = MessageContext.getCurrentMessageContext();
Vector results = null;
if ((results = (Vector) msgCtx
.getProperty(WSHandlerConstants.RECV_RESULTS)) == null) {
throw new RuntimeException("No security results!!");
} else {
for (int i = 0; i < results.size(); i++) {
//Get hold of the WSHandlerResult instance
WSHandlerResult rResult = (WSHandlerResult) results.get(i);
Vector wsSecEngineResults = rResult.getResults();

for (int j = 0; j < wsSecEngineResults.size(); j++) {
//Get hold of the WSSecurityEngineResult instance
WSSecurityEngineResult wser = (WSSecurityEngineResult)
wsSecEngineResults.get(j);
int action = ((Integer)wser.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
if(action == WSConstants.UT) {
WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) wser
.get(WSSecurityEngineResult.TAG_PRINCIPAL);
return principal;
}
}
}
}

return null;
}

public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
//Do nothing since we simply want to move forward
//user name and password to the EJB container
}


}



The services.xml is as follows :


<service>
<parameter name="ServiceClass" locked="false">org.acme.SimpleEJBService</parameter>
<operation name="sayHello">
<messageReceiver
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>

<module ref="rampart"/>

<wsp:Policy wsu:Id="UTOverTransport" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient" />
</wsp:Policy>
</sp:SignedSupportingTokens>

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>org.acme.SimpleEJBService</ramp:passwordCallbackClass>
</ramp:RampartConfig>

</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>


</service>


Note that I didn't bother with authentication of the incoming UsernameToken because this will be handled by the login module of the EJB container.

I first copied all (probably we don't need all of them ...) openejb-* jars from the OpenEJB distro and the jar'ed org.acme.Hello interface to the "lib" directory of WSO2WSAS-2.2 standalone and deployed the service.

Step 4 : Web service client


Finally I generated a client stub using the WSDL2Java tool and developed my client code


package org.acme;

import org.acme.HelloEJBStub.SayHelloResponse;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.rampart.RampartMessageData;

public class Client {

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

//This is because we use a self signed SSL cert in WSO2WSAS
System.setProperty("javax.net.ssl.trustStore", "/path/to/wso2wsas.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2wsas");

ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("/path/to/my/client/repo");

HelloEJBStub stub = new HelloEJBStub(ctx);
ServiceClient client = stub._getServiceClient();

//Engage Rampart
client.engageModule("rampart");

Options options = client.getOptions();


//Set user name and password
options.setUserName("jonathan");
options.setPassword("secret");

//Load and set UsernameToke/HTTPS policy
options.setProperty(
RampartMessageData.KEY_RAMPART_POLICY,
loadPolicy("/path/to/simpl/usernametoken/over/https/policy.xml"));

//Invoke service operation
SayHelloResponse resp = stub.sayHello();

System.out.println(resp.get_return());
}

private static Policy loadPolicy(String xmlPath) throws Exception {
StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
return PolicyEngine.getPolicy(builder.getDocumentElement());
}

}


Note that I have used "jonathan" as the user name and "secret" as the password. This user is there by default in the OpenEJB distro.

That's it !!! ... When I ran the client I got the following response:


Hello World!!!


And when I tried chaing the username I get :


Exception in thread "main" org.apache.axis2.AxisFault: This principle is not authorized.
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:479)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:351)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:397)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:214)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at org.acme.HelloEJBStub.sayHello(HelloEJBStub.java:433)
at org.acme.Client.main(Client.java:32)


Now it is clear that the login module was not able to authenticate the user.

Friday, January 04, 2008

UsernameToken authentication with the *nix account credentials

Ever wondered how we can enable users of a Linux box to authenticate against a web service?

Apache Rampart can be used with JPam to easily set this up. You can simply set up UsernameToken authentication (policy/sample01 in the Apache Rampart distro) and use this callback handler implementation to authenticate against PAM. Make sure you follow the instruction in INSTALL.txt in JPam distribution to set up JPam before using the callback handler.

Thursday, September 06, 2007

Apache Rampart 1.3 Released

This is the 1.3 release of Apache Rampart.

Apache Rampart 1.3 is a toolkit that provides implementations of the WS-Sec* specifications for Apache Axis2 1.3, based on Apache WSS4J 1.5.3 and the Apache AXIOM-DOOM 1.2.5 implementations.

You can download the releases from:
http://www.apache.org/dyn/closer.cgi/ws/rampart/1_3

There are two main Apache Axis2 modules provided with this release.

* rampart-1.3.mar
This provides support for WS-Security and WS-SecureConversation
features.
* rahas-1.3.mar
This module provides the necessary components to enable SecurityTokenService functionality on a service.

Apache Rampart 1.3 uses a configuration model based on WS-Policy and WS-Security Policy. It is important to note that the Apache Rampart 1.0 style configuration is also available even though being marked as deprecated.

Apache Rampart 1.3 can be successfully used with the next Apache Sandesha2 release targeted towards Apache Axis2 1.3 to configure WS-SecureConversation + WS-ReliableMessaging scenarios.

The rampart module was successfully tested for interoperability with other WS-Security implementations.

WS - Sec* specifications supported by Apache Rampart are as follows:

* WS - Security 1.0
* WS - Secure Conversation - February 2005
* WS - Security Policy - 1.1 - July 2005
* WS - Trust - February 2005
* WS - Trust - WS-SX spec - EXPERIMENTAL

Thank you for using Apache Rampart.

Apache Rampart team

Thursday, August 02, 2007

Podcast on Rahas

Rahas is the WS-Trust implementation of Apache Rampart. I recently did a podcast with WSO2 Oxygen Tank about Rahas and its available here.

Saturday, June 02, 2007

Apache Rampart 1.2 Released

This is the 1.2 release of Apache Rampart.

Apache Rampart 1.2 is a toolkit that provides implementations of the
WS-Sec* specifications for Apache Axis2 1.2, based on Apache WSS4J 1.5.2
and the Apache AXIOM-DOOM 1.2.4 implementations.

There are two main Apache Axis2 modules provided with this release.

* rampart-1.2.mar
This provides support for WS-Security and WS-SecureConversation
features.
* rahas-1.2.mar
This module provides the necessary components to enable
SecurityTokenService functionality on a service.


Apache Rampart 1.2 uses a configuration model based on WS-Policy and
WS-Security Policy and it is important to note that Apache Rampart 1.0
style configuration is also available even though being marked as
deprecated.

Apache Rampart 1.2 can be successfully used with the next Apache
Sandesha2 release targeted towards Apache Axis2 1.2 to configure
WS-SecureConversation + WS-ReliableMessaging scenarios.

The rampart module was successfully tested for interoperability with
other WS-Security implementations.

WS - Sec* specifications supported by Apache Rampart are as follows:

* WS - Security 1.0
* WS - Secure Conversation - February 2005
* WS - Security Policy - 1.1 - July 2005
* WS - Trust - February 2005
* WS - Trust - WS-SX spec - EXPERIMENTAL

Rampart-1.2 artifacts can be downloaded from :
http://www.apache.org/dyn/closer.cgi/ws/rampart/1_2

Thank you for using Apache Rampart.

Apache Rampart team

Friday, April 27, 2007

Axis2 1.2 Released

Just over 4 months since the original 1.1.1 release, we are very proud
to announce the release of Apache Axis2 version 1.2

Downloads are available at:
http://ws.apache.org/axis2/download.cgi

Apache Axis2 is a complete re-design and re-write of the widely used
Apache Axis engine and is a more efficient, more scalable, more modular
and more XML-oriented Web services framework. It is carefully designed to
support the easy addition of plug-in "modules" that extend its
functionality for features such as security and reliability.

Modules supporting WS-Security/Secure-Conversation (Apache Rampart),
WS-Trust (Apache Rahas), WS-Reliable Messaging (Apache Sandesha) and
WS-Eventing (Apache Savan) will be available after the Apache Axis2
1.2 release. Please see these projects' own sites for further information.

Major Changes Since 1.1:

  • WSDL 2.0 fully support (reading, writing, and codegen)

  • POJO annotation (JSR 181)

  • JAX-WS integration

  • JAX-WS -annotation

  • Un-wrapping (Response)

  • ADB - support for union and list

  • Maven2 support

  • JSON support

  • Binary serialization (Fast infoset)

  • Codegen support for WSDL with Multiple services

  • HTTP code generation (both WSDL 1.1 and 2.0)

  • Custom deployer support

  • Message formatters

  • Message Builders

  • EJB Provider support


Known Issues and Limitations in 1.2 Release:

  • Xml-beans databinding does not support response uwwrapping

  • ADB databinding does not support minOccurs and maxOccures attributes in sequence and choice elements


Apache Axis2 1.2 is a major new release compared to Axis2 1.1. We are
striving for a simple and happy first time user experience as well as a
satisfying experienced user experience with this release. We welcome any
and all feedback at:
axis-user@ws.apache.org (please include "[axis2]" in the subject)
axis-dev@ws.apache.org (please include "[axis2]" in the subject)
http://issues.apache.org/jira/browse/AXIS2

Thank you for your interest in Apache Axis2!

The Axis2 Development Team
http://ws.apache.org/axis2/

Training courses on Apache Axis2 and Apache Rampart

I will be in Maryland, US in the second week of May. Is anybody
interested in attending tutorials on Apache Axis2 and Apache Rampart?
Both are 1/2 day programs.

This would be on Thursday the 10th of May.

Please drop me a note at training@wso2.com and let me know.