Posts tagged ‘java’

Check in Java web app if user is logged in in Rails web app

I have a Rails application where users can log in and do stuff. For one of the actions a user can perform, I actually use a Java web application integrated in the Rails application. Because I don’t want a malicious user that is not logged in to the application to surf directly to the Java application, I need a system where my Java application is only accessible for users logged in to the Rails application. I used a Servlet Filter that contacts the Rails application in the background and asks if the user is logged in. Only then is the user allowed to proceed.

First I built an a controller in Rails with an action that checks if the user is logged in. In my application this is available at the url localhost:3000/session/check.

class SessionController < ApplicationController

def check

if session[‘user’].nil?

logged_in = false

else

logged_in = true

end

render :text => logged_in.to_s #just write true or false to the output

end

end

package be.vrt.medialab.filters;

Now I want my Java web application to first request the Rails session check and when it returns false it should redirect to the login page instead of serving the Java servlets. I used a Java servlet filter for this job. I created the filter in a separate project, here is the source code:

package be.vrt.medialab.filters;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.MalformedURLException;

import java.util.ResourceBundle;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

public class RailsAuthentication implements Filter {

FilterConfig filterConfig = null;

private ResourceBundle resources;

public RailsAuthentication() {

resources = ResourceBundle.getBundle(“config”);

}

public boolean getRailsResponse(String urlString,String cookie) {

// Open a URL connection.

java.net.URL url;

try {

System.out.println(“urlString=”+urlString);

url = new java.net.URL( urlString );

final java.net.URLConnection uconn = url.openConnection( );

if ( !(uconn instanceof java.net.HttpURLConnection) )

throw new java.lang.IllegalArgumentException(

“URL protocol must be HTTP.” );

final java.net.HttpURLConnection conn =

(java.net.HttpURLConnection)uconn;

// Set up a request.

conn.setConnectTimeout( 10000 ); // 10 sec

conn.setReadTimeout( 10000 ); // 10 sec

conn.setInstanceFollowRedirects( true );

conn.setRequestProperty( “User-agent”, “spider” );

conn.setRequestProperty(“Cookie”, “_ifip_rails_session=”+cookie+“;”);

// Send the request.

conn.connect( );

BufferedReader in = new BufferedReader( new InputStreamReader((InputStream) conn.getContent( )));

String inputLine;

inputLine = in.readLine(); // Process each line.

System.out.println(“rails returned: “+inputLine);

conn.disconnect( );

if (inputLine.equals(“true”)) {

//authentication successful: user is logged in

System.out.println(“authentication successful!”);

return true;

} else {

//authentication failed: user is not logged in

System.out.println(“authentication failed!”);

return false;

}

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException,ServletException {

String railsCheck =resources.getString(“RailsCheck”);

String invalidUrl=resources.getString(“InvalidUrl”);

HttpServletRequest request = (HttpServletRequest) req;

Cookie[] cookies = request.getCookies();

String rails_session_id = null;

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

Cookie cookie = cookies[i];

if (cookie.getName().equals(“_ifip_rails_session”)) {

rails_session_id = cookie.getValue();

}

}

if (rails_session_id == null) {

//authentication fails

System.out.println(“Autentication fails, no rails session id!”);

} else {

System.out.println(“Rails session id is “+rails_session_id);

//query rails app if this session id is from a logged in user

boolean valid_user =getRailsResponse(railsCheck,rails_session_id);

if (valid_user) {

// pass the request along the filter chain

chain.doFilter(request, response);

} else {

System.out.println(“valid_user=”+valid_user+“, redirecting to /RedirectServlet”);

ServletContext context =filterConfig.getServletContext();

context.getRequestDispatcher(“/RedirectServlet”).forward(request, response);

}

}

}

public void init(FilterConfig fConfig) throwsServletException {

// TODO Auto-generated method stub

filterConfig = fConfig;

}

}


I couldn’t find how to redirect to an external URL directly from within the servlet filter, so I just forwarded to a second servlet that has the sole job of redirecting to a certain URL (the login page):


package be.vrt.medialab;

import java.io.IOException;

import java.util.ResourceBundle;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class RedirectServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

private ResourceBundle resources;

public RedirectServlet() {

super();

resources = ResourceBundle.getBundle(“config”);

}

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {

String invalidUrl=resources.getString(“InvalidUrl”);

response.sendRedirect(invalidUrl);

}


protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {

String invalidUrl=resources.getString(“InvalidUrl”);

response.sendRedirect(invalidUrl);

}

}

