Please start here if you want to connect your service to the SURFconext platform

Setting up Shibboleth

Set up Apache with Shibboleth as described here.

SURFconext Metadata

Take note that the metadata and the metadata locations used for the test and production environments of SURFconext differ. Use them accordingly:

Setting up the Servlet

We start with a basic Servlet:

Create a file WEB-INF/src/surfnet/tutorials/mfsp/MFSP.java with the following content:

package surfnet.tutorials.mfsp;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MFSP extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
    response.setContentType("text/html");

    PrintWriter out = response.getWriter();

    out.println("<html>");
    out.println("<head>");
    out.println("<title>My First SP</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>My First SP</h1>");
    out.println("<p>Hello World!</p>");
    out.println("</body>");
    out.println("</html>");
    out.close();
}

}

and create WEB-INF/web.xml:

<web-app version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<servlet>
		<servlet-name>mfsp</servlet-name>
		<servlet-class>surfnet.tutorials.mfsp.MFSP</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>mfsp</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

Create the WEB-INF/classes directory

Compile the servlet and create a war-file with:

javac -d WEB-INF/classes/ WEB-INF/src/surfnet/tutorials/mfsp/MFSP.java
jar cvf mfsp-java.war *

Don't forget to include servlet-api.jar in your classpath. This library is included in the Tomcat lib directory.  

After deploying the war file into your local Tomcat root, visiting http://localhost:8080/mfsp-java should show the servlet and tell you "Hello World!".

Setup Apache as a Proxy

Next, we are going to setup as a proxy for mfsp instance that is running on Tomcat.

First, make sure Tomcat is configured with an AJP connector. Typically, it should be listening on port 8009, and the following configuration statement should be present (and not commented out) in /etc/tomcat7/server.xml.

<Connector port="8009" protocol="AJP/1.3" tomcatAuthentication="false" redirectPort="8443" />

Then, make sure that the Apache module proxy and proxy_ajp are enabled:

a2enmod proxy
a2enmod proxy_ajp

Add the following directions to your Apache configuration:

ProxyPass /mfsp-proxied ajp://localhost:8009/mfsp-java/

to instruct Apache to map /mfsp-proxied to /mfsp-java at the Tomcat server.  Then check if the Java applet can now be reached through the regular Apache web server at https://mfsp.gadgets.surfconext.nl/mfsp-proxied (substitute your own host name).

If that works, enable Shibboleth authentication for this url by adding the following snippet to you Apache configuration:

ProxyPass /mfsp-proxied ajp://localhost:8009/mfsp-java/
<Location /mfsp-proxied>
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    require valid-user
</Location>

As a result, you should now be required to authenticate before accessing the servlet.

Accessing SAML attributes

Even though simple authentication is now active on your servlet, it is not yet possible to access SAML attributes (such as username, email address, etc) from Java.  

In Apache, the SAML attributes are stored in server variables (see xxx), and the Apache module mod_proxy_ajp supports passing of such server variables to the Java servlet while proxying a page.  However, only variables whose names start with "AJP_" are passed to the servlet.  Therefore, configure the prefix in the Shibboleth configuration by adding a attributeprefix configuration option to the main <ApplicationDefaults> tag:

	<ApplicationDefaults entityID="https://mfsp.gadgets.surfconext.nl/shibboleth"
                             attributePrefix="AJP_"
                             REMOTE_USER="eppn persistent-id targeted-id">

and restart shibd.  

To show the attributes, we adjust the example servlet:

package surfnet.tutorials.mfsp;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MFSP extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
    /*
     * Get the value of form parameter
     */
    //String name = request.getParameter("name");
    //String welcomeMessage = "Welcome "+name;
    /*
     * Set the content type(MIME Type) of the response.
     */
    response.setContentType("text/html");

    PrintWriter out = response.getWriter();
    /*
     * Write the HTML to the response
     */
    out.println("<html>");
    out.println("<head>");
    out.println("<title>My First SP</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>My First SP</h1>");
    out.println("<p>Hello World!</p>");


    /* names of the SAML attributes to display */
    String[] shib_attributes = {
        "persistent-id","Shib-user","Shib-displayName","Shib-surName",
        "Shib-commonName","Shib-givenName","Shib-eduPersonPN",
        "Shib-email","Shib-HomeOrg","Shib-uid",
        "Shib-userStatus","Shib-voName","Shib-memberOf"
    };

    out.println("<h2>SAML attributes</h2>");
    out.println("<table>");
    for (int i=0; i<shib_attributes.length; i++)
    {
        out.print("<tr><td>"+shib_attributes[i]+"</td>");
        out.print("<td>"+request.getAttribute(shib_attributes[i])+"</td></tr>\n");
    }
    out.println("</table>");

    /* also print generic attributes
     * NOTE: this will nog display the SAML attributes, because for some
     * reason these are not included in request.getAttributeNames()
     */
    out.println("<h2>Attributes:</h2>");
    out.println("<table>");
    Enumeration attributes = request.getAttributeNames();
    while ( attributes.hasMoreElements() )
    {
        String attr_name = (String) attributes.nextElement();
        Object attr_val  = request.getAttribute(attr_name);

        out.print("<tr><td>"+attr_name+"</td>");
        out.print("<td>"+attr_val+"</td></tr>\n");
    }
    out.println("</table>");

}

}

Compile and deploy again, and your servlet should show something like this:

That's all folks!

You now have a functional example of a Java servlet connected to SURFconext.  Enjoy!

Any questions and comments are welcome at support@surfconext.nl.