import java.io.BufferedReader;

Now the only thing we have to do is place the classes in our web application and change the web.xml as follows:

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

<web-appxmlns:xsi=http://www.w3.org/2001/XMLSchema-instance&#8221;xmlns=http://java.sun.com/xml/ns/javaee&#8221;xmlns:web=http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;xsi:schemaLocation=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;id=“WebApp_ID” version=“2.5”>

<display-name>IfipUploader</display-name>

<welcome-file-list>

<welcome-file>TestPage.html</welcome-file>

<welcome-file>FormUpload.html</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<filter>

<filter-name>Rails Authentication</filter-name>

<filter-class>be.vrt.medialab.filters.RailsAuthentication</filter-class>

</filter>

<filter-mapping>

<filter-name>Rails Authentication</filter-name>

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

</filter-mapping>

<servlet>

<servlet-name>RedirectServlet</servlet-name>

<display-name>RedirectServlet</display-name>

<description>redirects to InvalidUrl</description>

<servlet-class>be.vrt.medialab.RedirectServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>RedirectServlet</servlet-name>

<url-pattern>/RedirectServlet</url-pattern>

</servlet-mapping>

<servlet>

<description>Extension of abstract class UploadServlet</description>

<display-name>UploadServletWithQueue</display-name>

<servlet-name>UploadServletWithQueue</servlet-name>

<servlet-class>be.vrt.medialab.upload.UploadServletWithQueue</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>UploadServletWithQueue</servlet-name>

<url-pattern>/UploadServletWithQueue</url-pattern>

</servlet-mapping>

</web-app>

import java.io.IOException;

Below are two logs from the Java web application:

Logged out: (the Rails session id is from a previous session and thus invalid)

Rails session id is BAh7CToQX2NzcmZfdG9rZW4iMVUyeFJWWWVzc1hUZFNPRDR2dkFUb3lONVFaQlJrVmsxR1h0VzVaS3RmUFU9Og9zZXNzaW9uX2lkIiUyOTg2NDc2NzY0N2RlMGU1OWExMTFiOTUwMTk0Zjg2MCIQaW5pdGlhbF91cmkiDS9tYW1taWUvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--41ae001042b16ee26966fc931d11719bc51d7b71
urlString=http://media.ibbt.be/mammie/session/check
rails returned: false
authentication failed!
valid_user=false, redirecting to /RedirectServlet

Logged in:

Rails session id is BAh7CiIJdXNlcm86CVVzZXIHOhZAYXR0cmlidXRlc19jYWNoZXsAOhBAYXR0cmlidXRlc3sdIg5qb2JfdGl0bGUiF1NpdGUgQWRtaW5pc3RyYXRvciIRb2ZmaWNlX3Bob25lMCIPdXBkYXRlZF9hdCIYMjAwOS0xMC0wOCAxMTo1OToxNiIKdGl0bGUiF3NpdGUgYWRtaW5pc3RyYXRvciIYb3JnYW5pc2F0aW9uX3JlZ2lvbjAiDXVzZXJuYW1lIgphZG1pbiIMY291bnRyeSIHQkUiGW9yZ2FuaXNhdGlvbl9hZGRyZXNzMCIHaWQiBjEiHG9yZ2FuaXNhdGlvbl9kZXBhcnRtZW50MCIWb3JnYW5pc2F0aW9uX2NpdHkwIhRhc3Npc3RhbnRfcGhvbmUwIg9maXJzdF9uYW1lIgphZG1pbiITaGFzaGVkX3Bhc3dvcmQiLWI0NzIwODY3MGU2YmU1ODdhNjE1YTcwZDMzZGRkYmVkNmNhMGNiZjAiD29mZmljZV9mYXgwIhFvcmdhbmlzYXRpb24wIg5sYXN0X25hbWUiFnRoZSBhZG1pbmlzdHJhdG9yIhBhZmZpbGlhdGlvbjAiFm9yZ2FuaXNhdGlvbl90eXBlMCIPY3JlYXRlZF9hdCIYMjAwOS0xMC0wOCAxMTo1OToxNiIKZW1haWwiHmthcmVsLmJyYWVja21hbkBnbWFpbC5jb20iEW1vYmlsZV9waG9uZTAiHW9yZ2FuaXNhdGlvbl9wb3N0YWxfY29kZTAiGW9yZ2FuaXNhdGlvbl9jb3VudHJ5MDoPc2Vzc2lvbl9pZCIlMjk4NjQ3Njc2NDdkZTBlNTlhMTExYjk1MDE5NGY4NjA6EF9jc3JmX3Rva2VuIjFVMnhSVlllc3NYVGRTT0Q0dnZBVG95TjVRWkJSa1ZrMUdYdFc1Wkt0ZlBVPSIQaW5pdGlhbF91cmkiDS9tYW1taWUvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--9857ba6780010c041df44eabbfa5f3943ecbe218
urlString=http://media.ibbt.be/mammie/session/check
rails returned: true
authentication successful!

Advertisements

October 20, 2009 at 11:56 am 1 comment

Getting started with Fedora Repository

I recently had to get started with the Fedora Repository. Because the Fedora Commons site is somewhat chaotic, and a quickstart is hard to find online, I’ll write the basic steps in getting a Fedora Repository up and running here. 

fedora_commons

What is it?

First of all, the Fedora Repository has nothing to do with the famous Linux distro (there actually was some dispute over the trademark). Fedora Repository is an open source digital repository management system, originating at the Cornell University in 1998 and open source since 2003. The current release is Fedora 3.2. 

The repository is meant to store (or link to) digital assets (images, video, audio, … anything really) and their related metadata. For example, I am using Fedora as a repository for video files. The video files are available in different formats (high resolution, low resolution flash video, …) and there is an XML file per video describing the video contents. 

This article describes the setup of the repository, the data model Fedora uses, and how to interact with the repository using Java and Ruby.

Installation

First download the latest version of Fedora from their site (go to Developers > Downloads). As mentioned before, the current release is fedora-installer-3.2.jar. When installing you can choose between the quick and the custom installation. Choose the latter, because we want to enable the REST interface. Go to the download location in your terminal and type

java -jar fedora-installer-3.2.jar

to start the installation process. The default options are ok except that you should enable the REST api. More information on the installation is available here.

Fedora comes runs inside a tomcat server. After installation you can start Fedora by going to fedora_home/tomcat/bin and typing in a command line (Linux / Mac)

sh catalina.sh run

or (Windows)

startup.bat

You should see some messages that indicate that tomcat is starting up and that Fedora is being deployed and the final message should say something like “server startup complete”. Now you can fire up your browser and surf to http://localhost:8080/fedora. If everything went well, an ugly page showing some info about Apache Axis.

The Fedora data model

A Fedora object contains several datastreams

A Fedora object contains several datastreams

The image on the right shows a Fedora object. It has a unique ID called the PID (persistent ID) and some other properties. A Fedora object also contains so-called datastreams. These contain the actual data. This data can be the essence (e.g., the video material) or the metadata about this essence (e.g., an XML file with descriptions). 

Fedora has some default datastreams (RELS-EXT, DC and AUDIT), and the user can add as many other datastreams as necessary. So what do these default datastreams contain?

  • The RELS-EXT datastream contains the relationships to other objects in the repository. This can for example contain a relationship “is part of” that states that this object is part of another object (e.g. a collection “news videos”).
  • The DC datastream contains Dublin Core metadata about the object. Dublin Core is a metadatastandard with some basic fields (like title, author etc.), so this stream is a basic description of the object’s contents.
  • The AUDIT datastream contains the history of actions performed on the object.
  • The other datastreams could contain the different versions of a video file (High resolution version, low resolution, audio channels, …). Datastreams can also contain more metadata (e.g., a NewsML XML file).

You can find more information about the datastreams in tutorial 1 on the Fedora site.

Fedora offers a number of cool features, like versioning datastreams (so you can go back to a previous version of a datastream, e.g. when someone messed up the metadata describing a videofile). It is also possible to define transformations of your datastream using webservices. If you have for example a webservice that can convert an image to grayscale, you could couple this to Fedora and it would be like your object had an extra datastream that contained the grayscale version, but actually when this datastream is called a grayscale version would be created on the fly. 

Adding your first objects

The best way to get started with Fedora is using the client administrator program that is included in the installation (fedora_home/client/bin/fedora-admin). 

This is explained in tutorial2 on the Fedora site: tutorial2, so I won’t go into detail. You really should follow this tutorial as it gives a good overview of Fedora’s possibilities. The image below shows a screenshot of the application:

The Fedora Administrator application

The Fedora Administrator application

With the application you can add new objects to Fedora. 

Connecting to Fedora with Ruby

ruby_logo

The Fedora repository exposes two types of interfaces to the outside world: a SOAP API and a REST API. The latter is the simplest and we’ll start with it to demonstrate access from within a Ruby script to Fedora. 

The guys at http://www.yourmediashelf.com/ have created two Ruby gems for communication with Fedora: RubyFedora and ActiveFedora (homepage). RubyFedora is a Ruby wrapper around the Fedora REST interface and is the gem we’ll be using in this paragraph. ActiveFedora tries to provide an ActiveRecord-like experience when using Fedora from Ruby, I haven’t tested this gem yet. 

Start by installing the RubyFedora gem:

gem install ruby-fedora

Use the following Ruby script (fill in your username, e.g., fedoraAdmin, and password in the repository url) to create a new object, save it and find it back:

#!/usr/local/bin/ruby
require 'ruby-fedora'
repository = Fedora::Repository.register('http://user:pass@localhost:8080/fedora')
test_object = Fedora::FedoraObject.new(:label => 'honolulu', :contentModel => 'Image', :state => 'A', :ownerID => 'fedoraAdmin')
repository.save(test_object)
objects = repository.find_objects('label~Image*')
object = repository.fetch_content('demo:1')

(The last line will result in an error if a file with pid equal to demo:1 does not exist)

The following is a more elaborate example that will print some of the object’s fields and will also print some of the fields of the Dublin Core datastream:

#!/usr/local/bin/ruby
require ‘ruby-fedora’
require ‘rexml/document’
#connect to the repository
repository = Fedora::Repository.register(‘http://fedoraAdmin:test@localhost:8080/fedora&#8217;)
#create a new object
test_object = Fedora::FedoraObject.new(:label => ‘blublub’, :contentModel => ‘Video’, :state => ‘A’, :ownerID => ‘fedoraAdmin’)
#save the object
repository.save(test_object)
#find objects with pid video* (e.g., “video:1” / “video:2” / … )
vids = repository.find_objects(‘pid~video*’) 
vids.each { |video|
  #print this item’s fields
  puts video.pid.to_s     + “\n******************\n”
  puts “create_date … ” + video.create_date.to_s      + “\n”
  puts “modified_date … ” + video.modified_date.to_s       + “\n”
  puts “state … ” + video.state.to_s     + “\n”
  puts “label … ” + video.label.to_s     + “\n”
  puts “owner_id … ” + video.owner_id.to_s     + “\n”
#  puts “profile … ” + video.profile.to_s     + “\n”
  
  #extract Dublin Core datastream
  xml_data = video.object_xml
  doc = REXML::Document.new(xml_data)
  root = doc.root
  dc_field = root.elements[“foxml:datastream[@ID=’DC’]/foxml:datastreamVersion/foxml:xmlContent/oai_dc:dc”]
  puts “\n” + dc_field.elements[“dc:identifier”].text + ” => ” + dc_field.elements[“dc:title”].text
}
#!/usr/local/bin/ruby
require 'ruby-fedora'
require 'rexml/document'
#connect to the repository
repository = Fedora::Repository.register('http://fedoraAdmin:test@localhost:8080/fedora')
#create a new object
test_object = Fedora::FedoraObject.new(:label => 'blublub', :contentModel => 'Video', :state => 'A', :ownerID => 'fedoraAdmin')
#save the object
repository.save(test_object)
#find objects with pid video* (e.g., "video:1" / "video:2" / ... )
vids = repository.find_objects('pid~video*') 
vids.each { |video|
  #print this item's fields
  puts video.pid.to_s     + "\n******************\n"
  puts "create_date ... " + video.create_date.to_s      + "\n"
  puts "modified_date ... " + video.modified_date.to_s       + "\n"
  puts "state ... " + video.state.to_s     + "\n"
  puts "label ... " + video.label.to_s     + "\n"
  puts "owner_id ... " + video.owner_id.to_s     + "\n"
  #puts "profile ... " + video.profile.to_s     + "\n"
  #extract Dublin Core datastream
  xml_data = video.object_xml
  doc = REXML::Document.new(xml_data)
  root = doc.root
  dc_field = root.elements["foxml:datastream[@ID='DC']/foxml:datastreamVersion/foxml:xmlContent/oai_dc:dc"]
  puts "\n" + dc_field.elements["dc:identifier"].text + " => " + dc_field.elements["dc:title"].text
}

Connecting to Fedora with Java

296946221_6ef6d4e99b

(Duke image taken from here). The Fedora installation comes with a client demo illustrating some of the things you can do with the SOAP interface. It is located at Fedora_Home\client\demo\soapclient. To create a project in Eclipse with this code, start up Eclipse and add the following libraries to your build path: fedora_home/client/fedora-client-3.1.jar and everything in fedora_home/client/lib/. Add the DemoSOAPClient.java file to your project and use the functions in it in your own code. For example, the following code will add an item to Fedora based from a FOXML file.

 

 

public static void addToFedora(String filename,long theID) {
//FEDORA REPO
DemoSOAPClient caller;
try {
	caller = new DemoSOAPClient("http", "localhost", 8080, "fedoraAdmin", "test");
	//RepositoryInfo repoinfo = caller.describeRepository();
	//delete item if it exists
	String purgeDate=null;
	try {
		purgeDate = caller.purgeObject(
			"id:"+theID, // the object pid
			"purge object", // an optional log message about the change
			 false);  // do not force changes that break ref integrity
	} catch (Exception e) {
		//System.out.println("Hack...just ignore failures since objects may not exist yet." + e.getMessage());
	}

	//add the item to Fedora
	FileInputStream inStream=null;
	String ingestPID=null;
	File ingestFile=new File(filename);
	try {
		inStream=new FileInputStream(ingestFile);
	} catch (IOException ioe) {
		System.out.println("Error on ingest file inputstream: " + ioe.getMessage());
		ioe.printStackTrace();
	}
	System.out.println(" - ingest FoXML in Fedora");
	try {
	        ingestPID = caller.ingest(inStream, fedora.common.Constants.FOXML1_1.uri, "ingest of item");
	} catch (IOException ee1) {
		System.out.println("Error during ingest: "+ee1.getMessage());
		//ee1.printStackTrace();
	}
	//System.out.println("Finished test ingest of sdef object: " + ingestPID);
} catch (Exception e1) {
	// TODO Auto-generated catch block
	e1.printStackTrace();
}
}

That’s it for this Fedora introduction!

May 24, 2009 at 2:34 pm 10 comments

Continuous testing: using Hudson for Maven projects

I experimented a bit with Continuous Integration a while ago. I found some great freely available tools which facilitate the automatic building and testing of (web) applications. In this post I’ll discuss the setup of a system that uses Hudson to automate the build and testing process. I intend to write some follow up posts that digg further into testing a web application using Selenium.

In this post I assume you have already set up a Maven project, and that you use Subversion as version control system (check out my other post if you are unsure about this).

Continue Reading December 27, 2008 at 11:42 pm 5 comments

Using Eclipse for multi-module Maven2 projects (part 3)

In the last post in this series we used the m2eclipse plugin to create a Maven webapplication in Eclipse. In this post we’ll create a multi-module Maven application.

Continue Reading December 23, 2008 at 4:32 pm 3 comments

Using Eclipse for multi-module Maven2 projects (part 2)

In the first post we installed Eclipse and some plugins. Now we will start using the m2eclipse plugin to open and create Maven projects. This post will show how to create a Maven webapplication in Eclipse.

Continue Reading December 23, 2008 at 3:51 pm Leave a comment

Using Eclipse for multi-module Maven2 projects

I have been diving into a lot of Java and Eclipse recently. We’re setting up a Continuous Integration system at work, using Hudson as the engine. Because sometimes things didn’t went as smooth as I would have liked them to go I decided to write some posts about setting up the system. In this first post we’ll be setting up Eclipse with the necessary plugins.

Continue Reading November 1, 2008 at 10:10 am 1 comment


Feeds

Articles to be written…

Twitter – kr3l

my del.icio.us

RSS Google Reader Shared Stuff

  • An error has occurred; the feed is probably down. Try again later.

RSS Listening to..

  • An error has occurred; the feed is probably down. Try again later.