Index by title

Apache SPEP Installation Guide

Authors
Shaun Mangelsdorf

Applicable versions
0.7

Preparing your server

To successfully operate the Apache SPEP your server must be accessible on port 443 from the ESOE system. You can ask your ESOE system administrator for the IP addresses ESOE will connect from if you're running a restrictive firewall policy and update it appropriately. In some circumstances your administrator may allow you to configure port 80 unsecured SPEP instances. This is a per installation decision, on which your ESOE system administrator can advise you.

Minor change required to ESOE
There is a small change required to the ESOE environment to support Apache SPEPs, due to a bug in the Java libraries related to XML signature validation. This change requires that the commons-logging and xmlsec jar files are moved from $TOMCAT/shared/lib to $TOMCAT/common/endorsed.

Upgrading from pre-Beta 1 versions of the Apache SPEP
There has been considerable change to the configuration process, along with the ability to now use Java keystores rather than having to extract the keys into files manually. We recommend that anyone upgrading from a pre-0.4 version rewrite their configuration file from the default provided.

Build Prerequisites:

The source distribution of SPEP consists of 4 gziped tared files:

  1. Extract saml2-{version}.tar.gz spep-{version}.tar.gz spepd-{version}.tar.gz and modspep-{version}.tar.gz to a directory suitable for building. You will need approximately 200mb free space on the filesystem for the build process.
  2. The 4 source trees extracted all have a GNU standard configure script and Makefile. Note that if you have any of the required libraries installed in non-standard locations you will need to provide --with parameters to configure. See ./configure --help for more information.
  3. Build the source by running the configure script in a manner suitable for your system, then running make install to build and install the files.
  4. For the purposes of the rest of this document, we will refer to the prefix of your installation as $prefix. This defaults to /usr/local and is changed by the --prefix parameter to the configure script.

Registering the SPEP with ESOE Manager

Ask your ESOE administrator, or see this page for information if you manage your ESOE instance.

Service configuration

Retrieve your service configuration and keystore from ESOE Manager, or from your ESOE administrator.

This page shows you the configuration values that need to be set up in the spep.conf file, which can be found at $prefix/etc/spep/

You may also need to change the path information in the spep.conf file, if you installed the SPEP to a non-standard location.

For each of the configuration options shown by the ESOE Manager service node configuration page, enter the corresponding value for the current node in its spep.conf file.

It is very important that each node's configuration be correct. There will be some differences between them.

The keystore will be the same for all nodes. We recommend that you save the keystore to the same location as spep.conf and set it to be owned by the user that will run spepd. This keystore does not need to be read by the Apache module, so 0600 permissions are highly recommended.

Running the SPEP Daemon

The command line options for the SPEP daemon are:

spepd options:
  --help                   display this help message
  -f [ --config-file ] arg the spepd configuration file to use
  -l [ --log-file ] arg    file to send log output to
  --debug                  run in debug mode (don't fork to become daemon)
  -v [ --verbose ]         run in verbose mode (display some messages on
                           startup to describe what is happening)

Protecting your web content

After copying modspep.so into your apache modules directory, add the following statement to enable it:

LoadModule spep_module modules/modspep.so

Note the path to the module may differ slightly if your apache installation differs from the default.

Add the following options to the root of your httpd.conf (Outside any Directory/Location sections)
SPEPDaemonPort 7142

The daemon port here should correspond to the value configured in spep.conf earlier. The log file specified here should be a different file to the one that spepd logs to.

As an example, here is the configuration required to protect all web content under /secure
<Location /secure>
    SPEPEnabled On
</Location>

Run the environment

Your environment is now able to be started, we recommend you watch logging closely for the first little while to make sure all configuration is in order. To invoke spep simply browse to the protected web application.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup an SPEP. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Configuring Authorization Policies

Authors
Bradley Beddoes
Andre Zitelli
Shaun Mangelsdorf

Applicable Versions
Beta 2

Overview

The Enterprise Sign On Engine (ESOE) features a powerful authorization engine. ESOE controls which identities may access your enterprises resources. A wide range of identities are supported for authentication purposes. ESOE uses a language based on the XACML 2.0 standard released by OASIS. We've intentionally cut this down and called it Lightweight XACML (LXACML) for the following reasons:

  1. When demonstrating the design to clients many where worried about the complexity of the XACML specification and getting their heads around its concepts. The fact that ESOE would act as the decision point was a weird enough concept on its own. A request was put forward to find a suitable stepping stone.
  2. Our primary target initially was web based resources. This is a high volume environment in many cases which means that asking PDP for every single request was not going to be possible, we needed to cache responses, doing so with the full XACML specification was extremely complex
  3. XACML 3.0 specification was to be ratified shortly.

The core PDP is currently LXACML compliant. However, in the near future, we plan to offer an XACML 3.0 fully compliant sister PDP. This will allow ESOE for access resources where the use of the full XACML spec is warranted and caching is not required due to access volumes.

The design team feels we have struck a pretty good balance in the features that LXACML offers in regards to its bigger brother.

To describe how the PDP works internally you should consult the ESOE Administrators Guide

Lets start with an example...

The following simple policy is a good place to start as an example:
<Policy PolicyId="urn:simpletest">
       <Description>Simple Test Policy. 1 Rule. 1 Resource in 1 target.</Description>
      <Target>
        <Resources>
          <Resource>
            <AttributeValue>/default/.*</AttributeValue>
          </Resource>
        </Resources>
      </Target>
      <Rule Effect="Permit" RuleId="1">
        <Description>Simple test Rule. Permit all at default target.</Description>
      </Rule>
    </Policy>

The above rule defines the policy target resource /default/.* and one Rule. As the Rule does not define any target resources, the policy target resource will be applied to it when processing authorization requests. The Rule has no conditions, and the effect of the rule is PERMIT.

If a request is made for http://myservice.company.com/default/index.html, it will be matched against the policy resource target regular expression and the effect of the rule will be applied, resulting in the authorization processor returning PERMIT.

If any resource that does not start with /default is requested, it will fail to match any target resources and the default decision will be returned.

Components of a Policy

A Policy is made up of the following components

By combining these powerful results can be achieved. A single policy can have an unlimited number of Rule elements, which, in turn, can have multiple boolean operators applied. Multiple policies also can be applied to a single service. Where this is the case, the combining algorithm used is such that all targets in all policies that match a resource request will be evaluated.

Available comparators

The following are able to be supplied to the <Apply> element as values for FunctionId

The default service policy

When a new service is created it has a policy associated with it by default as shown below:
<?xml version="1.0" encoding="UTF-16"?>
<Policy PolicyId="spep-0" 
    xmlns="http://www.qut.com/middleware/lxacmlSchema">
    <Description>
        First service policy, applies to all resources of the service -
        Please change this description
    </Description>
    <Target>
        <Resources>
            <Resource>
                <AttributeValue>.*</AttributeValue>
            </Resource>
        </Resources>
    </Target>
    <Rule Effect="Deny" RuleId="spep-rule-0">
        <Description>
            This rule causes all resource to be denied by default
        </Description>
    </Rule>
</Policy>

This means that every request to access the service will be denied . You need to extend the policy to support your particular applications.

Important points about Policy writing

  1. Each value for the PolicyId attribute across your service must be unique
  2. Each value for the RuleId attribute across your service must be unique
  3. For the Effect of a rule to be applied the Condition element must resolve to true (or not exist for that rule)
  4. Check out our Policy Templates for policy snippets you can simply copy and paste to get going quickly

Finally, ESOE policy is very powerful and flexible. You are given more than enough rope to hang yourself. For example, if OpenID and/or Shibboleth integration are enabled, you need to be very careful which resources you allow external users access to. Consider carefully what your enterprise requires and the potential risks involved. Make sure your policy is correct. If you are not sure, get your ESOE system administrator to validate your policies for you. THINK HARD ABOUT YOUR ENTERPRISE'S POLICY! TEST, TEST, TEST!

More example policies

Probably the best way to teach the syntax is through a variety of examples please review the below and ask questions if you need help with understanding.

Example 1

<Policy PolicyId="urn:policy:complexity:1">
      <Description>A complex policy with multiple rules and conditions. All permit rules must be recorded in the response.</Description>
      <Target>
        <Resources>
          <Resource>
            <AttributeValue>/default/.*</AttributeValue>
          </Resource>
          <Resource>
            <AttributeValue>.*/other/.*</AttributeValue>
          </Resource>
          <Resource>
            <AttributeValue>[A-Z]*/regex/\d*/[y]{2}.*</AttributeValue>
          </Resource>
        </Resources>
      </Target>
      <Rule Effect="Permit" RuleId="complexity:1-1">
        <Description>Permit access to any resources matched for this policy if the 'username' attribute contains a z</Description>
        <Condition>
          <Apply FunctionId="string-regex-match">
                  <SubjectAttributeDesignator AttributeId="username" />
                  <AttributeValue>.*z.*</AttributeValue>
          </Apply>
        </Condition>
      </Rule>
       <Rule Effect="Permit" RuleId="complexity:1-1a">
        <Description>Permit access to these resources if the 'username' attribute is equal to zitelli</Description>
        <Target>
            <Resources>
                      <Resource>
                          <AttributeValue>/default/-i.*</AttributeValue>
                      </Resource>
                      <Resource>
                          <AttributeValue>/other/not/so/public.*</AttributeValue>
                      </Resource>
              </Resources>
        </Target>
        <Condition>
          <Apply FunctionId="string-equal">
                  <SubjectAttributeDesignator AttributeId="username" />
                  <Apply FunctionId="string-normalize-to-lower-case" />
                  <AttributeValue>zitelli</AttributeValue>
          </Apply>
        </Condition>
      </Rule>
      <Rule Effect="Deny" RuleId="complexity:1-2">
          <Description>DENY everyone access to following resources</Description>
          <Target>
              <Resources>
                  <Resource>
                      <AttributeValue>/default/private/.*</AttributeValue>
                  </Resource>
                  <Resource>
                      <AttributeValue>/other/secret/.*</AttributeValue>
                  </Resource>
              </Resources>
          </Target>
      </Rule>
      <Rule Effect="Deny" RuleId="complexity:1-3">
          <Description>No subject attribute designator = Invalid Rule. Any matches on these targets will
           result in a deny being returned by the PDP.</Description>
          <Target>
              <Resources>
                  <Resource>
                      <AttributeValue>/other/test/brokenrule.jsp</AttributeValue>
                  </Resource>
              </Resources>
          </Target>
          <Condition>
          <Apply FunctionId="string-regex-match">
                  <AttributeValue>.*z.*</AttributeValue>
          </Apply>
        </Condition>
      </Rule>
    </Policy>

Example 2

<!--  all rules in this policy must apply to default target. Not a good example of usage but good for testing -->
    <Policy PolicyId="urn:qut:policy:complex:4">
        <Description>Description</Description>
        <Target>
            <Resources>
                <Resource>
                    <AttributeValue>/default/private/.*</AttributeValue>
                </Resource>
                <Resource>
                    <AttributeValue>
                        /default/something/hello.jsp
                    </AttributeValue>
                </Resource>
                <Resource>
                    <AttributeValue>/painful/.*</AttributeValue>
                </Resource>
            </Resources>
        </Target>
        <Rule Effect="Permit" RuleId="complexity:4-5g4">
            <Description>Description</Description>
            <Condition>
                <Apply FunctionId="string-regex-match">
                    <SubjectAttributeDesignator AttributeId="username" />
                    <AttributeValue>smith</AttributeValue>
                    <AttributeValue>.*zitelli.*</AttributeValue>
                </Apply>
            </Condition>
        </Rule>
        <Rule Effect="Permit" RuleId="complexity:4-64">
            <Description>Description</Description>
        </Rule>
        <Rule Effect="Permit" RuleId="complexity:4-cond:1">
            <Description>Complex conditions</Description>
            <!--  any users who email attribute contains the regex -->
            <Condition>
                <!--  all 3 apply elements must evaluate to false. A fairly useless condition though.-->
                <Apply FunctionId="not">
                    <Apply FunctionId="string-regex-match">
                        <SubjectAttributeDesignator
                            AttributeId="username" />
                        <AttributeValue>zffitelli</AttributeValue>
                    </Apply>
                    <Apply FunctionId="string-regex-match">
                        <SubjectAttributeDesignator AttributeId="email" />
                        <AttributeValue>.*s4ghh.*</AttributeValue>
                    </Apply>
                    <Apply FunctionId="string-regex-match">
                        <SubjectAttributeDesignator AttributeId="type" />
                        <AttributeValue>test</AttributeValue>
                    </Apply>
                </Apply>
            </Condition>
        </Rule>
        <Rule Effect="Permit" RuleId="complexity:4-cond:OUCH">
            <Description>
                Complex conditions. This condition reads as: ( username
                = beddoes and email contains beddoes AND type !=
                part-time-staff or student) OR (username = zitelli and
                email contains zitelli AND type != part-time-staff or
                student)
            </Description>
            <Target>
                <Resources>
                    <Resource>
                        <AttributeValue>
                            /painful/new/complex/rule.target
                        </AttributeValue>
                    </Resource>
                </Resources>
            </Target>
            <Condition>
                <Apply FunctionId="or">
                    <Apply FunctionId="and">
                        <Apply FunctionId="and">
                            <Apply FunctionId="string-equal">
                                <SubjectAttributeDesignator
                                    AttributeId="username" />
                                <AttributeValue>beddoes</AttributeValue>
                            </Apply>
                            <Apply FunctionId="string-regex-match">
                                <SubjectAttributeDesignator AttributeId="email" />
                                <AttributeValue>.*eddoes.*</AttributeValue>
                            </Apply>
                        </Apply>
                        <Apply FunctionId="not">
                            <Apply FunctionId="string-equal">
                                <SubjectAttributeDesignator
                                    AttributeId="type" />
                                <AttributeValue>part-time-staff</AttributeValue>
                            </Apply>
                            <Apply FunctionId="string-equal">
                                <SubjectAttributeDesignator
                                    AttributeId="type" />
                                <AttributeValue>student</AttributeValue>
                            </Apply>
                        </Apply>
                    </Apply>
                    <Apply FunctionId="and">
                        <Apply FunctionId="and">
                            <Apply FunctionId="string-equal">
                                <SubjectAttributeDesignator
                                    AttributeId="username" />
                                <AttributeValue>zitelli</AttributeValue>
                            </Apply>
                            <Apply FunctionId="string-regex-match">
                                <SubjectAttributeDesignator
                                    AttributeId="email" />
                                <AttributeValue>.*zitelli.*</AttributeValue>
                            </Apply>
                        </Apply>
                        <Apply FunctionId="or">
                            <Apply FunctionId="string-equal">
                                <SubjectAttributeDesignator AttributeId="type" />
                                <AttributeValue>part-time-staff</AttributeValue>
                                <Apply FunctionId="string-normalize-to-lower-case" />
                            </Apply>
                            <Apply FunctionId="string-regex-match">
                                <SubjectAttributeDesignator
                                    AttributeId="type" />
                                <AttributeValue>student</AttributeValue>
                                <Apply FunctionId="string-normalize-to-lower-case" />
                                <Apply FunctionId="string-normalize-space" />
                            </Apply>
                        </Apply>
                    </Apply>
                </Apply>
            </Condition>
        </Rule>
    </Policy>

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike create detailed authorization policies. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Configuring build environment for Java

Authors
Bradley Beddoes

Applicable versions
All in development versions

Applicable Environment
All platforms

Please note: This document has not yet been updated after the move to Git version control.

Generic requirements

All Java code in the ESOE project is setup under a specially defined build environment which relies on flexible and powerful open source tools. We don't like what we consider to be the restrictive environments of some Java build 'standards' available today. We're so happy with what we've achieved infact we plan to launch our own standard for others to follow (should they wish to!) in the next few months.

This process attempts to create very generic build environments on multiple platforms with minimal setup time. We move machines quite a bit, these tools allow us to work anywhere.

JDK

The minimum supported JDK for the project is JDK 5 in some special circumstances (such as the Active Directory Authenticator) we require JDK 6, we recommend you install and have this operational before proceeding on your development platform of choice, see http://java.sun.com for downloads and documentation.

Eclipse Europa

The development team currently uses Eclipse Europa 3.3, previous to this release development was undertaken in Eclipse 3.2. Instructions on downloading and configuring eclipse are available at http://www.eclipse.org NB: When using eclipse your ANT_HOME directory is ECLIPSE_HOME/plugins/org.apache.ant_1.7.0.v200706080842 so in my particular case
/home/beddoes/development/eclipse/plugins/org.apache.ant_1.7.0.v200706080842

You are of course welcome to use other editors such as Netbeans or even plain old vi. If using these environment we leave configuration details upto your individual situation

Eclipse Subversion Connector

In order to resolve the ESOE project and code from Subversion you need to install the Subversion connector for Eclipse. We use and recommend Subclipse. You can get installation details and update site URL's from http://subclipse.tigris.org/

Apache Ant

Ant is how we manage our build environment, we recommend Ant 1.7.0 or greater, users of Eclipse Europa (3.3+) have this installed by default. Instructions on configuring Ant and downloads are available at http://ant.apache.org, note we refer to ANT_HOME in this document, this is the root installation point of your ant deployment eg /usr/share/ant.

Apache Ivy

Ivy is our artifact resolution tool of choice, in short that means it automatically assembles all the dependencies required to build ESOE components. At the present time Ivy is incubating at Apache and downloads are available from http://incubator.apache.org/ivy/ Version 2.0.0 Alpha 1 or higher are recommended. To install simply download the zip file, extract on your development system and copy ivy-x.y.z.jar and ivy-core-x.y.z to ANT_HOME/lib

Eclipse users: Eclipse does not automatically pickup jars added to ANT_HOME. To add the jars to your environment select Window -> Preferences -> Ant -> Runtime. Highlight "Ant Home Entries" and click the 'add external jars' button. You should then navigate to the location of the Ivy jars extracted about and add them to eclipse.

The error message associated with not adding jars correctly to eclipse is:
Problem: failed to create task or type antlib:-Org.apache.ivy.ant:configure

Cause: The name is undefined.

Checkout Projects

Our Subversion layout is slightly different to other projects, while we still use the standard trunk, branches and tags approach we believe that the trunk should always have the latest STABLE features, our trunk will never be broken for compiles and testing, it will also never be a specific version. Like other projects if your wanting to get the code at 0.3 then you need to checkout the 0.3 tag. We use a special branch called "development" to do our latest development hacking and committing to. It may very well be broken at any point in time. (Though we try to avoid this as well with personal development branches as much as is practical).

So if your looking to add features checkout the projects under /esoe/branches/development/* in our SVN server. Bug fixes should be made against the Tag in which the bug appeared and if necessary (usually it will be) also merged to the development branch.

Dependencies

We have an automated development environment dependency resolution process using the Ivy files we have provided and the intient.com Ivy repository. To resolve dependencies you must first checkout the projects your interested in and load them in your Ant environment inside Eclipse. Executing the target "dev-resolve" on each project will then connect to the internet (ensure your system has an active connection) and retrieve all dependencies for you automatically. It will also create a HTML file for you listing what was obtained.

NB: If your doing this for the first time in Eclipse you may need to refresh the project (F5) to get the library resolver to pickup the new jars on the project path.

Develop!

Your now ready to develop Java code for the ESOE across its many varied projects. Some projects will have more specific development documentation added for them, these documents are on the ESOE Developers page. All projects however use the same standard format, understand one of them and you can move freely between them all.

We welcome feedback and additions for this document.


Downloads

ESOE Core Downloads

Binary releases of ESOE are not currently provided. The ESOE Project can be built from the sources at http://github.com/esoeproject/esoeproject

The following example build steps assume that ant is on your path, and has Ivy configured.

~$ export ESOE_BUILD_ARGS="-Desoe.version=0.9.5 -Desoebuild=/path/to/esoeproject/esoebuild" 
~$ cd /path/to/esoeproject/esoebuild
esoeproject/esoebuild$ ant $ESOE_BUILD_ARGS -f esoe-dev-setup.xml build
esoeproject/esoebuild$ cd ../esoecore
esoeproject/esoecore$ ant $ESOE_BUILD_ARGS resolve:all release

Other projects are built similarly to esoecore.

SPEP Downloads

Integrate web applications with the ESOE.

SPEP Downloads are available from the Files page.


ESOE Administrators Guide

Authors
Bradley Beddoes
Andre Zitelli
Shaun Mangelsdorf

Applicable Versions
Beta 2

Overview

Welcome to this Administrators guide to the Enterprise Sign On Engine (ESOE), we hope you'll find it an invaluable resource for configuring and managing your own deployments of this software.

The ESOE is built on the Java language and platform which provides a wealth of functionality to aid the implementation of what is a very complex set of requirements. Alongside the base platform are many open source projects including Spring, Apache XML Security, Apache Axis 2, JAXB, iBatis and others. Each of these projects lead the field in their particular areas of expertise which is why they have been selected and we thank the many developers on these projects for their excellent contributions.

Additionally the ESOE itself is open source and released under the Apache 2.0 license, so once you've become more familiar with the system we invite you to check out the developers section to customize for your own needs.

The Enterprise Sign On Engine (ESOE) is an advanced system which combines into a standards compliant solution identity management, single sign on to the web tier and deployment of advanced, centralized authorization policies to restrict access to content in a flexible and extensible manner.

In addition to these features the ESOE provides native understanding of many user centric and federated authentication solutions such as OpenID and Shibboleth. This allows enterprise to easily connect into the possibilities which these collaborative technologies bring without risking security or requiring modification to their internal systems. As future solutions come on board (for example Yahoo BBAuth) the ESOE is easily extensible to provide support for them allowing single point of implementation to automatically populate to all your applications.

The ESOE is designed around the OASIS SAML 2.0 specification and it's powerful authorization engine is built around a reduced version of the OASIS XACML 2.0 standard which is dubbed Lightweight eXtensible Authorization Control Markup Language or "LXACML".

With its ability to integrate identity from unlimited data repositories, automatically create sessions for users whom are logged into Windows Active Directory (actual true single sign on!), release only approved attributes about users to potentially untrusted applications and provide centralized, audit able authorization we believe that the ESOE presents an excellent choice amongst the varied SSO systems available today, commercially or otherwise.

Usage Scenarios

We'll discuss two usage scenarios here, there are many more possibilities however and we'd like to know how your using the system in ways which we may not have even thought of for inclusion here.

Scenario 1

The Queensland University of Technology has an in house developed system that web applications use, it provides a very basic form of single sign on, but always requires at least one entry of Username and Password from the principal. This system generates a cookie which is stored across the entire .qut.edu.au domain and presented to various applications which run some special code again developed in house for Java and Apache. Applications are managed by local service providers who are not necessarily experts in web server technology. These applications read that cookie do some basic cryptography and make LDAP connections to validate information and retrieve attributes about users. Each application requires much complex configuration, a unique LDAP account requiring contact with ITS and a turn around time of a few days. Authorization is adhoc and done locally from local on disk configuration files which have again an inhouse developed syntax, to provide assistance. No one knows what versions of software are running for any given service, who is the technical administrator of the service, or indeed what services are even using this solution. To provide assistance to administrators local accounts are required on hosts, sometimes requiring fire wall changes which can take a long time to become approved due to security approval processes. Finally the University is wanting to push all these great applications to federated users, some using shibboleth, some using openID, others still looking at Yahoo BB Auth, naturally with the IT security team screaming about all of this not being secure.

How the ESOE solution addresses these issues:

Scenario 2

As an online service provider I have many nodes which load balance requests for content, each of which the user must have a valid login to access. With much hype in the identity arena we are under increased pressure to support multiple methods to allow our paying customers to sign in, without forcing them to create and manage local accounts. The issue is everyone wants something different, OpenID for business, Shibboleth for higher education even direct connections to one customers LDAP server. The problem is we can't support all these technologies in the backend we'd have to deploy service providers for each type of authentication we want to support.

  1. The ESOE is designed to solve this issue with ease, in this particular case there are no internal authentication methods as their are no local users, which is more then fine.
  2. Shibboleth, OpenID etc are already supported in dedicated authentication delegators by the ESOE, the backend nodes would only need to understand the service provider enforcement point (SPEP) applicable to their technology set (Java/Apache/IIS) and this problem is solved.
  3. Additional authentication delegators are easy to write, if you choose to support connections directly to a customers LDAP server (or database or Web Services engine or even a flat text file) you could easily write this functionality, of course releasing it to the community for the good of others :).
  4. You may choose to then take advantage of the power of our authorization engine or leave this for a future software revision and continue using an in house developed solution, the option is yours.
  5. Load balancing across nodes is no problem at this point so long as its configured to always send the user requests to the same backend node. In the future our planned ESOE and SPEP cluster support will make this easier still.

Description of core components

Below we will describe in overview terms what each major component of the ESOE does. More in depth technical specifications and implementation details are located in the developers guide.

Authentication Processor

The authentication processor is designed to process all events which an individual deployment of the ESOE considers to be part of authentication. In most instances this will simply include the act of principal identification via some means supported by one of the base handlers documented below.

Handlers are configured in a pipleline which the authentication processor executes one by one. Handlers may choose to take some action or simply pass the request on down the line not invoking any logic, this may be the case when for example the principal is accessing the ESOE from outside the enterprise or if they are not running an Active Directory connected Windows host. Handlers themselves are grouped as Principal Identifiers and Non Principal Identifiers. Each group has upto four subclasses of handler which specify what rules the handler adheres to.

Once a successful authentication has taken place the authentication processor will create a unique session identifier to be stored in the principals browser as cookie value which is a 32 byte randomly generated hex encoded value with greater then 2 ^ -320 chance of being duplicated. It then asks the session processor to create a session for the principal.

Once all this is completed the principal is redirected back to the original content which they came from, or if they access then authentication system directly an administrator configured welcome page.

Base Handlers

Username/Password form input authentication

The Username/Password Handler allows a principal to submit their username and password to a web form to identify themselves to the system, this is the most popular of methods currently in use today but the least secure and most intrusive.

This handler is of type Non Automated, Non Passive and Catch All. This means that it should be configured as the last handler in the pipeline to be capable of performing principal identification, of course other handlers which rely on the principal to be identified may still be configured after this.

If this handler detects that the principal is already successfully authenticated by an earlier stage of the pipeline it performs no operation and returns control to the authentication processor.

Automated Windows authentication

The Windows authentication handler processes special tickets which are generated by an Active Directory enabled Windows host that are created when the user logs in to Windows. Successful validation of these tickets against an AD domain controller will result in the principal identification being successfully established. Failure to do so will cause the handler to return control to the authentication processor.

This handler is of type Automated, Passive. This means it can be configured anywhere in the pipeline before a catch all handler.

If this handler detects that the principal is already successfully authenticated by an earlier stage of the pipeline it performs no operation and returns control to the authentication processor, it will also return control if it determines the principal is not a member of Active Directory.

Single Sign On Processor for Services

The single sign on processor for services handles principal requests for access to each service's SPEP that is deployed. These services may be wiki's, portals, blogs, static web pages infact anything that the principal may choose to interact with using a standard web browser. As the principal navigates to a new service the SPEP generates a SAML 2.0 compliant request and transfers this to the ESOE for validation by one of the supported profiles for principal to service identification. The supported profiles are listed below, it is envisaged this list will grow over time to fulfill more of the options in the SAML 2.0 specification.

Once this processor has received the request it will process it internally using the previously generated session data from the authentication processor and using the same profile as for the request returns an assertion decreeing that the principal should be or should not be granted a session on that service, along with some other important information, including a private ESOE and SPEP identifier that represents the principal. This identifier is once again unique from any identifier the principal ever sees in a session cookie.

Generally it would be expected that a principal would navigate to a service before having been identified by the authentication processor. If this is the case the single sign on processor for services will redirect the principal to the authentication processor for identification, upon successful completion of which they will be transfered back to the single sign on processor for services. The process documented above then continues as normal.

HTTP-POST profile

This is the default profile for ESOE and its SPEP software connectors.

When the user first vists SPEP protected content a SAML request is issued and stored in the response from the SPEP to the clients browser. This is then posted to the ESOE which uses it to undertake SSO processing. The ESOE likewise response with a SAML document to the clients browser. This is the posted to the SPEP which uses it to establish a session with the local service and redirect the user to the original content. (of course it may also cause a session to be denied).

HTTP-GET Profile

This is an optional profile for the ESOE.

When the user first connects to a remote service that service will generate a query string bound for the ESOE per SAML specification. The users browser is then issued a HTTP 302 redirect and sends a standard get request to the ESOE containing the created query string. In most circumstances the ESOE will respond to HTTP-GET with a HTTP-POST profile response (per SAML specification) due to the size of data being returned.

Single Logout Processor

The single logout processor handles logout for all services connected to the ESOE which a user has visited during their session. Once the user navigates to the ESOE logout page web service calls are made in the backend to each service to terminate local sessions for the user. This is different to the way you may be experienced with logout working in that there is no browser redirect to each service. Infact cookies for each service are actually retained with this process. The key is if the client does infact attempt to visit a service again after logout the SPEP will at that time void their cookies along with any application specific cookies that the service owner may wish to terminate, for example a cookie which sets an internal ID.

Principal Session Processor

The principal session processor is responsible for tracking all data about a user while they have an active session established with the ESOE and supporting SPEP's. It creates user sessions, updates them and removes them on logout or session timeout.

Part of its job is to map on the ESOE side the transient identifiers which change each session that are communicated to SPEP's with the real local identifiers of that user. The other important piece of work it does is to track user identifiers. In the case of remote login via an authentication delegator this information is communicated directly into the processor. For users who authenticate locally the processor is responsible for aggregating identity details to provide to SPEP's

Disparate identity source integrator

At startup the ESOE is configured with a number of identity resolvers, by default it is configured with an LDAP source but you may add any source you deem necessary with plugins. Using ESOE Manager administrators can configure with pieces of identity they wish to get from each backend system. Where identity attributes exist in multiple systems possibly under multiple names these can all be aggregated by the ESOE and presented in a clean unified namespace to SPEP's.

In this way your backend identity infrastructure can now be protected from applications in client space. This allows you to safely and easily perform backend changes while only needing to modify the configuration of the ESOE. If applications need some additional data you can configure it centrally and have it delivered to them easier then ever before.

Attribute Authority Processor

To use the above attribute data SPEP software will make a web service call to the ESOE when a user establishes a session to retrieve attribute data. Based on configured policies set by administrators the ESOE will then release attributes to the SPEP. This means that sensitive data will never be delivered to your wiki software for example while your finance system which is more trusted is able to utilize it.

Authorization Processor

The authorization processor is responsible for processing authorization policies for protected resources accessed by authenticated users and returning a decision based on the outcome of the policy evaluation. The processor will attempt to match resources against the set of policies defined for a given SPEP, returning the authorization value specified by the policy. If no policy rules can be matched against the requested resource, a default decision is returned. This default decision is configured in the ESOE global configuration parameter:

esoe.config

# Default authorization action
authorizationDefaultMode=mode

Where mode can ONLY be one of ALLOW or DENY

Authorization process

When a resource protected by an SPEP is requested, the SPEP will send a SAML 2.0 extension called a LXACML request to the authorization processor via a backend web service call. It will supply the users transient identifier so the authenticated user can be identified by the PDP. It also provides details on the resource being accessed in the form of a string.

The authorization processor will first attempt to retrieve the policy set associated with the requesting SPEP, using the supplied SPEP identifier. If no policies can be found for that SPEP, DENY is returned. This overrides any default authorization policy set in the ESOE global config. NOTE: The processor will retrieve said policy set from it's policy cache. The cache is updated from the central data store at regular intervals specified in the configuration parameter:

# Time in seconds to attempt to refresh updated policies from data repository
authorizationPollInterval=120

This being the case, policy changes made via the esoemanager web interface may take up to 'interval time' to be updated in the policy cache.

Next, the authorization processor will attempt to match the requested resource against the the targets specified in the authorization policy associated with the requesting SPEP. If a match is found the authorization processor will evaluate the rule that matched the requested resource. If no target match is found for the requested resource, the default authorization decision is returned.

We recommend that administrators read the document [Configuring Authorization Policies] to learn how to build LXACML policy documents. This is also useful reading for your service administrators.

While this document refers to resources primarily in terms of web level resources the PDP itself is actually generic. In the near future some powerful examples of using the PDP right down in internals of applications to control function access, database row access etc will be made available.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new ESOE administrators to come online. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE Attribute Authority Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Attribute Authority Processor

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.aa.impl.\*
Type AttributeAuthorityProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.aa.AttributeAuthorityProcessor
Exceptions InvalidRequestException, InvalidPrincipalException

Verify the supplied value of [com.qut.middleware.esoe.aa.bean.AAProcessorData.requestDocument|#Verifying Requests]. Any invalid request MUST set com.qut.middleware.esoe.aa.bean.AAProcessorData.responseDocument to a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Requestor. No AttributeStatement is generated for this failure case and no further processing should be undertaken except to create and throw com.qut.middleware.esoe.aa.exception.InvalidRequestException

The value of <Issuer> should be retrieved and stored at com.qut.middleware.esoe.aa.bean.AAProcessorData.descriptorID.

The value of <Subject> should be determined and stored against com.qut.middleware.esoe.aa.bean.AAProcessorData.subjectID.

The subjectID SHOULD be used with the the [[com.qut.middleware.esoe.sessions.Query.querySAMLSession]|[#Query]] query component to retrieve a com.qut.middleware.esoe.sessions.Principal. If the request throws an exception this should be caught. It MUST be considered a failure, the AAP MUST set com.qut.middleware.esoe.aa.bean.AAProcessorData.responseDocument to a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Authn. No AttributeStatement is generated for this failure case and no further processing should be undertaken except to create and throw com.qut.middleware.esoe.aa.exception.InvalidRequestException

Once the principal object is successfully retrieved the processor should evaluate com.qut.middleware.esoe.sessions.bean.IdentityData.attributes. At the present time the processing model here is fairly simple. In the future the Attribute Authority may be extended to support privacy for users and perhaps an extensible pipeline architecture for responding with attributes. Addtionally the aatribute authority does not currently impose the SAML spec limitations correctly especially relating to only returning equal values for <AttributeValues> which are specified and only returning <Attributes> which are specified. This functionality will also be added later, for now all SPEP get all attribute details.

The attribute authority currently only supports the basic attribute profile.

For each key stored in com.qut.middleware.esoe.sessions.bean.IdentityData.attributes a check should be made to ensure the vector located in the associated com.qut.middleware.esoe.sessions.bean.IdentityAttribute.values has at least one element. If this is the case <saml:Attribute> should be created. NameFormat SHOULD always be set to urn:oasis:names:tc:SAML:2.0:attrname-format:basic. Name SHOULD be set to the current key. An <saml:AttributeValue> should now be created, for each value stored in the vector. type for this element MUST be set to the matching XML type for the corresponding value of com.qut.middleware.esoe.sessions.bean.IdentityAttribute.type (ie For 'string' type="xs:string").

Where no attributes exist an empty AttributeStatement should be returned.

An AttributeStatement MUST now be created.

Once complete the value com.qut.middleware.esoe.aa.AttributeAuthorityProcessor.result.Successful MUST be returned

Creating AttributeStatement

Once all the <saml:Attribute> elements have been created for the specified com.qut.middleware.esoe.sessions.Principal an <AttributeStatement> MUST be created and embed all the generated values for <saml:Attribute>

SAML Wrappers

An [[assertion]|[SAML Document Descriptors#Generating Assertions]] MUST be created and the <AttributeStatement>. embedded inside.

A base [[response]|[SAML Document Descriptors#Generating Responses]] MUST be created with <Status> information set as detailed by the request processing, it should contain the generated <Assertion>.

Once successfully created the response should be stored at com.qut.middleware.esoe.aa.bean.AAProcessorData.responseDocument.


ESOE Authentication Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Authn Servlet

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.authn.servlet.*
Type AuthnServlet

The Authn Servlet is a control point for initial principal authentication and identification. The servlet must conform to the Servlet 2.4 specification http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html, this servlet currently only supports standards compliant web browser user-agents.

This servlet MUST be of the type com.qut.middleware.esoe.authn.servlet.AuthnServlet

The servlet will be used for all requests made to https://esoe.url/logon, and utilises a cookie with a deployment configured name to determine if user-agent to web teir SSO should be enabled.

For each request that enters the servlet an object of type javax.servlet.ServletRequest is supplied by the container. This is to be stored as the value of httpRequest in a session bean implementing com.qut.middleware.esoe.authn.bean.AuthnProcessorData. An object of type javax.servlet.http.HttpServletResponse is supplied by the container. This is also to be stored as the value of httpResponse in the bean. If the SSO cookie is present and carrying a string value of true (case insensitive) then the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.automatedSSO MUST be set to false, otherwise it MUST be set to true. Finally the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.redirectTarget must be set to that specified by the name vale pair of esoeTarget, if this is not sent in the request and the value is currently null the configured default must be set.

Once the bean is fully populated the Authn Servlet MUST call the execute function on the AuthnProcessor and submit the bean as an argument.

Handled return values and actions

com.qut.middleware.esoe.authn.AuthnProcessor.result.Completed

When this success state is encountered the servlet MUST perform the following actions:

  1. The value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.redirectTarget MUST be passed to HttpServletRequest sendRedirect
  2. Should the above value be null or not exist the configured default authn completed page MUST be retieved and passed to HttpServletRequest sendRedirect

com.qut.middleware.esoe.AuthnProcessor.result.Failure

When recieving this return value the authn servlet SHOULD interrogate the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL and MUST advise the user-agent to redirect to this location, no further changes to session state should occur.

Handled exceptions and actions

com.qut.middleware.esoe.AuthnProcessor.result.AuthnFailure

When recieving this exception the servlet SHOULD redirect the user-agent to the configured location for http 500 errors for this servlet.

Authn Processor

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.authn.impl.\*
Type AuthnProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.authn.AuthnProcessor
Exceptions HandlerRegistrationException, AuthnFailureException

The authn processor is primarily concerned with utlisation of the authn handler pipeline. using Spring 2.0 and its IoC functionality many unique handlers are registed with the system to handle the supported methods for achieving authn with the principal. Each of these MUST implement the com.qut.middleware.esoe.authn.pipeline.Handler interface. Handlers are stored in the AuthnProcessor variable, registeredHandlers.

On initialisation the authn processor MUST verify that at least one handler has been registered, failure to have at least one handler registered MUST result in the exception com.qut.middleware.esoe.authn.AuthnProcessor.HandlerRegistrationException.

Handlers are registered in a list data structure. For every authn attempt the authn processor SHOULD traverse the entire list. Handlers may interrupt this process to perform some function, the AuthnProcessor MUST pickup where it left off when it has control handed back to it. For each handler the execute function should be called. The com.qut.middleware.esoe.authn.bean.AuthnProcessorData bean MUST be supplied to this interface. Handlers MAY add detail to this data structure but they MUST not remove any data from it. For each handler which is called the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.currentHandler must be set to value of com.qut.middleware.esoe.authn.pipeline.Handler.handlerName.

On creation of the AuthnProcessor the values of sessionDomain and sessionTokenIdentifier must be set via injection to the domain in which the session identifying cookie should live and the name the session identifying cookie should be given.

Handled return values and actions

com.qut.middleware.esoe.authn.pipeline.Handler.result.Successful

For each response of AuthnSuccessful the AuthnProcessor MUST evaluate if the value com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn is true, if not it should be set to true. It should then determine if any handlers remain to be evaluated in the registeredHandlers list. If they do the next handler's execute method MUST be called, additionally the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.currentHandler MUST be set to value of com.qut.middleware.esoe.authn.pipeline.Handler.handlerName.

If no further handlers are present evaluation of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn MUST occur. If this boolean is true then the the com.qut.middleware.esoe.authn.AuthnProcessorData.sessionID value should be set in a javax.servlet.Cookie with scope as the configured value for sessionDomain and name set to the value of sessionTokenName. The cookie MUST be stored in the response by calling the methods supplied in com.qut.middleware.esoe.authn.bean.AuthnProcessorData.httpResponse

AuthnProcessor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.Successful.

If the boolean is not true then no handler has been able to identify the principal (will only occur when a catch-all handler is NOT deployed). The configured url for redirecting users to for this fault MUST be set as the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL, the AuthnProcessor MUST populate and throw com.qut.middleware.esoe.authn.AuthnFailure

com.qut.middleware.esoe.authn.pipeline.Handler.result.SuccessfulNonPrincipal

For each response of SuccessfulNonPrincipal the AuthnProcessor must evaluate if any handlers remain to be evaluated in the registeredHandlers list. If they do the next handler's execute method MUST be called, additionally the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.currentHandler must be set to value of com.qut.middleware.esoe.authn.pipeline.Handler.handlerName.

If no further handlers are present evaluation of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn MUST occur. If this boolean is true then the AuthnProcessor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.Successful.

If it is not true then no handler has been able to identify the principal (will only occur when a catch-all handler is NOT deployed). The configured url for redirecting users to for this fault MUST be set as the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL, the Authn Processor MUST populate and throw com.qut.middleware.esoe.authn.AuthnFailureException

com.qut.middleware.esoe.authn.pipeline.Handler.result.NoAction

For each response of NoAction the AuthnProcessor MUST evaluate if any handlers remain to be evaluated in the registeredHandlers list. If they do the next handler's execute method MUST be called, additionally the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.currentHandler MUST be set to value of com.qut.middleware.esoe.authn.pipeline.Handler.handlerName.

If no further handlers are present evaluation of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn MUST occur. If this boolean is true then the AuthnProcessor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.Completed.

If it is not true then no handler has been able to identify the principal (will only occur when a catch-all handler is NOT deployed). The configured url for redirecting users to for this fault MUST be set as the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL, the Authn Processor MUST populate and throw com.qut.middleware.esoe.authn.AuthnFailureException

com.qut.middleware.esoe.authn.pipeline.Handler.result.Failure

If this is returned the AuthnProcessor SHOULD immediently stop processing any additional handlers. The Authn Processor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.Failure

com.qut.middleware.esoe.authn.pipeline.Handler.result.UserAgent

If this is returned the AuthnProcessor MUST immediently stop processing any additional handlers. The Authn Processor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.UserAgent

com.qut.middleware.esoe.authn.pipeline.Handler.result.Invalid

If this is returned the AuthnProcessor MUST immediently stop processing any additional handlers. The Authn Processor MUST return com.qut.middleware.esoe.authn.AuthnProcessor.result.Invalid

Handled exceptions and actions

com.qut.middleware.esoe.authn.exception.SessionCreationException

If this exception is thrown the AuthnProcessor should immediently stop processing any additional handlers. The configured url for redirecting users to for this fault should be set as the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL

The Authn Processor SHOULD populate and throw com.qut.middleware.esoe.authn.exception.AuthnFailureException

Handlers

Handlers are responsible for actually carrying out some kind of action in regards to authn. All handlers in the authn pipeline are evaluated when an authn request takes place until either all are exhausted or a NonPassive handler decides to act.

Additionally handlers may choose to act before or after another handler in the pipeline has fully completed identification of the principal, a handler may for instance want to set a cookie regardless of the user being authenticated or not. In other situations handlers may choose to not undertake any operations if the com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn value is not set to true.

Types of Handlers

Principal Identifiers

Principal identifiers are directly involved in the process of authenticating a principal via some set of credentials which the organisation has chosen to trust. All principal identifiers MUST set the value of com.qut.middleware.esoe.authn.AuthnProcessorData.sessionID to a new session identifier when the principal is identified, they MUST set the value com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn to true and MUST return com.qut.middleware.esoe.authn.pipeline.Handler.result.Successful.

Automated

An automated handler is one which while it may send redirect statements to the user-agent does not require the user to enter any additional information to complete the identification process, for example the usage of PKI certificate installed in the users browser which is trusted. An automated handler MUST NOT complete the identification process if the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.automatedSSO is false.

Non Automated

A non automated handler is one which will require the user to explicity enter credentials in the form of username/password or supplying a specific smart card or selecting a specific card from cardspace for example.

NonPassive

A non passive handler is one which MUST take control of the users session in order to perform Authn. For example the authn processor may redirect the clients browser to some specific page containing a form element or respond back to the client with a set of specific headers to get a local application to provide some value.

Non passive handlers should be ordered carefully. Implementing a non passive handler should be done with much care to ensure that they only get invoked when environmental factors are correct. For example the user is a member of certain group or is using a specific user-agent technology. Non passive handlers which do not implement any of these checks are said to be 'catch-all' handlers. Having more then one 'catch-all' handler per stack should be very carefully thought out.

Passive

A passive handler is one which MUST NOT take control of the users session in order to perform authn. They may be simply there as a logger for example or additionally they may silently set some cookie or header value required by another handler in the pipeline or even some external application. Passive handlers can be invoked at any stage of the pipeline as necessary.

Non Principal identifiers

Non Principal identifiers are not directly involved in the process of authenticating a principal. They are used to send/recieve other information about the session. For example, they could be used to implement a CAPTCHA

NonPassive

A non passive handler is one which MUST take control of the users session in order to perform some action related to authn. For example the authn processor may redirect the clients browser to some specific page containing some information or respond back to the client with a set of specific headers to get a local application to provide some value.

Non passive handlers should be ordered very carefully. Implementing a non passive handler should be done with much care to ensure that they only get invoked when environmental factors are correct. For example the user is a member of certain group or is using a specific user-agent technology. Non passive handlers which do not implement any of these checks are said to be 'catch-all' handlers. Having more then one 'catch-all' handler per stack should be very carefully thought out.

Passive

A passive handler is one which MUST NOT take control of the users session in order to perform some action related to authn. They may be simply there as a logger for example or additionally they may silently set some cookie or header value required by another handler in the pipeline or even some external application. Passive handlers can be invoked at any stage of the pipeline as necessary.

Username/Password Handler

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.authn.pipeline.handlers.\*
Type UsernamePasswordHandler
Implemented Interfaces com.qut.middleware.esoe.authn.pipeline.Handler
Exceptions SessionCreationFailureOnSuccessfulAuthn

The UsernamePasswordHandler will allow clients to submit their username and password in a textual form to identify themselves to the system, the most popular of methods currently in use today.

This handler is of type NonAutomated, NonPassive, additionally it is catch-all.

If com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfulAuthn is already set to true the handler MUST return com.qut.middleware.esoe.authn.pipeline.Handler.result.NoAction

The handler looks for a post request coming from the user. If this is not present in the request the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL must be set to the default value and com.qut.middleware.esoe.authn.pipeline.Handler.result.UserAgent returned.

The form SHOULD be created with a method of post, a target of https://esoe.url/logon a name of esoeauthn_uphandler and autocomplete set to off. The form MUST expose two input fields, the first named esoeauthn_user of size 20 and type text, the second named esoeauthn_pw of size 20 and type password.

If the request form is considered to be invalid the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL MUST be set to the configured location for failed authentication attempts. Generally this will be the same page as used for entering esoeauthn_user and esoeauth_pw. Name value pairs of 'esoerc=failauthn' and 'esoehandler=<name#>-<version#>' should be appended where name# is the name of the handler and version# is the current version of the handler. Once this value is set the exception com.qut.middleware.esoe.authn.exception.AuthnFailureException MUST be populated and thrown.

When the user submits this form the Handler MUST traverse the list of authenticator objects which have been injected into it by calling each authenticate function in turn and passing the values of esoeauthn_user and esoeauthn_pw as arguments. These authenticators MUST implement the com.qut.middleware.esoe.authn.pipeline.Authenticator interface.

Any exception returned from the authenticator MUST be caught by the Handler. If an exception is caught or the value com.qut.middleware.esoe.authn.pipeline.Authenticator.result.Failure is returned then the following MUST occur:
The value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.failURL MUST be set to the configured location for failed authentication attempts. Generally this will be the same page as used for entering esoeauthn_user and esoeauth_pw. Name value pairs of 'esoerc=failauthn' and 'esoehandler=<name#>-<version#>' should be appended where name# is the name of the handler and version# is the current version of the handler. Once this value is set the value com.qut.middleware.esoe.authn.pipeline.Handler.result.Failure MUST be returned.

If the result of an authenticate call is com.qut.middleware.esoe.authn.pipeline.Authenticator.result.Successful the handler SHOULD generate a session identifier using the SAML2lib-j Identifier Generator. Once the session has been created a call to the Sessions Processor creation interface should be made. The value of the generated session identifier and the value of esoeauthn_user should be supplied as arguments.

If the result of this call is com.qut.middleware.esoe.sessions.Create.result.SessionCreated the session identifier value MUST be set in com.qut.middleware.esoe.authn.AuthnProcessorData.sessionID

Any exception returned from creating a session MUST be caught by the Handler and the exception com.qut.middleware.esoe.authn.pipeline.SessionCreationFailureOnSuccessfulAuthn populated and thrown.

If the Handler is satisified that all is successful the value of com.qut.middleware.esoe.authn.bean.AuthnProcessorData.succesfullAuthn MUST be set to true. The value com.qut.middleware.esoe.authn.pipeline.Handler.result.Successful MUST be returned.

If the result of an authenticate call is com.qut.middleware.esoe.authn.pipeline.Authenticator.result.Failure then all other authenticators present in the list should be called in turn, once all authenticators are exhausted the value com.qut.middleware.esoe.authn.pipeline.Handler.result.Failure MUST be returned.

SPNEGO Handler

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.authn.pipeline.handlers.\*
Type SPNEGOHandler
Implemented Interfaces com.qut.middleware.esoe.authn.pipeline.Handler
Exceptions

This handler is of type Automated, Passive.

The handler accepts POST requests from the client and performs the following actions:

If the value of AuthnProcessorData.automatedSSOEnabled is false, no further processing is undertaken and the Handler returns Handler.result.NoAction;

If auto SSO is enabled, the handler will look for a customised user-agent field containing the string configured in esoe.config:spnegoHandler.spnegoUserAgentID. If the string is present the handler will send a HTTP 401 WWW-Authenticate: Negotiate response back to the browser. This informs SPNEGO capable browsers to use the SPNEGO Negotiate protocol.

If the browser responds to the Authenticate response, the handler will attempt to process the SPNEGO token sent in the browser request by calling com.qut.middleware.esoe.auth,pipeline.authenticator.SPNEGOAuthenticator.execute.

If the SPNEGO data is valid and a context can be established with the Kerberos AS, the Handler will attempt to create the user session. If the session is sucessfully created, Handler.result.Successful is returned. If the seesion cannot be created, Handler.result.Invalid is returned.

If the SPNEGO data is invalid, or a context cannot be established with the kerberos AS to authenticate the principal, Handler.result.NoAction is returned.

Authenticators

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.authn.pipeline.authenticators.\*

Each handler delegates its authentication functionality to an Authenticator, this enables a single handler for example the username/password handler to Authenticate against a number of backend systems as required by a particular deployment. Authenticators may be presented as a single instance or as a list of instances, each of which can be evaluated in turn until success is found or all options are exhausted, authentication implementation is specific to a Handler and is left upto the developer to determine implementation. All authenticator interfaces MUST live under com.qut.middleware.esoe.auth.pipeline and implementations MUST live under com.qut.middleware.esoe.auth.pipline.authenticator. Reuse wherever possible is encouraged.


ESOE Authorization Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

PDP Processor (LXACML)

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.pdp.\*

The current design of the PSP is based on a simplified XACML 2.0 standard which we have dubbed 'Lightweight eXtensible Access Control Markup Language (LXACML)', all requests and responses are wrapped up in the (L)XACML 2.0 profile for SAML 2.0 for all transports and to ensure properties such as message integrity. We decided to implement a streamlined version of XACML 2.0 to meet specific business requirements, there will also be fully XACML 2.0 compliant offering in the open source version.

(L)XACML authorization policies are XML documents that define three top-level policy elements: <Rule>, <Policy> and <PolicySet>.
The <Rule> element contains a Boolean expression that can be evaluated in isolation, but that is not intended to be accessed in isolation. So, it is not intended to form the basis of an authorization decision by itself. The <Policy> element contains a set of <Rule> elements and a specified procedure for combining the results of their evaluation. It is the basic unit of policy used and so it is intended to form the basis of an authorization decision. The <PolicySet> element contains a set of <Policy> or other <PolicySet> elements and a specified procedure for combining the results of their evaluation. It is the standard means for combining separate policies into a single combined policy.

For our initial purposes the PAP will be a simplified web form which will take an XML file already encoded in the schema outlined below, this will be validated and pushed up to the PDP which will live as a component inside the ESOE. Our PDP will initially only implement one rule combining algorithm Deny-overrides. If a single <Rule> or <Policy> element is encountered that evaluates to Deny, then, regardless of the evaluation result of the other <Rule> or <Policy> elements in the applicable policy, the combined result is Deny. The default state of the authorization engine is to Deny, this can be configured to a default state of Permit by administrators if required but changing the default state should be undertaken with care.

Reading Requirements

Authorization Terms

Access \- Performing an action
Access control \- Controlling access in accordance with a policy
Action \- An operation on a resource
Applicable policy \- The set of policies and policy sets that governs access for a specific decision request
Attribute \- Characteristic of a subject, resource, action or environment that may be referencedin a predicate or target
Authorization decision \- The result of evaluating applicable policy. A function that evaluates to "Permit" or "Deny"
Bag \- An unordered collection of values
Condition \- An expression of predicates. A function that evaluates to "True", "False" or "Indeterminate"
Conjunctive sequence \- a sequence of predicates combined using the logical 'AND' operation
Context \- The canonical representation of a decision request and an authorization decision
Context handler \- The system that converts decision requests in the native request format to the XACML canonical form and converts authorization decisions in the XACML canonical form to the native response format
Decision \- The result of evaluating a rule, policy or policy set
Disjunctive sequence\* - a sequence of predicates combined using the logical 'OR' operation
Effect \- The intended consequence of a satisfied rule (either "Permit" or "Deny")
Policy \- A set of rules, an identifier for the rule-combining algorithm and (optionally) a set of obligations. May be a component of a policy set
\*Policy administration point (PAP) - The system that creates a policy or policy set
Policy-combining algorithm \- The procedure for combining the decision and obligations from multiple policies
Policy set \- A set of policies, other policy sets, a policy-combining algorithm and (optionally) a set of obligations. May be a component of another policy set
Predicate \- A statement about attributes whose truth can be evaluated
Resource \- Data, service or system component
Rule \- A target, an effect and a condition. A component of a policy
Rule-combining algorithm \- The procedure for combining decisions from multiple rules
Subject \- An actor whose attributes may be referenced by a predicate
Target \- The set of decision requests, identified by definitions for resource, subject and action, that a rule, policy or policy set is intended to evaluate

authzPolicy Cache Processor

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.pdp.cache.impl.\*
Type PolicyCacheProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor

The authzPolicy cache processor is perhaps one of the most critical elements in the entire system, it is responsible for continuously monitoring the database for changes to policy items and advising to all effected SPEP's that they should drop their caches immediently.

Binding for communicating with SPEP

The ESOE should implement the saml-bindings-2.0 SAML over SOAP over HTTP Binding as their method of communication with the SPEP.

The ESOE should only ever send authorization responses over backchannel communication.

The ESOE should not set any additional HTTP header information.

The SAML response should be appropriately wrapped in a SOAP envelope and delivered to the HTTP endpoint for the SPEP.

Generating initial cache state

The authZ Cache processor MUST execute as follows:
On startup the processor is to be created in its own thread, this thread MUST continuously stay active until the shutdown of the system. Should it fail in some way it MUST be automatically recovered by the system.

When the processor is executed it SHOULD using iBatis database stack connect to the ESOE authorative data store and a query should be issued agaist the database to determine the most highest value of SEQID from SERVICE_POLICIES_STATE this value should be stored as prevSequenceID

The processor now MUST obtain an exclusive lock on the PDP wide authzCache object. For each descriptorID located in the table SERVICE_POLICIES a vector of type java.util.Vector should be created. For each descriptorID its (L)XACML policies stored in the database MUST be parsed into language specific objects representing the <Policy> element. Each policy object should be stored in the vector. Once all elements are parsed the vector should be stored in the authzCache with a key of descriptorID. The exclusive lock SHOULD now be released.

Once the cache has been generated the processor MUST advise SPEPs that it has built a new cache.

For each descriptorID:
A request supplying the descriptorID should be sent to the [[SPEP processor]|[#Endpoint Resolver]] endpoint resolver for cache clear to retrieve a vector of endpoints to communicate with.

For each effected descriptorID/endpoint combination a ClearAuthzCacheRequest SHOULD be created by generating a base [[Request]|[SAML Document Descriptors#Generating Requests]] with the addition of the following:
Reason MUST be set to the string of "ESOE advises complete rebuild of central authzPolicy cache"
<Extenstions> MUST be present and its value MUST be set to be the set to the <GroupTarget> for this entity as follows:
The value of <GroupTargetID> SHOULD be set to the corresponding value of the entities <Policy> / <Target> from the authzCache. A new <AuthzTarget> element should be set to the corresponding value of each defined <Rule> / <Target>. Where <Rule> has been created with no <Target> value the value of <Policy> / <Target> should be substituted. This MUST only occur once, subsequent <Rules> that DO NOT define a <Target> can be ignored.

For each request generated the spring injected ESOEWS instance clear cache service should be called and the generated SAML message and currently processing endpoint supplied. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. Where these conditions are not met or an exception is returned by ESOWES a bean implementing com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate must be created. The SAML request document must be stored at com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.requestDocument, the current endpoint at com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.endPoint. This bean should be supplied to the Spring IoC injected failed authz cache monitor.

Maintaining Cache State

Once the initial configuration has been setup the authzPolicy cache processor must poll the database using iBatis database stack at configured time intervals (default 60 seconds) for changes to the table SERVICE_POLICIES_STATUS. This is achieved by requesting the maximum value of SEQID and comparing it against prevSequenceID

If the values are in sync then no further action is to be taken and the processor is to sleep for another configured time interval.

If the returned value is greater the processor MUST select all policies and associated descriptorID's from SERVICE_POLICIES_STATE that have a SEQID value greater then prevSequenceID, the maximum value of SEQID from this request gets set as the new value of prevSequenceID.

For each modified descriptorID:

The value of POLACTION MUST be checked. For a value of 'U' (Update) the processor must parse the associated policy stored in the table SERVICE_POLICIES into LXACML language specific objects. The current cache should be checked to determine if a policy with the current policyID exists for the descriptorID, if it does then it must be ejected and this new version added. If it doesn't contain the DescriptorID, PolicyID combination the policy is considered to be new and entered into the cache.

For a value of 'D' (Deleted) the processor must find the associated object in its cache for the supplied DescriptorID PolicyID combination and eject it.

For each update the processor MUST operate on ALL changes to a descriptorID that have occured in the current update cycle. Once all changes to a specified descriptorID have been processed they should be inserted into the PDP wide AuthzCache. This should be done by exclusive lock and steps taken to minimise the time this lock is in effect.

A request supplying the descriptorID MUST be sent to the SPEP processor endpoint resolver for cache clear to retrieve a vector of endpoints to communicate with.

For each effected descriptorID/endpoint combination a ClearAuthzCacheRequest SHOULD be created by generating a base Request with the addition of the following:
Reason MUST be set to the string of "ESOE advises administrator initiated change to SPEP authzPolicy cache"
<Extenstions> MUST be present and its value MUST be set to be the set to the <GroupTarget> for this entity as follows:
The value of <GroupTargetID> SHOULD be set to the corresponding value of the entities <Policy> / <Target> from the authzCache. A new <AuthzTarget> element should be set to the corresponding value of each defined <Rule> / <Target>. Where <Rule> has been created with no <Target> value the value of <Policy> / <Target> should be substituted. This MUST only occur once, subsequent <Rules> that DO NO define a <Target> can be ignored.

For each request generated the spring injected ESOEWS instance clear cache service should be called and the generated SAML message and currently processing endpoint supplied. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. Where these conditions are not met or an exception is returned by ESOWES a bean implementing com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate must be created. The SAML request document must be stored at com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.requestDocument, the current endpoint at com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.endPoint. This bean should be supplied to the Spring IoC injected failed authz cache monitor.

The processor MUST now sleep for another configured time interval.

Failed Authz Cache Monitor

The failed cache monitor consistently looks at a repository of com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate beans. Once it reaches the end of the repository it MUST immediently start at the beginning and work its way back through again attempting to deliver updates to SPEPs. On startup the monitor is to be created in its own thread, this thread MUST continuously stay active until the shutdown of the system. Should it fail in some way it MUST be automatically recovered by the system.

For each bean stored in the repository the spring injected ESOEWS instance clear cache service should be called with com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.requestDocument and com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.endPoint supplied. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. If this is the case the bean is ejected from the local repository.

If this check fails the value of com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.TimeStamp should be evaluated. If it is older then the time configured as a maximum (default of 24hrs) the bean is ejected from the local repository.

Where these conditions are not met or an exception is returned by ESOWES the bean should remain in the local repository.

External systems will supply additional failed requests to be added to the repository at random intervals. When they are supplied the repository MUST be locked for both read and write access while the new data is added. For each bean placed into the repository the value of com.qut.middleware.esoe.pdp.cache.bean.FailedAuthzCacheUpdate.TimeStamp must be set to the current system time.

Providing cache information to new or restarted SPEP

When an SPEP starts up it will interact with the ESOE through backchannel communication. The com.qut.middleware.esoe.spep.SPEPProcessor will make a call to the authzCacheProcessor to advise this new service has come online. It MUST supply the unique id of the descriptor along with the value of the authzCacheIndex to respond to.

The details stored in cache for the unique descriptorID should be retrieved, A ClearAuthzCacheRequest SHOULD be created by generating a base Request with the addition of the following:
Reason MUST be set to the string of "ESOE advises configured cache details for new SPEP execution instance"
<Extenstions> MUST be present and its value MUST be set to be the set to the <GroupTarget> for this entity as follows:
The value of <GroupTargetID> SHOULD be set to the corresponding value of the entities <Policy> / <Target> from the authzCache. A new <AuthzTarget> element should be set to the corresponding value of each defined <Rule> / <Target>. Where <Rule> has been created with no <Target> value the value of <Policy> / <Target> should be substituted. This MUST only occur once, subsequent <Rules> that DO NO define a <Target> can be ignored.

For each request generated the spring injected ESOEWS instance clear cache service should be called and the generated SAML message supplied along with the values descriptorID and the value of the endpoint. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. Where these conditions are not met the value com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor.result.Failure should be returned, otherwise com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor.result.Successful should be returned.

Authorization Processor

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.pdp.impl.\*
Type AuthorizationProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.pdp.AuthorizationProcessor
Exceptions InvalidRequestException, InvalidPrincipalException

The authorization processor is the core policy decision processor. It is responsible for evaluating requests to resources at remote SPEP's and responding with allows or denies based on the policies which have been defined by the administrators of that site.

It MUST implement the interface com.qut.middleware.esoe.pdp.AuthorizationProcessor

Binding for communicating with SPEP

The ESOE should implement the saml-bindings-2.0 SAML over SOAP over HTTP Binding as their method of communication with the SPEP.

The ESOE should only ever send authorization responses over backchannel communication.

The ESOE should not set any additional HTTP header information.

The SAML response should be appropriately wrapped in a SOAP envelope and delivered to the HTTP endpoint for the SPEP.

Request processing rules

Verify the supplied value of [com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.requestDocument|#Verifying Requests]. If it does not validate this is a failure. A response <StatusCode> of urn:oasis:names:tc:SAML:2.0:status:AuthnFailed must be returned. A Deny LXACMLAuthzDecisionStatement SHOULD be created with a <StatusMessage> of "Invalid request format". The exception com.qut.middleware.esoe.pdp.exception.InvalidRequestException should be created and thrown.

As soon as any failure state is encounted due to either internal processing factors or external environmental factors a Deny LXACMLAuthzDecisionStatement MUST be generated.

The value of <Issuer> should be retrieved and stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.descriptorID.

The value of <Subject> should be determined and stored against com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.subjectID.

The subjectID SHOULD be used with the the com.qut.middleware.esoe.sessions.Query.querySAMLSession query component to retrieve a com.qut.middleware.esoe.sessions.Principal. If the request throws an exception this should be caught. It MUST be considered a failure, a response <StatusCode> of urn:oasis:names:tc:SAML:2.0:status:AuthnFailed must be returned. A Deny LXACMLAuthzDecisionStatement SHOULD be created with a <StatusMessage> of "Principal specified has not been previously identified". The exception com.qut.middleware.esoe.pdp.exception.InvalidPrincipalException SHOULD be created and thrown.

The vector stored in the authzCache for com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.descriptorID should be retrieved. The <Resource> / <Attribute> / <AttributeValue> value in the presented <LXACMLAuthzDecisionQuery> must now be evaluated against all policies <Target> / <Resources> / <Resource> / <AttributeValue> values present in this vector. Values should attempt to be matched by:
\#. Exact string match on supplied <Resource> / <AttributeValue>.
\#. Regex string match on supplied <Resource> / <AttributeValue>.

If no match is established the PDP falls through to the default state of the policy (standard configuration sets this to Deny) and generates the appropriate LXACMLAuthzDecisionStatement, The response <StatusCode> should be set to urn:oasis:names:tc:SAML:2.0:status:Success. The LXACMLAuthzDecisionStatement should be created with a <StatusMessage> of "No matching policy located falling through to default state of $1", where $1 specifies the current default operation mode of the policy of "Permit" or "Deny". The value com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful should be returned.

ALL the matching policies MUST be evaluated until either a "Deny" effect is determined or until all matching policies are exhausted.

For each policy ALL the policy rules MUST be evaluated until either a "Deny" effect is determined or until all rules are exhausted.

In order to send the SPEP the correct response a record of every policy target and every rule target that evaluates to "Permit" must be recorded. If the final result is Permit this information will be sent to the SPEP as obligations in <LXACMLAuthzDecisionStatement>. For a Rule that does not implement a Target but which evaluates to Permit the target of the policy must be registered. This MUST be recorded only once even if multiple matching Rules in the policy do not specify a Target.

To evaluate each <Rule> it must be determined if the one of the <Rule> / <Target> / <Resources> / <Resource> / <AttributeValue> matches the <AttributeValue> of the <Resource> defined in the presented <LXACMLAuthzDecisionQuery>. If the <Rule> / <Target> does not exist it is considered to be an automatic match state. If it does exist it must be evaluated in the following order:
\#. Exact string match on supplied <Resource> / <AttributeValue>.
\#. Regex string match on supplied <Resource> / <AttributeValue>.

If a <Rule> is considered to be a match then the <Condition> element MUST be evaluated. If the condition does not exist the value of Effect is immediently applied. Should the value be "Permit" the value of RuleId should be added to the successfully negotiated rule set for this policy. Should the value be "Deny" the PDP MUST generate an appropriate [LXACMLAuthzDecisionStatement|#Creating LXACMLAuthzDecisionStatement]. The response <StatusCode> should be set to urn:oasis:names:tc:SAML:2.0:status:Success. The LXACMLAuthzDecisionStatement should be created with a <StatusMessage> of "Policy $1 located and rules evaluated, identified DENY state for principal on Rule $2. Rules evaluated $3. $4", $1 SHOULD be the current PolicyId, $2 should be the current RuleId, $3 should be all RuleId values that were successfully evaluated for the current policy before the Deny state was encountered, $4 should be all PolicyId values of policies which have already been successfully evaluated. A <GroupTarget> with <GroupTargetID> set to the matching resource target of the current policy and the value of <AuthzTarget> set to the value of the current rule should also be set. The value com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful should be returned.

If a <Condition> element does exist it should be treated as a boolean function. <Conditions> may include embeded <Conditions>, <Apply>, <AttributeValue> and <SubjectAttributeDesignator>. Child nodes should be evaluated as necessary to satisfy the input requirements of their parents.

The <Apply> element denotes application of a function to its arguments, thus encoding a function call. The following functions may be defined as appropriate for the FunctionId attribute of the <Apply> element

The <AttributeDesignatorType> is the type for elements that identify attributes by name. All attributes are considered to be of type string, should an attribute not be available the bag will be considered empty.

The <SubjectAttributeDesignator> indicates to the PDP it should use the set of values for the matching attribute which we have already retrieved earlier from the [Sessions Processor|ESOE Design#Sessions Processor].

The result of the <Condition> is the result of the top level <Apply> element. If the condition is evaluated as being TRUE then the value of Effect for the rule is applied. Should the value be "Permit" the value of RuleId should be added to the successfully negotiated rule set for this policy. Should the value be "Deny" the PDP MUST generate an appropriate [LXACMLAuthzDecisionStatement|#Creating LXACMLAuthzDecisionStatement]. The response <StatusCode> should be set to urn:oasis:names:tc:SAML:2.0:status:Success. The LXACMLAuthzDecisionStatement should be created with a <StatusMessage> of "Policy $1 located and rules evaluated, identified DENY state for principal on Rule $2. Rules evaluated $3. $4", $1 SHOULD be the current PolicyId, $2 should be the current RuleId, $3 should be all RuleId values that were successfully evaluated for the current policy before the Deny state was encountered, $4 should be all PolicyId values of policies which have already been successfully evaluated. A <GroupTarget> with <GroupTargetID> set to the matching resource target of the current policy and the value of <AuthzTarget> set to the value of the current rule should also be set. The value com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful should be returned.

If the condition is evaluated as being FALSE then the rule is discounted in this policy evaluation. At this stage any remaining rules for the policy must be evaluated.

Once all <Policy> objects are evaluated by the PDP if at least one "Permit" has been identified the PDP MUST generate an appropriate LXACMLAuthzDecisionStatement. The response <StatusCode> should be set to urn:oasis:names:tc:SAML:2.0:status:Success. The LXACMLAuthzDecisionStatement should be created with a <StatusMessage> of "Policies located and rules evaluated, identified PERMIT state for principal. $1", $1 SHOULD be all PolicyId values of policies which were successfully evaluated. For each policy that contained at least one <Rule> which evaluated to Permit a <GroupTarget> with <GroupTargetID> set to the matching resource target of the policy and the values of <AuthzTarget> set to the target of all the contained rules which evaluated to Permit. The value com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful should be returned.

If all <Policy> objects are exhausted without an explicit "Deny" or "Permit" Effect being encountered the PDP falls through to the default state of the policy (standard configuration sets this to Deny) and generates an appropriate LXACMLAuthzDecisionStatement, The response <StatusCode> should be set to urn:oasis:names:tc:SAML:2.0:status:Success. The LXACMLAuthzDecisionStatement should be created with a <StatusMessage> of "Policies located and rules evaluated but no explicit outcome detected falling through to default state of $2", $1 SHOULD specify the current default operation mode of the policy of "Permit" or "Deny". The value com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful should be returned.

Creating LXACMLAuthzDecisionStatement

The LXACMLAuthzDecisionStatement should be created to match the outcomes of the request processor.

Queries which are evaluated to Deny

Set the value of <Response> / <Result> / <Decision> to Deny
<AttributeValue> should be the original resource that was queried by the SPEP

Set the value of <Response> / <Result> / <Status> / <StatusMessage> to the value indicated by the request processor.

Set the value of <Response> / <Result> / <Obligations> to a new <Obligation> with values:
FullFillOn set to Deny
ObligationId set to lxacmlpdp:obligation:cachetargets

Queries which are evaluated to Permit

Set the value of <Response> / <Result> / <Decision> to Permit
<AttributeValue> should be the original resource that was queried by the SPEP

Set the value of <Response> / <Result> / <Status> / <StatusMessage> to the value indicated by the request processor.

Set the value of <Response> / <Result> / <Obligations> to a new <Obligation> with values:
FullFillOn set to Permit
ObligationId set to lxacmlpdp:obligation:cachetargets

<lxacml-context:Result
    xmlns:group="http://www.qut.com/middleware/lxacmlGroupTargetSchema"
    xmlns:lxacml="http://www.qut.com/middleware/lxacmlSchema"
    xmlns:lxacml-context="http://www.qut.com/middleware/lxacmlContextSchema">
    <lxacml-context:Decision>Permit</lxacml-context:Decision>
    <lxacml-context:Status>
        <lxacml-context:StatusMessage>
            Policies located and rules evaluated. Identified PERMIT
            state for principal.
            \{urn:qut:policy:complex:3,urn:qut:policy:complex:4\}
        </lxacml-context:StatusMessage>
    </lxacml-context:Status>
    <lxacml:Obligations>
        <lxacml:Obligation
            ObligationId="lxacmlpdp:obligation:cachetargets"
            FulfillOn="Permit">
            <lxacml:AttributeAssignment
                AttributeId="lxacmlpdp:obligation:cachetargets:updateusercache">
                <group:GroupTarget>
                    <group:GroupTargetID>
                        /default/\*
                    </group:GroupTargetID>
                    <group:AuthzTarget>
                        /default/public\*
                    </group:AuthzTarget>
                </group:GroupTarget>
            </lxacml:AttributeAssignment>
        </lxacml:Obligation>
    </lxacml:Obligations>
</lxacml-context:Result>

SAML Wrappers

An Assertion should be created and the <LXACMLAuthzDecisionStatement>. embedded inside.

A base Response should be created with <Status> information set as detailed by the request processing, it should contain the generated <Assertion>.

Once successfully created the response should be stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.responseDocument.

Sessions Processor

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.impl.\*
Type SessionsProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.SessionsProcessor
Exceptions ConfigurationValidationException

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in
RFC 2119


ESOE Delegated Authentication Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

ESOE Delegated Authn Abstract Processor

Design details to follow.

ESOE Delegator for Shibboleth

Component Lead Bradley Beddoes
Package
Type
Implemented Interfaces
Exceptions

Design details to follow.


ESOE Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Enterprise Sign On Engine

ESOE authoritative data store

One of the core components to the operation of the ESOE is the central repository of authoritative data. This database stores all the details required to build the metadata representation of the core system and its associated service providers in network. It also contains a record of each new authentication event which successfully takes place on the system as well as records of each service that is visited for clients in each session. This allows fine grained security data to obtained easily with the added benefit of data mining activities to gain a picture of where clients are traversing the system.

This data is managed by the ESOE Manager system which is documented elsewhere.

Design documentation

  1. ESOE Authentication Design
  2. ESOE Single Sign-on and Logout Design
  3. ESOE Web Services Design
  4. ESOE Attribute Authority Design
  5. ESOE Authorization Design
  6. ESOE Sessions Cache Design
  7. ESOE Logging Design
  8. ESOE Metadata Processor Design
  9. ESOE SPEP Processor Design
  10. ESOE Delegated Authentication Design

Developers

Welcome to the Enterprise Sign On Engine developers space. This space contains all the downloads, documentation and links to helpful places you will need to get started with developing custom integrators, SPEP modules and more for the ESOE. We suggest that you take advantage of some of the features here such as RSS feeds, page watches and space watches to ensure your up to date with all the information which will be collated here.

Development Environment

Development environment setup
Configuring build environment for Java
Configuring build environment for C++

Git Access

Read-only
git clone git://github.com/esoeproject/esoeproject.git

Commit access
Fork the esoeproject repository on GitHub. Feel free to send pull requests to the esoe-dev list, for review.

Restrictions
Commits that bring in binaries, bad code, or bugs will be rejected.

Component Design Documentation

ESOE Design
ESOE Design Diagram

Support and Mailing Lists

ESOE Developers Mailing List
ESOE Users Mailing List

GSOC 2008


ESOE Download Checksums

This page intentionally left blank (for now).


ESOE Features

Authors
Bradley Beddoes

Applicable versions
All

Introduction

This page is meant as a guide to new comers to the Enterprise Sign On Engine who would like to get an appreciation for what abilities the ESOE has an what kinds of problems it may be able to solve for your situation. Over time as ESOE is adapted to more installations we'll be adding case studies and other materials.

Currently the ESOE is technology which is used to manage access and data transfer to applications in the web tier. In the future this will be extended to include web services and a host of other resources as developers start trialling more and more far out concepts on the building blocks it now provides. This is a community project, its direction is driven by the needs of our users so if you have a particular feature requirement please join our mailing lists and get a discussion started.

As a quick overview the ESOE can

Each heading below lays out more detail on what the ESOE can do for you.

Authentication

The first major component that ESOE handles is authentication. It can do this to a variety of backend datastores such as the out of the box provided LDAP compliant directory connector. The architecture is such that any datastore can actually be used with the creation of an authentication module. This might be databases, flat files, web services or basically any other component you might already have.

To show off this flexibility the ESOE also provides a second authentication connector out of the box that talks to Microsoft Active Directory. When windows users interact the ESOE it automatically gets their credentials from the Windows session, validates it against your domain controllers and authenticates the user. We call this "True Single Sign On" as the user only ever presents their password to the operating system itself when they start their session.

The authentication process itself can be customized as needed by a particular implementation. For example you may wish to show users who authenticate for the first time a web page detailing some important messages your company wants them to read and agree to before they are given access to your resources, or you may wish to set a particular cookie, all of this can be achieved using the ESOE.

Finally the interface users see to authenticate and interact with the ESOE is completely customizable to your site. So long as you provide some basic HTML form components you can choose to present your portal any way and anywhere you choose.

Federated Authentication

One of the biggest challenges we face today is remembering all our identities. Usernames and passwords at multiple sites, hard to remember, hard to obtain in the first place a real nightmare. Certainly a big negative when it comes to collaborating with business partners.

ESOE takes care of this problem allowing you to use federated identities. Essentially this means that your business partner can login at their own company, using their local username and password and then access your content across the internet without needing to login again.

We currently support this using two primary technologies, the first being the internet2 shibboleth project and the second being a new technology called OpenID. The former is more heavily used in educational organizations where security and anonymity are highly important. The latter is extremely easy to deploy and is used in sites where security is sometimes less of a concern but you want to be able to gather some basic details about the person who is visiting you.

In the future we'll support even more identity sources including Yahoo BBAuth to truly integrate your company with the rest of the world.

Application Single Sign On

Single sign on has a lot of different meanings, earlier we discussed True Single Sign On to describe the user only needing to authenticate once to the operating system, this is different from Application Single Sign On (ASSO) (and is what most people mean when the refer to SSO).

Once the user has authenticated to the ESOE using one of the methods mentioned previously they never have to authenticate again while their browser is open and their session is active, regardless of how many various applications they visit. For example once I authenticate to ESOE of a morning I can visit our central portal, our blackboard deployment and our confluence deployment all without ever being asked for my credentials again. This is what we mean when we talk about Application Single Sign On. Multiple independent applications all being authenticated to without needing to issue my credentials again.

The best part of all of this is that even though as a user I have no knowledge of what is going on underneath the system is doing a lot of work with cryptography and XML to ensure that the sessions are completely secured. Easy to use, works in any web browser, exactly the way I as a user want it to be.

Multi-factor authentication

One of the biggest risks associated with ASSO is that once a potential attacker has penetrated your security, they have access to many resources in your environment. To help mitigate this risk, resources with different levels of trust should be separated. ESOE addresses this problem via multi-factor authentication.

With the addition of modules to the Authentication system you can require that users to particular services must be first authenticated to a certain level, for example your financial system. Users can happily move between all services your company offers with a username and password however when they access your finance system ESOE will require them to authenticate to a higher level before granting access. This may be with a one time token issued over SMS, a 6 digit token pad given to trusted persons or some other kind of technology you wish to make use of.

The real beauty of the solution is that you can have as many levels of security as necessary for your company, with each level requiring even stricter methods of authentication to progress. Of course you don't need to write this support into every application you wish to enforce the levels on either, even when they change. Its all done by the ESOE.

Transfer identity data

Part of ASSO is transfer of identity data from the ESOE to the application regarding the person or other entity that is authenticating.

ESOE is able to connect to as many sources of identity data as you have available, retrieve that data, clean it, combine it and present as single unified source to the end application. This is kind of hard to explain so an example will assist.

At company X we have two LDAP servers, one stores information on personal data such as names, email address etc. The other has corporate data such as membership of different roles. Ideally these two directories should be merged to a single one but practically this can't happen just yet. To be able to make use of this data effectively applications would need to query both sources. If for some reason we add a third source to the mix lets say a database which also has role membership information the ESOE can use this as well. To make things even worse roles in LDAP are identified by "Roles" whereas roles in the database are identified by "client_membership". ESOE can query all these sources and add them altogether in a single view of the person or entity, it can even clean up the various identifiers of the attributes so instead of "Roles" and "client_membership" it presents the application with the simplified identifier of "role" which contains all the data from both sources. Applications never need to know just where the data is coming from and you can change and migrate your backend infrastructure without risk.

ESOE currently ships with support for LDAP out of the box, additional connectors are planned but are very much deployment specific.

Access control

In the modern IT environment some resources are supposed to be shared with external partners. On the other hand some resources should not be shared externally. Having a system that is able to interpret and securely provide correct access to all these resources without inconvenience to the user is paramount. Other systems don't put as much importance on this aspect as ESOE does.

Furthermore auditors want to be able to go through your policies across all systems and make sure that its been done correctly to company standards. With the common application distributed approach this is a nightmare. Furthermore with this common approach your system administrators need to learn a new style of syntax for each platform and application your trying to support.

ESOE rectifies this with it's centralized access control decision making. All policies for all applications in your system are stored and maintained centrally. When a person or entity requests access to the resource the application software will first speak to the ESOE to ensure that the access is allowed. If the ESOE responds in the negative access is denied for that person or entity. When access is allowed naturally the user is granted access. This is combined with some high speed caching and provides for a really solid yet flexible approach to the access control problem.

Centralized registration and management of services

In some large companies various business units can work fairly autonomously meaning that you don't always know who is running a particular application. Furthermore enforcing any control over ensuring things are done securely and that versions of software are patched is harder still.

ESOE deals with these problems on several fronts

Conclusion

This concludes our overview of features for the ESOE, we welcome your feedback and comments to improve this document and we hope you found it useful in evaluating this product.


ESOE Installation Additions - Apache and Mod Proxy AJP

Authors
Bradley Beddoes

Applicable versions
Beta 2

Overview

This document explains requirements for getting Apache and mod_proxy_ajp working as a front end to your ESOE Tomcat deployment.

ESOE Startup Config

Naturally with Apache offloading you should only configure URL's and host addresses with the standard http[s]://. There is no requirement to specify ports of 80 or 443 for this kind of deployment.

Setup

We have left the configuration of virtual hosts and your Apache server itself out of this documentation. There are many excellent resources online if you need assistance with this. We recommend:
http://httpd.apache.org/docs/2.0/vhosts/ and http://httpd.apache.org/docs/2.0/mod/mod_proxy.html as starting points.

Once your VirtualHost is configured correctly and you have Mod Proxy and Mod Proxy AJP installed and operational you will require the following configuration:
<Location />
    Allow from all
    ProxyPass ajp://localhost:8009/
    ProxyPassReverse http://esoe.debian.intient.test/
</Location>

<Location /esoemanager/>
    Allow from all
    ProxyPass ajp://localhost:8009/esoemanager/
    ProxyPassReverse http://esoe.debian.intient.test/esoemanager/
</Location>

<Location /spep/>
    Allow from all
    ProxyPass ajp://localhost:8009/spep/
    ProxyPassReverse http://esoe.debian.intient.test/spep/
</Location>

<Location /web/>
    Allow from all
    ProxyPass ajp://localhost:8009/web/
    ProxyPassReverse http://esoe.debian.intient.test/web/
</Location>

Please Note: "Allow from all" is probably to generous for a production environment, we recommend you review these options in the Apache documentation and configure your security according to you own environment.

SSL

Having Apache handle your SSL is fine and won't effect the operation of ESOE except for Metadata resolution. If you are using a Self Signed Certificate you must ensure that the JVM running tomcat trusts this certificate. Failure to do this will result in spep.data/logging/spep.log and esoe.data/logging/esoe.log complaining about being unable to resolve Metadata, this is because the https connection has been terminated due to the use of an untrusted CA. Certificates signed by external commercial providers should not require any additional JVM configuration.

Feedback

We aim to continually improve this documentation set to make it as easy as possible to configure Apache as a front end for ESOE and Tomcat. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE Installation Additions - Debian

Authors
Peter Schober
Bradley Beddoes

Applicable versions
Beta 2

Applicable Debian Versions
Debian 4.0 "Etch"

Contributions

The ESOE project team thanks Peter Schober from the University of Vienna for his time in forming this documentation.

Overview

The tomcat environment that comes as a default install with Debian has some quirks with how its setup. This document is to be read in addition to the standard ESOE installation guide.

Requirements

It is assumed you're using tomcat5.5, and tomcat5.5-admin as packages via apt management. You may have tomcat5.5-webapps installed though this may cause you some issues with respect to update, if you can remove this package. We currently require you to DISABLE TOMCAT SECURITY in /etc/init.d/tomcat5.5

Directory Ownership

Ensure that the directories you have configured for esoe.data esoemanager.data and spep.data are owned by the user Tomcat55 before running esoestartup. This permission should remain for running the actual ESOE installation itself.

Special jar requirements

Due to the Jar layout on debian systems your database jar files for Oracle or Mysql must reside in $TOMCAT/common/lib you must also place a copy of log4j.jar in this location

Deployment of war files

Tomcat on Debian uses pre-exploded war files and context files by default so to try and simply deploy war files in the Debian Tomcat container will cause you a lot of grief, instead follow the instructions below (shutdown tomcat first).

ESOE Startup

  1. Copy esoestartup.war to /var/lib/tomcat5.5/webapps
  2. Create the file /usr/share/tomcat5.5/conf/Catalina/localhost/esoestartup.xml
  3. Edit esoestartup.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/esoestartup" docBase="/var/lib/tomcat5.5/webapps/esoestartup.war" debug="0" privileged="true" allowLinking="true">
</Context>

You should now run ESOE Startup as normal, once the process is complete shutdown tomcat.

ESOE Deployment

  1. If you have installed tomcat5.5-webapps remove the symlink for ROOT.xml in /usr/share/tomcat5.5./conf/Catalina/localhost - This will ensure no conflicts on restart.
  2. Copy ROOT.war to /var/lib/tomcat5.5/webapps
  3. Create the file /usr/share/tomcat5.5/conf/Catalina/localhost/ROOT.xml
  4. Edit ROOT.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/" docBase="/var/lib/tomcat5.5/webapps/ROOT.war" debug="0" privileged="true" allowLinking="true">
</Context>
  1. Copy spep.war to /var/lib/tomcat5.5/webapps
  2. Create the file /usr/share/tomcat5.5/conf/Catalina/localhost/spep.xml
  3. Edit spep.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/spep" docBase="/var/lib/tomcat5.5/webapps/spep.war" debug="0" crossContext="true" privileged="true" allowLinking="true">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>META-INF/context.xml</WatchedResource>
</Context>
  1. Copy esoemanager.war to /var/lib/tomcat5.5/webapps
  2. Create the file /usr/share/tomcat5.5/conf/Catalina/localhost/esoemanager.xml
  3. Edit esoemanager.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/esoemanager" docBase="/var/lib/tomcat5.5/webapps/esoemanager.war" debug="0" crossContext="true" privileged="true" allowLinking="true">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>META-INF/context.xml</WatchedResource>
</Context>
  1. Copy web.war to /var/lib/tomcat5.5/webapps
  2. Create the file /usr/share/tomcat5.5/conf/Catalina/localhost/web.xml
  3. Edit web.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/web" docBase="/var/lib/tomcat5.5/webapps/web.war" debug="0" privileged="true" allowLinking="true">
</Context>

You should now restart Tomcat and all should operate as normal from this point.

Feedback

We aim to continually improve this documentation set to make it as easy as possible to configure ESOE on Debian. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE Installation Additions - Redhat

Authors
Bradley Beddoes

Applicable versions
Beta 2

Applicable Redhat Versions
Redhat Enteprise Linux 4 and 5

Overview

The tomcat environment that comes as a default install with Redhat has some quirks with how it's set up. This document is to be read in addition to the standard ESOE installation guide.

Requirements

It is assumed you're using tomcat5 installed with up2date.

Directory Ownership

Ensure that the directories you have configured for esoe.data esoemanager.data and spep.data are owned by the user Tomcat before running esoestartup. This permission should remain for running the actual ESOE installation itself.

Special jar requirements

Due to the Jar layout on Redhat systems your database jar files for Oracle or Mysql must reside in $TOMCAT/common/lib you must also place a copy of log4j.jar in this location

Deployment of war files

WAR file deployment on Redhat Tomcat is fairly straight forward. However before beginning it is recommended you undeploy ROOT.war and the ROOT directory from /usr/share/tomcat5/webapps

WAR deployment is now as per normal Tomcat install, copy the war files to /usr/share/tomcat5/webapps. It is advisable that you deploy esoestartup on its own, run through the install fully, remove it and then install the remaining wars.

Feedback

We aim to continually improve this documentation set to make it as easy as possible to configure ESOE on Redhat. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE Installation Guide

Authors
Bradley Beddoes
Paul Stepowski
Shaun Mangelsdorf

Applicable versions
Beta 2

Note: The instructions here do not apply to builds from the current development branch.

For the security conscious we highly recommend our guide on Securing ESOE in Unix environments in addition to this guide

Custom Linux install documentation is available for some platforms and should be read in addition to this document

These instructions assume a standalone tomcat installation not fronted by Apache, please see ESOE Installation Additions - Apache and Mod Proxy AJP for instructions on deploying behind apache

Prerequisites

System

Software Website
Sun Java SE 5 (Sun Java SE 6 for Active Directory Integration) http://java.sun.com
MySQL Server 5.x or Oracle 9g1 http://dev.mysql.com/downloads/mysql/5.0.html or http://www.oracle.com
Tomcat 5.5.x or higher http://tomcat.apache.org

1 May be substituted with other supported database software.

Dependencies

ESOE is a complex system with many dependencies, all dependencies are Apache 2.0 licensed or licensed under compatible terms.

Apart from database dependencies which need to be shipped directly by vendors and logging dependencies which are a per site special deployment the ESOE download supplies all required jar files in two separate packages, NAME-shared.tar.gz and NAME-endorsed.tar.gz installation of these packages is explained in the subsequent passages below. Each package contains a html file which specifies versions which are relied on for the release of the ESOE you are installing. Should you wish to manage your dependencies via a package management repository such as those provided by jpackage.org this file will be invaluable in assisting you with deployment. Be aware that dependencies which are specified as endorsed are particularly important, failure to correctly endorse dependencies can lead to problems with utilization of broken or incomplete implementations of classes from the JVM.

MySQL Dependencies

You need to retrieve MySQL JDBC driver from:
http://www.mysql.com/products/connector/j/

The version you will require is 5.0+

Oracle Dependencies

You need to retrieve Oracle JDBC driver from:
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html

Please select the correct version for your backend Oracle deployment.

Overview of ESOE components

There are 4 major components which are deployed to get your ESOE deployment up and running:

Some decisions around deployment should be made at this stage. The components esoemanager and spep MUST be deployed in the same tomcat instance. However we recommend that the esoecore component is deployed in a separate instance (preferably on a separate machine), however if you are limited to one tomcat instance all three components will play happily together.

Generally we run esoestartup and esoecore in the same tomcat instance, you may however freely separate this to two further tomcat instances if you desire.

Considerations for physical hardware are important for ESOE deployments. All operations the ESOE undertakes require cryptographic processes which is CPU intensive. As a guide we are able to guarantee around 25 operations a second on Pentium 3 class hardware with JVM memory maximums of 768m. Further performance figures are forthcoming.

Configure Your System

Taking a backup

If you are using versions of software that already exist on the system, particularly the tomcat instance we cannot stress enough the need to MAKE A BACKUP before continuing. The best of us make mistakes, a backup makes them small mistakes, not backing up can make them a nightmare.

Ensure active Prerequisites

To run ESOE you need the following available on your system:

  1. A Sun JVM preferably Java SE 6 but 5 is also acceptable (NOTE: Users of Java 5 you will not be able to use the Active Directory true single sign on).
    ESOE requires more memory than the defaults. You should set JAVA_OPTS to have memory sizes similar to the following -Xms128m -Xmx512m, this will work for most testing environments. For Production we recommend a range between 512 and 1024 but this needs to be tuned to your expected load.
  2. Tomcat 5.5.x or 6.x (Other Java containers should also be suitable but are as yet untested - let us know your experiences on the mailing list if you install in another container)
  3. Either an Oracle or MySQL database instance, with a unique database/schema and an account with read/write privileges. This account will be used by both the ESOE Core and ESOE Manager components.

Ensure your default Tomcat install can be accessed on port 8080 and you can see the generic welcome message, then continue below.

For the security conscious we highly recommend our guide on Securing ESOE in Unix environments in addition to this guide

Configure Dependencies

Dependencies Package

Extract the package you have downloaded for the ESOE Project. E.g.
$ mkdir esoestartup
$ cp esoe-startup.tar.gz esoestartup
$ tar zxf esoe-startup.tar.gz

This will result in a number of gziped tar packages being made available, along with esoestartup.war.

At this stage you will have decided if all the components will be running on a single tomcat instance or across multiple instances. If you are running a separate container then you need to make similar decisions, likewise the below extraction points need to be mapped to your container of choice. We would appreciate your instructions for achieving this on other containers. Some of these dependencies are similar across components. If you are deploying several components in the same container you can safely expect warnings about overwriting files when extracting.

ESOE Startup dependencies

  1. Extract esoestartup-endorsed.tar.gz to your $TOMCAT/common/endorsed directory of the tomcat instance which will run esoestartup
  2. Extract esoestartup-shared.tar.gz to your $TOMCAT/shared/lib directory of the tomcat instance which will run esoestartup

ESOE Core dependencies

  1. Extract esoecore-endorsed.tar.gz to your $TOMCAT/common/endorsed directory of the tomcat instance which will run esoecore
  2. Extract esoecore-shared.tar.gz to your $TOMCAT/shared/lib directory of the tomcat instance which will run esoecore

ESOE Manager dependencies

  1. Extract esoemanager-shared.tar.gz to your $TOMCAT/shared/lib directory of the tomcat instance which will run esoemanager
  2. Extract spep-endorsed.tar.gz to your $TOMCAT/common/endorsed directory of the tomcat instance which will run esoemanager
  3. Extract spep-shared.tar.gz to your $TOMCAT/shared/lib directory of the tomcat instance which will run esoemanager

Configuring your own dependencies

To configure your own dependencies you should acquire them from whatever source deemed most suitable and configure as endorsed and shared libraries to match the versions set down in the supplied html files in each NAME-endorsed.tar.gz and NAME-shared.tar.gz package.

Database dependencies

Earlier you downloaded dependencies for your database either MySQL or Oracle. Both distributions should come with a single jar file. This jar file should be copied to $TOMCAT_HOME/shared/lib for tomcat instances which are running the components esoestartup, esoecore and esoemanager

Configure Database

Your database itself is already configured, undertake the following for your environment.

MySQL

  1. Start the mysql command line tool and login as a user with the global SUPER privilege
  2. Switch to your esoe database
  3. Run the following command:
    source $esoestartupextractdir/databasegeneration/generate_db-mysql.sql
    NOTE: Replace $esoestartupextractdir with your working directory you extracted esoestartup.tar.gz to.
  4. You will see a lot of query successful commands fly by, you may wish to check that all tables are populated by issuing "show tables"

Oracle

Oracle databases are generally controlled by a DBA with the ESOE account not having permission to actually create schema. Give your DBA the generate_db-oracle.sql script to setup your environment. You should then be able to connect as the account provided for ESOE and ensure that tables exist in your schema.

Configure ESOE

Ensure Tomcat is shutdown before proceeding. Copy the esoestartup WAR file to tomcat's webapps directory.

Setup run time configuration properties.

ESOE, ESOE Manager and all SPEP instances rely on Java properties being configured to point to locations at which they can resolve their configuration and keystores. ESOE Startup also utilizes these properties to write configuration files and keystores it generates to.

We recommend you create a directory structure to hold all these files as such
/opt/esoe
        |
        - core
             |
             - config
             - logging
        - manager
             |
             - config
             - logging
        - spep
             |
             - config
             - logging

Windows users should select a suitable location on your server to create a similar structure.

Assuming the above structure you should ensure that the following are exposed to the system variable JAVA_OPTS before starting tomcat:

JAVA_OPTS="${JAVA_OPTS} -Desoe.data=/opt/esoe/core" 
JAVA_OPTS="${JAVA_OPTS} -Desoemanager.data=/opt/esoe/manager" 
JAVA_OPTS="${JAVA_OPTS} -Dspep.data=/opt/esoe/spep" 

Logging

Logging is configured for you in WEB-INF/classes/log4j.xml - Feel free to modify this configuration for your needs.

Run ESOE Startup

You are now ready to restart tomcat. This will automatically deploy the web applications in the WAR file.

The first time you restart tomcat after copying over all the WAR and JAR files, it may take some time for tomcat to start. This is normal. Please be patient. You can view the tomcat and ESOE logs to watch the deployment as it progresses.

Once the esoestartup web application is deployed, point your web browser at [http://$HOSTNAME:8080/esoestartup/]. Where $HOSTNAME is the fully qualified domain name of the IP address that tomcat is listening on.

NOTE: Do not use an IP address for $HOSTNAME. This will cause an error.

The ESOE startup application will now guide you through the remainder of the install process asking you many questions along the way, please have all details about your environment ready for this process.

BE CAREFUL with host addresses. When configuring ESOE and ESOE Manager SPEP details be sure to include the port on URL's if you are not deploying on the standard ports of 80 or 443 which IS the case for most standalone tomcat installations. Changing this later can prove to be difficult so plan your access URL's before proceeding. For most standalone tomcat installs you will want to append port 8080 to each URL or host entry.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup the ESOE. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE License

The ESOE is completely licensed under the liberal Apache 2.0 license which is available at http://www.apache.org/licenses/LICENSE-2.0

At the time of writing this page the associated text for the license is

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

1. You must give any other recipients of the Work or Derivative Works a copy of this License; and

2. You must cause any modified files to carry prominent notices stating that You changed the files; and

3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS


ESOE Logging Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Logging Processor

Component Lead Bradley Beddoes
Package NA
Type NA
Implemented Interfaces NA
Exceptions NA

The logging processor is responsible for distributing interesting events that are occuring inside the ESOE to registered logging handlers, these handlers may inturn distribute messages to any medium which they implemented for including syslog, flatfile, databases, webservices or snmp to name a few examples.

The logging processor is not a concrete class, it is instead conceptual and makes use of the Log4j package.

Handlers are responsible for actually carrying out some kind of action in regards to logging an event. Log4j specifies that handlers are invoked when they meet some specific criteria. The criteria are all laid out inside the log4j.xml document distributed as part of the ESOE.

Handlers MAY log data to any source they wish, syslog, flatfile, databases, webservices or snmp for example.

Handlers SHOULD timestamp every message they log, where the backend system can't reasonably be manipulated to store timestamps they MAY be left out, however this must be clearly indicated in the associated documentation for the handler.

The ESOE defines three additional logging levels of AUTHN, AUTHZ and INSANE these are implemented as extenstion levels to log4j.

AUTHN

This level is for events that are directly related to success or failure of a principal to authenticate, it should only be called once for each authenctication attempt

AUTHZ

This level is for events that are directly related to permit or deny states when a principal requests access to some resource at a remote SPEP. It should only be called once for each resource access attempt.

INSANE

This level is utilised for logging any data which would be highly unusual to ever want to see and for large volumes of data, examples of this MAY include but are not limited to complete http handshake data, full SAML documents and encrypted/encoded data blocks.


ESOE Metadata Processor Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Metadata Processor

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.metadata.impl.\*
Type MetadataImpl
Implemented Interfaces com.qut.middleware.esoe.metadata.Metadata
Exceptions InvalidMetadataEndpointException, InvalidMetadataKeyException

The Metadata processor is used internally by the wider ESOE to obtain details about SPEP's that are stored in metadata, specifically information such as the public key they have used to sign SAML documents and locations of endpoints which are specified in requests.

Metadata retrieval thread

On initalization this component will launch a thread, this thread MUST continuously stay active until the shutdown of the system. Should it fail in some way it MUST be automatically recovered by the system.

When executed this thread will connect to the Metadata provider offered by the [administrator management system|Administrator Management System Design]. The document will be parsed and stored locally in com.qut.middleware.esoe.metadata.Metadata.cache. Before writing to the cache an exclusive lock MUST be obtained. Once it is updated this lock MUST be released.

A hash of the retrieved document should be taken and stored as com.qut.middleware.esoe.metadata.Metadata.currentRevision.

This thread MUST execute at configured intervals (default 120 seconds), a hash of the document should be taken and compared against com.qut.middleware.esoe.metadata.Metadata.currentRevision, if the values are equivalent no further action is to be taken and the thread should sleep. If they are not equivalent the document MUST be parsed and stored locally in com.qut.middleware.esoe.metadata.Metadata.cache. Before writing to the cache an exclusive lock MUST be obtained. Once it is updated this lock MUST be released. A hash of the retrieved document should be taken and stored as com.qut.middleware.esoe.metadata.Metadata.currentRevision.

Endpoint Resolver

The following are available to resolve an endpoint:

com.qut.middleware.esoe.metadata.Metadata.resolveAssertionConsumerService

Requests to this method must supply the descriptorID and ID of the index which they are interested in. The metadata component will verify these values against its local cache and return the appropriate value of the attribute Location. (See SAML <md:indexedendpoint>)

Should the supplied values not be resolveable from the cache the exception com.qut.middleware.esoe.spep.exception.InvalidMetadataEndpointException SHOULD be populated and thrown.

com.qut.middleware.esoe.metadata.Metadata.resolveSingleLogoutService

Requests to this method must supply the descriptorID which they are interested in. The metadata component will verify these values against its local cache and return a vector containing all the appropriate values of the attribute Location. (See SAML <md:endpoint>)

Should the supplied values not be resolveable from the cache the exception com.qut.middleware.esoe.spep.exception.InvalidMetadataEndpointException SHOULD be populated and thrown.

com.qut.middleware.esoe.metadata.Metadata.resolveCacheClearService

Requests to this method must supply the descriptorID which they are interested in. The metadata component will verify these values against its local cache and return a vector containing all the appropriate values of the attribute Location. (See SAML <md:endpoint>)

Should the supplied values not be resolveable from the cache the exception com.qut.middleware.esoe.spep.exception.InvalidMetadataEndpointException SHOULD be populated and thrown.

Key Resolver

The key resolver makes available the keys for validating signatures (and in the future decryption):

com.qut.middleware.esoe.metadata.Metadata.obtainSigningKey

Requests to this method must supply the descriptorID and keyName of the descriptor they are interested in. The metadata component will verify these value against local cache. For the located <KeyDescriptor> the value of use will be evaluated if it is either not present or set to 'signing' the value of <ds:KeyInfo> / <KeyValue> will be returned to the caller.

Should the supplied values not be resolveable from the cache the exception com.qut.middleware.esoe.spep.exception.InvalidMetadataKeyException SHOULD be populated and thrown.


ESOE Sessions Cache Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Sessions Processor

The sessions processor is the overall control point for session data within the ESOE and the distributed network of SPEPs. It is responsible for creating, storing, updaing and providing all the data related to a principals session.

To facilitate this it loads a primary configuration file called sessiondata.xml, the location from which to load this configuration file is specified in the associated Spring configuration descriptor for this processor. The sessions processor configuration file is compliant with the SessionDataSchema.xsd schema.

The sessions processor is responsible for parsing this configuration file, ensuring it is valid to the schema and storing it in a bean which implements the com.qut.middleware.esoe.sessions.bean.SessionData as the value of com.qut.middleware.esoe.sessions.bean.SessionData.identity, this should be acheived by utilising the functionality of the [[https://jaxb.dev.java.net/|jaxb]] library. Any failure associated with the configuration file SHOULD result in the exception com.qut.middleware.esoe.sessions.exception.ConfigurationValidationException being populated and thrown.

The sessions processor exposes four components to the rest of the ESOE. com.qut.middleware.esoe.sessions.Create, com.qut.middleware.esoe.sessions.Query, com.qut.middleware.esoe.sessions.Update and com.qut.middleware.esoe.sessions.Terminate Each of these in turn may expose several public methods of interaction. Using Spring 2.0 and its IoC functionality each of these are injected to the sessions processor.

The Sessions Processor also stores a central session identity cache. This is indexed by the session identifier supplied with the principal has been successfully authenticated by an authentication handler.

Create

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.impl.\*
Type CreateImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.Create
Exceptions DataSourceException

The create component is responsible for creating new sessions within the ESOE. It exposes two public methods to fullfill this purpose createLocalSession and createDistributedSession. Using Spring 2.0 and its IoC functionality the create component has the system identity resolver injected at runtime.

createLocalSession

This function takes a unique session identifier for the session and the user identification string they used to authenticate to the system, this should be the same value which is used to resolve all their identity details from backend identity stores.

The identity resolver is responsible for assembling all portions of the identity. In order to interact with the resolver the stored reference to com.qut.middleware.esoe.sessions.bean.SessionData should be retrieved. A bean of type com.qut.middleware.esoe.sessions.bean.IdentityData should be created. The value of com.qut.middleware.esoe.sessions.bean.SessionData.identity (which corresponds to the <Identity> element in the session processor configuration) should be copied to com.qut.middleware.esoe.sessions.bean.IdentityData.identity. The value of com.qut.middleware.esoe.sessions.bean.IdentityData.sessionID should be set the supplied unique session identifier. The value of com.qut.middleware.esoe.sessions.bean.IdentityData.principalName should be set to the supplied user identifier.

com.qut.middleware.esoe.sessions.bean.IdentityData.attributes is special, it stores a hashmap with the name of the identifier as the key and an Object which implements the interface com.qut.middleware.esoe.sessions.bean.IdentityAttribute as a value. Within the identity processor ALL identity values are stored as their corresponding object data type, for example int is stored as Integer. The interface defines com.qut.middleware.esoe.sessions.bean.IdentityAttribute.type in which the string representation of the contained type is stored. It also defines com.qut.middleware.esoe.sessions.bean.IdentityAttribute.delimiter in which any configured delimiter value is stored. It also defines com.qut.middleware.esoe.sessions.bean.IdentityAttribute.values which is an Object vector to store the values of this piece of identity.

For each attribute identified by com.qut.middleware.esoe.sessions.bean.IdentityData.identity a corresponding entry MUST be created in com.qut.middleware.esoe.sessions.bean.IdentityData.Attributes. The type SHOULD be set to the value of Type for this Attribute, the delimiter SHOULD be set to the value of Delimiter.

Once this bean is prepared the execute function on the identity resolver should be called.

Handled return values

com.qut.middleware.esoe.sessions.identity.IdentityResolver.result.Successful

Once this value has been recieved from the identity resolver a bean that implements com.qut.middleware.esoe.sessions.Principal should be generated. The value of com.qut.middleware.esoe.sessions.Principal.attributes should be set to the value of com.qut.middleware.esoe.sessions.bean.IdentityData.attributes. The value of com.qut.middleware.esoe.sessions.Principal.principalName should be set to the value of com.qut.middleware.esoe.sessions.bean.IdentityData.principalName. The value of com.qut.middleware.esoe.sessions.Principal.authnTimestamp MUST be set the current value of UTC. The value of com.qut.middleware.esoe.sessions.Principal.samlAuthnIdentifier should be generated by the Identity Generator and added to the principal.

Once populated this bean should be stored in the session identity cache. Its index MUST be set to com.qut.middleware.esoe.sessions.bean.IdentityData.sessionID.

The value com.qut.middleware.esoe.sessions.Create.result.SessionCreated should be returned to the caller.

Once the session is successfully established the principal MUST be also associated with the session identity cache by the value of its samlAuthnIdentifier

Handled exceptions

com.qut.middleware.esoe.sessions.exception.DataSourceFailure

This exception should not be caught, instead it should be pased up the call stack.

createDistributedSession

Exceptions

Identity Resolver

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.identity.impl.\*
Type IdentityResolverImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.identity.IdentityResolver
Exceptions DataSourceException, HandlerRegistrationException

To allow the correlation of disparate identity sources the Indentity Resolver is primarily concerned with the utilisation of the identity handler pipeline. Using Spring 2.0 and its IoC functionality many unique handlers are registed with the system to handle the supported methods for retrieving identity associated with the principal. Each of these MUST implement the com.qut.middleware.esoe.sessions.identity.pipeline.Handler interface. Handlers are stored in com.qut.middleware.esoe.sessions.identity.IdentityResolver.registeredHandlers.

On initalisation the identity resolver MUST verify that at least one handler has been registered, failure to have at least one handler registered SHOULD result in the exception com.qut.middleware.esoe.sessions.exceptionHandlerRegistrationException.

Handlers are registered in a list data structure. For every request the session processor SHOULD traverse the entire list, and for each handler the execute function should be called. The com.qut.middleware.esoe.sessions.bean.IdentityData bean MUST be supplied to this interface. Handlers MAY add detail to this data structure but they MUST not remove any data from it. For each handler which is called the value of com.qut.middleware.esoe.sessions.bean.IdentityData.currentHandler must be set to value of com.qut.middleware.esoe.session.pipeline.Handler.handlerName.

Handled return values and actions

com.qut.middleware.esoe.sessions.identity.pipeline.Handler.result.Successful

When this value is returned the identity resolver must determine if any handlers remain to be evaluated in the registeredHandlers vector. If they do the next handler's execute method should be called, additionally the value of com.qut.middleware.esoe.sessions.bean.IdentityData.currentHandler must be set to the value of com.qut.middleware.esoe.authn.pipeline.Handler.handlerName.

If no further handlers are present the value com.qut.middleware.esoe.sessions.identity.IdentityResolver.result.Successful should be returned.

Handled exceptions and actions

com.qut.middleware.esoe.sessions.exception.DataSourceException

This exception should not be caught, instead it should be pased up the call stack.

Handlers

Handlers are responsible for actually carrying out some kind of action in regards to retrieving identity. All handlers in the identity pipeline are evaluated when an identity creation of update request takes place within the ESOE. In the identity sense there is only one type of handler, it is passive, the principal is not aware it is happening.

A handler MUST NOT overwrite or remove attribute data set elsewhere in the pipeline.

Handlers MAY retrieve data from any source they wish, LDAP, Databases, web services and flat files to name a few examples. Additionally they MAY be written to simply always append a static value to some piece of identity information or to create a completely new piece of identity information by combining two previously set values.

Handlers utilise the value of com.qut.middleware.esoe.sessions.bean.IdentityData.identity to iterate through all values in the identity configuration. To attempt to populate values for an attribute the handler MUST ensure that the configuration has specified the handler should handle this attribute, that is the value of <Handler> for the <Attribute> MUST match the value of com.qut.middleware.esoe.sessions.pipeline.Handler.name

LDAP Handler

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.identity.pipeline.handler.impl.\*
Type LDAPHandlerImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.identity.pipeline.Handler
Exceptions DataSourceFailure

The LDAP Handler is the default handler for the ESOE identity resolver in the distribution package.

The LDAP Handler utilises the functionality of Spring LDAP as an abstraction layer to make queries to the configured LDAP server, LDAP server pool or other LDAP instance and process results.

The LDAP Handler SHOULD loop through all attributes specified in com.qut.middleware.esoe.sessions.bean.IdentityData.identity. It should attempt to look for attributes which have been delegated to the handler 'com.qut.middleware.esoe.sessions.identity.pipeline.handler.impl.LDAPHandlerImpl'. If a the value of LocalIdentity has been set this should be stored as the value to query from the backend LDAP system.

Once all attributes which this handler is responsible for are located queries to the LDAP server should be made, attention should be paid to the value of Singleton and different execution paths taken for singleton vs non singleton types. Any attribute which has a unique local identity should be stored as the value for the overall attribute. Any exception which occurs in the LDAP library should be caught and the exception com.qut.middleware.esoe.sessions.exception.DataSourceException populated and thrown.

For each value returned its type should be determed by the corresponding value of com.qut.middleware.esoe.sessions.bean.IdentityAttribute.type in the corresponding object stored in com.qut.middleware.esoe.sessions.bean.IdentityData.Attributes. It should be converted to the Object type that represents it (in the case of non String) and added to com.qut.middleware.esoe.sessions.bean.IdentityAttribute.values vector.

On successful completion the handler MUST return com.qut.middleware.esoe.sessions.identity.pipeline.Handler.result.Successful

Query

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.sessions.impl.\*
Type QueryImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.Query
Exceptions InvalidSessionIdentifierException

The query component is responsible for supplying information to ESOE about sessions which already exist within the system.

queryAuthnSession

This method takes the identifier assigned to the principal during authn. This identifier is used as a key to the local session cache.

Once located in the session cache the object of type com.qut.middleware.esoe.sessions.Principal should be returned to the caller. Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.InvalidSessionIdentifierException should be populated and thrown.

querySAMLSession

This method takes the identifier assigned to the principal as com.qut.middleware.esoe.sessions.Principal.samlAuthnIdentifier by the [authentication authority|#Authentication Authority Processor]. This identifier is used as a key to the local session cache.

Once located in the session cache the object of type com.qut.middleware.esoe.sessions.Principal should be returned to the caller. Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.exception.InvalidSessionIdentifierException should be populated and thrown.

Update

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.impl.\*
Type UpdateImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.Update
Exceptions InvalidEntityIdentifierException, InvalidSessionIdentifierException

The update component is responsible for updating the com.qut.middleware.esoe.sessions.Principal with new session information as the principal moves between the ESOE and the various SPEPs.

It exposes three methods, updateSAMLAuthnIdentifier, updateEntityList and updateEntitySessionIdentifierList.

updateSAMLAuthnIdentifier

This method takes a session identifier and SAML identifier and stores the value in the associated com.qut.middleware.esoe.sessions.Principal at the location com.qut.middleware.esoe.sessions.Principal.samlAuthnIdentifier

Once complete the retrieved com.qut.middleware.esoe.sessions.Principal should be restored in the session cache, however this time with its key set to com.qut.middleware.esoe.sessions.Principal.samlAuthnIdentifier, this will allow equally fast access to the object regardless of which identifier is presented to the ESOE componenets.

Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.InvalidSessionIdentifierException should be populated and thrown.

updateEntityList

This method takes a session identifier and entity identifier and stores the value in the associated com.qut.middleware.esoe.sessions.Principal at the location com.qut.middleware.esoe.sessions.Principal.activeEntities. This a hashmap which uses the descriptorID as a key and stores an object of type vector.

Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.exception.InvalidSessionIdentifierException should be populated and thrown.

updateEntitySessionIdentifierList

This method takes a session identifier, entity identifier and SAML session index and stores the value in the associated com.qut.middleware.esoe.sessions.Principal at the location com.qut.middleware.esoe.sessions.Principal.activeEntities. This a hashmap which uses the descriptorID as a key. The value should be ADDED to the vector referenced by the key.

Should the entity identifier not exist as a key in com.qut.middleware.esoe.sessions.Principal.activeEntities the exception com.qut.middleware.esoe.exception.InvalidEntityIdentifierException should be populated and thrown.

Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.exception.InvalidSessionIdentifierException should be populated and thrown.

Terminate

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.sessions.impl.\*
Type CreateImpl
Implemented Interfaces com.qut.middleware.esoe.sessions.Terminate
Exceptions InvalidSessionIdentifierException

The terminate component is responsible for terminating sessions within the ESOE. It defines only a single public method terminateSession which takes a session identifier. This identifier is used as a key to the local session cache.

Once located in the session cache the object of type com.qut.middleware.esoe.sessions.Principal should be deleted. Should the identifier not exist in the cache the exception com.qut.middleware.esoe.sessions.exception.InvalidSessionIdentifierException should be populated and thrown.


ESOE Single Sign-on and Logout Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

SSO Servlet

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.sso.servlet.\*
Type SSOServlet
Implemented Interfaces N/A

The SSO Servlet is a control point for SSO requests. The servlet must conform to the Servlet 2.4 specification http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html, this servlet currently only supports standards compliant web browser user-agents.

The servlet will be used for all requests made to https://esoe.url/sso

The SSO Servlet SHOULD implement the saml-bindings-2.0 HTTP POST Binding as its primary method of communication with the SPEP.

Messages are encoded for use with this binding by encoding XML into an HTML form control and are transmitted using the HTTP POST method. The SPEP generated SAML <AuthnRequest> is form-encoded by applying the base-64 encoding rules to the XML representation of the message and placing the result in a hidden form control within a standard html form. The form control MUST be named SAMLRequest. The SSO Servlet MUST decode this value.

A bean which implements the interface com.qut.middleware.esoe.sso.bean.SSOProcessorData must be passed by the servlet to the SSO Processor, it MUST be initalised by the servlet. This bean MAY contain value of the users session identifier. Incoming requests from the user-agent will provide session identifiers, in this case in the form of cookies. The identity of the cookie to be utilised is configurable, if present its value MUST be stored in com.qut.middleware.esoe.sso.bean.SSOProcessorData.sessionID. Additionally any SAML request which has been recieved MUST be stored in com.qut.middleware.esoe.sso.bean.SSOProcessorData.samlRequestDocument. For each request that enters the servlet an object of type javax.servlet.http.HttpServletRequest is supplied by the container as is an object of type javax.servlet.http.HttpServletResponse. These are to be stored as the value of httpRequest and httpResponse respectively in com.qut.middleware.esoe.sso.bean.SSOProcessorData

Once the servlet now MUST call the SSO Processor execute function.

Responding to the SPEP

The SSO Servlet should determine a valid binding for the SPEP favoring the SAML POST binding.

Messages are encoded for use with the POST binding by encoding com.qut.middleware.esoe.sso.bean.SSOProcessorData.samlResponseDocument into an HTML form control and are transmitted using the HTTP POST method. The generated SAML <Response> is form-encoded by applying the base-64 encoding rules to the XML representation of the message and placing the result in a hidden form control within a standard html form. The form control MUST be named SAMLResponse. A response document should be sent back to the http user-agent. A javascript event should be utilised to POST the document to com.qut.middleware.esoe.sso.bean.SSOProcessorData.responseEndpoint after 2 seconds.

Handled return values and actions

com.qut.middleware.esoe.sso.SSOProcessor.result.SSOGenerationSuccessful

The servlet should respond to the SPEP using its response mechanism.

com.qut.middleware.esoe.sso.SSOProcessor.result.LogoutSuccessful

Should not be handled by this servlet

com.qut.middleware.esoe.sso.SSOProcessor.result.ForcePassiveAuthn

The servlet should now respond to the SPEP using its response mechanism.

com.qut.middleware.esoe.sso.SSOProcessor.result.ForceAuthn

The user-agent MUST be redirected to the configured Authn provider for the user-agent on the ESOE, again currently only supporting standards compliant web browser user-agents, the url (incl post data) being requested at the Authn Filter MUST be attached using a name value pairing of esoeTarget=<url>

Handled exceptions and actions

com.qut.middleware.esoe.sso.exception.InvalidSessionIdentifierException

This exception MUST have all sessionIdentifiers (cookies in this case) stripped from the user-agent.

The servlet should now respond to the SPEP using its response mechanism.

Authentication Authority Processor

Component Lead Bradley Beddoes
Package com.qut.middleware.esoe.sso.impl.\*
Type SSOProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.sso.SSOProcessor
Exceptions InvalidSessionIdentifierException

The SSOProcessorImpl should firstly validate the Request

Any invalidly generated request must create and throw com.qut.middleware.esoe.sso.InvalidRequest

The value of <Issuer> should be retrieved and stored at com.qut.middleware.esoe.sso.bean.SSOProcessorData.descriptorID. The value of AssertionConsumerServiceIndex should be retrieved and stored at com.qut.middleware.esoe.sso.bean.SSOProcessorData.responseEndpointID. This value along with the descriptorID MUST be sent to the [[SPEP processor]|[#SPEP Processor]] to determine the URL of the SPEP endpoint to respond to. The value of com.qut.middleware.esoe.sso.bean.SSOProcessorData.responseEndpoint should be set as the response value. If this operation causes an exception it should be caught and com.qut.middleware.esoe.sso.InvalidRequest created and thrown.

Once this occured the value of <NameIDPolicy> AllowCreate MUST be determined. Once this is the case one of three actions MUST be taken:

The SSOProcessorImpl MUST now validate sessionIdentifier against the [[com.qut.middleware.esoe.sessions.Query.queryAuthnSession]|[#Query]] query component to ensure that it has been issued by the ESOE Authn Processor and is currently valid by requesting a com.qut.middleware.esoe.sessions.Principal. Any request that fails to be validated against the local session cache after having presented what it considered to be a valid session identifer MUST result in an com.qut.middleware.esoe.sso.exception.InvalidSessionIdentifierException exception being thrown.

If the value of ForceAuthn in the request is set to 'true' one of three actions MUST be taken

If the principal has not previously had an entry recorded for the SPEP being accessed in com.qut.middleware.esoe.sessions.Principal.activeEntities this indentifier should be added to the principal by calling the [[com.qut.middleware.esoe.sessions.Update.updateEntityList]|[#Update]] update component, supplying the sessionIdentifier and descriptorID as values.

A 10 byte SHA1 hash should be generated by the Identity Generator and added to the principal by calling the [[com.qut.middleware.esoe.sessions.Update.updateEntitySessionIdentifierList]|[#Update]] update component, supplying the sessionIdentifier, descriptorID and generated samlAuthnSessionIndex as values.

Details about the com.qut.middleware.esoe.sessions.Principal should now be refreshed by using the valid sessionIdentifer with the [[com.qut.middleware.esoe.sessions.Query.queryAuthnSession]|[#Query]] query component.

If the request has passed all processing logic and deemed to be valid an AuthnStatement must be created by generating a base SAML Statement additionally
AuthnInstant MUST be set to the UTC value of time the assertion was created with no time zone information.
SessionIndex SHOULD be set to the value generated for the current session
SessionNotOnOAfter SHOULD be set to the UTC value of the time the assertion was generated plus the configured time skew allowance (set at default of 60 seconds)
<Subject> MUST be set and MUST contain a <NameID> element. The value of this element SHOULD be set to com.qut.middleware.esoe.sessions.Principal.samlAuthnIdentifier
<AuthnContext> MUST be set and MUST contain an <AuthenticatingAuthority> its value MUST be set to https://esoe.url/logon

The statement MUST be wrapped in a SAML Assertion

The assertion MUST be wrapped in a SAML Response

The completed SAML response should be stored at com.qut.middleware.esoe.sso.bean.SSOProcessorData.samlResponseDocument

The processor should now return control to the SSO Servlet with a value of com.qut.middleware.esoe.sso.SSOProcessor.result.SSOGenerationSuccessful.

Logout Servlet

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.logout.servlet.\*
Type LogoutServlet
Implemented Interfaces N/A

The Logout Servlet is a control point for Logout requests. The servlet must conform to the Servlet 2.4 specification http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html, this servlet currently only supports standards compliant web browser user-agents.

The servlet will be used for all requests made to https://esoe.url/logout

A bean which implements the interface com.qut.middleware.esoe.logout.bean.LogoutProcessorData must be passed by the servlet to the Logout Processor, it MUST be initalised by the servlet. This bean MAY contain value of the users session identifier. Incoming requests from the user-agent will provide session identifiers, in this case in the form of cookies. The identity of the cookie to be utilised is configurable, if present its value MUST be stored in com.qut.middleware.esoe.sso.bean.SSOProcessorData.sessionID. For each request that enters the servlet an object of type javax.servlet.http.HttpServletRequest is supplied by the container as is an object of type javax.servlet.http.HttpServletResponse. These are to be stored as the value of httpRequest and httpResponse respectively in com.qut.middleware.esoe.sso.bean.SSOProcessorData

Once the servlet now MUST call the Logout Processor execute function.

Handled return values and actions

com.qut.middleware.esoe.logout.LogoutProcessor.result.LogoutSuccessful

Once the logout is deemed to be completed the Logout Servlet should determine if 'disablesso' was presented by the user of the system. If it is present the Logout Servlet SHOULD create a cookie with a scope of https://esoe.url/ and named as configured for ESOE disablesso cookie. Its value should simply be set to 'disablesso'. The cookie SHOULD be stored in the response by calling the methods supplied in com.qut.middleware.esoe.logout.bean.LogoutProcessorData.httpResponse

The Logout Servlet must determine where to direct the principal. If the value of esoelogout_response was supplied the implementation MAY choose to redirect the user to location configured for the supplied identifier by setting the URL as the value of com.qut.middleware.esoe.logout.bean.LogoutProcessorData.responseURL. Should the implementation not wish to honor this value or it is not supplied com.qut.middleware.esoe.logout.bean.LogoutProcessorData.responseURL should be set to the configured default for the ESOE.

The user-agent MUST be redirected to the configured URL for successful logout requests for the ESOE.

Handled exceptions and actions

com.qut.middleware.esoe.logout.exception.InvalidSessionIdentifierException

This exception MUST have all sessionIdentifiers (cookies in this case) stripped from the user-agent.

The user-agent MUST be redirected to the configured URL for failed logout requests for the ESOE.

com.qut.middleware.esoe.logout.exception.InvalidLogoutRequestException

The user-agent MUST be redirected to the configured URL for failed logout requests for the ESOE.

Logout Processor

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.logout.impl.\*
Type LogoutProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.sso.SSOProcessor
Exceptions InvalidSessionIdentifierException

The LogoutProcessorImpl operates on a form post event coming from the principal.

The form SHOULD be created with a method of post, a target of https://esoe.url/logout a name of esoesso_logout and autocomplete set to off. The form MUST expose an input field named disablesso, type checkbox. The form creator MAY choose to implement the hidden field esoelogout_response, where the value of this field is a numeric value representing the prefered logout page to respond to as configured for the LogoutProcessorImpl. This allows the ESOE to be utilised for multiple logout pages within an enterprise should the single logout portal not be sufficent.

If the request form is considered to be invalid the LogoutProcessorImpl MUST populate and throw the exception com.qut.middleware.esoe.sso.exception.InvalidLogoutRequestException

The LogoutProcessorImpl MUST validate the com.qut.middleware.esoe.sso.bean.SSOProcessorData.sessionID value against the [[com.qut.middleware.esoe.sessions.Query.queryAuthnSession]|[#Query]] query component to ensure that it has been issued by the ESOE Authn Processor and is currently valid by requesting com.qut.middleware.esoe.sessions.Principal. Any request that fails to be validated against the local session cache after having presented what it considered to be a valid sessionIdentifer MUST result in a com.qut.middleware.esoe.sso.InvalidSessionIdentifierException exception being thrown.

Each descriptorID for the com.qut.middleware.esoe.sessions.Principal.activeEntities list SHOULD be traversed.

For each descriptorID
A request supplying the descriptorID should be sent to the [[SPEP processor]|[#Endpoint Resolver]] endpoints for single logout.

For each effected descriptorID/endPoint combination a LogoutRequest MUST be created by generating a base [[Request]|[SAML Document Descriptors#Generating Requests]] and addtionally specifying:
NotOnOrAfter SHOULD be set to the UTC value of the current system time plus the configured time skew allowance (set at default of 60 seconds)
Reason SHOULD be set to "https://esoe.url/logout"
<NameID> \- This value MUST be set to the principals samlAuthnIdentifier
<SessionIndex> \- This value MUST be set to the sessionIndex of the session being terminated.

For each request generated the injected IDPSSOWS instance single logout service should be called and the generated SAML message and currently processing endpoint supplied. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. Where these conditions are not met or an exception is returned by IDPSSOWS a bean implementing com.qut.middleware.esoe.logout.bean.FailedLogout must be created. The SAML request document must be stored at com.qut.middleware.esoe.logout.bean.FailedLogout.requestDocument, the current endpoint at com.qut.middleware.esoe.logout.bean.FailedLogout.endPoint. This bean should be supplied to the injected failed logout monitor.

The session information should be cleaned up on the ESOE by calling [[com.qut.middleware.esoe.sessions.Terminate.terminateSession]|[#Terminate]] terminate component and supplying the session identifier.

The processor should now return control to the Logout Servlet with a value of com.qut.middleware.esoe.sso.LogoutSuccessful.

Failed logout Monitor

The failed logout monitor consistently looks at a repository of com.qut.middleware.esoe.logout.bean.FailedLogout beans. Once it reaches the end of the repository it MUST immediently start at the beginning and work its way back through again attempting to deliver logouts to SPEPs. On startup the monitor is to be created in its own thread, this thread MUST continuously stay active until the shutdown of the system. Should it fail in some way it MUST be automatically recovered by the system.

For each bean stored in the repository the generated document stored at com.qut.middleware.esoe.logout.bean.FailedLogout.requestDocument should be regenerated with updated timestamps and signatures to avoid time problems and the new document re-stored at this location. The injected IDPSSOWS instance single logout service should now be called with com.qut.middleware.esoe.logout.bean.FailedLogout.requestDocument and com.qut.middleware.esoe.logout.bean.FailedLogout.endPoint supplied. A SAML response document MUST be returned. The SAML response contained should be validated and a status of urn:oasis:names:tc:SAML:2.0:status:Success assured. If this is the case the bean is ejected from the local repository.

If this check fails the value of com.qut.middleware.esoe.sso.bean.FailedLogout.TimeStamp should be evaluated. If it is older then the time configured as a maximum (default of 24hrs) the bean is ejected from the local repository.

Where these conditions are not met or an exception is returned by IDPSSOWS the bean should remain in the local repository.

External components will supply additional failed logout to be added to the repository at random intervals. When they are supplied the repository MUST be locked for both read and write access while the new data is added. For each bean placed into the repository the value of com.qut.middleware.esoe.logout.bean.FailedLogout.TimeStamp must be set to the current system time.


ESOE SPEP Processor Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

SPEP Processor

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.spep.impl.\*
Type SPEPProcessorImpl
Implemented Interfaces com.qut.middleware.esoe.spep.SPEPProcessor

The SPEP processor communicates with SPEP instances to ensure they have all information necessary in order to perform their roll. It also takes advice from SPEP's when they perform certain actions that is recorded centrally for possible future usage.

SPEP Startup Component

Component Lead Andre Zitelli
Package com.qut.middleware.esoe.spep.impl.\*
Type StartupImpl
Implemented Interfaces com.qut.middleware.esoe.spep.Startup
Exceptions InvalidRequest, DatabaseFailureNoSuchSPEP, SPEPCacheUpdateFailure

Verify the supplied value of [com.qut.middleware.esoe.spep.bean.SPEPProcessorData.requestDocument|#Verifying Requests]. Any invalid request MUST set com.qut.middleware.esoe.aa.bean.SPEPProcessorData.responseDocument to a <ValidateInitalizationResponse> by creating a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Requestor then create and throw com.qut.middleware.esoe.spep.exception.InvalidRequestException.

The value of <Issuer> should be retrieved and stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.requestEntityID.
The value of <authzCache> should be retrieved and stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.authzEndpointID.

Using iBatis database stack the supplied value com.qut.middleware.esoe.spep.bean.SPEPProcessorData.requestEntityID will be checked to ensure it exists in the table SPEP_REGISTRATION. If it does not a new record should be created in this table and store with it all the supplied values of ipAddress, compileDate, compileSystem, version and environment. An identical record SHOULD be stored in SPEP_REGISTRATION_HISTORY.

If a record already exists the values of ipAddress, compileDate, compileSystem, version and environment will be checked against the table SPEP_REGISTRATION. If ALL values are equal, then no further processing is undertaken. If any value is different all values of ipAddress, compileDate, compileSystem, version and environment should be written to the table and date_last_updated set to the current date. A new record should also be created in SPEP_REGISTRATION_HISTORY

If a primary key constraint exception occurs in the database the statup component MUST set the value of com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument to a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Requestor then create and throw com.qut.middleware.esoe.spep.exception.DatabaseFailureNoSuchSPEPException

If other exceptions occur the statup componenet MUST set the value of com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument to a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Responder then create and throw com.qut.middleware.esoe.spep.exception.DatabaseFailureException

Once database updates have been made the com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor SPEP Start component should be called and supplied the values com.qut.middleware.esoe.spep.bean.SPEPProcessorData.requestEntityID and com.qut.middleware.esoe.spep.bean.SPEPProcessorData.authzEndpointID. This inturn will make its own connection back to the SPEP and deliver initial caching state

Handled return values and actions

com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor.result.Failure

The startup component MUST set com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument to a <ValidateInitalizationResponse> by creating a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Requestor then create and throw com.qut.middleware.esoe.spep.exception.SPEPCacheUpdateException.

com.qut.middleware.esoe.pdp.cache.PolicyCacheProcessor.result.Successful

The startup component MUST set com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument to a <ValidateInitalizationResponse> by creating a base response with <Status> of urn:oasis:names:tc:SAML:2.0:status:Requestor The startup component should then return.


ESOE to Active Directory Authentication Handler Installation Guide

Authors
Andre Zitelli
Bradley Beddoes

Applicable versions
Beta 1

Configuring the SPNEGO handler for integrated Active Directory SSO

This section assumes the reader has a reasonably detailed understanding of the Kerberos V5 authentication protocol. Additionally, an understanding of the Microsoft GSS extension of Kerberos may be helpful. The SPNEGO handler is dependent on the existence of a Kerberos KDC and AS. At the time of writing, only an Active Directory KDC has been tested with the handler. Below are some articles that may be of assistance.

http://msdn2.microsoft.com/en-us/library/ms995329.aspx
http://web.mit.edu/kerberos/www/
http://unix.lsa.umich.edu/docs/mit-kerberos/install_3.html
http://www.upenn.edu/computing/pennkey/sysadmin/e_install_win/win-config.html
http://www.microsoft.com/technet/prodtechnol/windows2000serv/howto/kerbstep.mspx

There must be a an existing Kerberos server before the SPNEGO handler can be configured to a working state. Once you have the Kerberos server up and running, you may continue with handler the configuration.

Enabling the SPNEGOHandler

By default, the SPNEGO authentication mechanism is disabled. We recommend you extract the ESOE ROOT.war file supplied to you to enable the Active Directory connector. Steps for enabling the connector are as follows:

  1. Create a directory called ROOT in your home directory
  2. Copy ROOT.war to ROOT
  3. Change to the ROOT directory and execute "jar -xf ROOT.war"
  4. Delete ROOT.war
  5. File: WEB-INF/esoeContext.xml
    Uncomment <import resource="resources/authentication/handlers/authenticators/kerberosV5Authenticator.xml" />
    Uncomment <import resource="resources/authentication/handlers/SPNEGOHandler.xml" />
  6. File: WEB-INF/resources/authentication.xml
    Uncomment <ref bean="spnegoHandler" />
  7. Extract and untar the file esoeauthn-ad.tar.gz which you have retrieved from our downloads area and copy the jar esoeauthn-ad.jar to WEB-INF/lib
  8. Recreate the war by running the command "jar -cf ../ROOT.war *". This will create ROOT.war in the parent directory

We release updates to ESOE as the default packaged ROOT.war file, please be aware you'll need to undertake this process when you deploy updates

Configuring the Kerberos realm.

The SPNEGO Handler must be configured to talk to a specified Kerberos realm KDC. The location of the realm configuration files are specific to the platform being used to host the ESOE (usually /etc/krb5.conf on \*NIX). This is configured as a standard Kerberos V5 configuration file and will be picked up by the SPNEGO handler (or more correctly, by native Kerberos libraries used by the JVM) on startup for processing. See the configuration file provided with the ESOE (krb5.conf) application deployment for an example configuration.

Setting up the ESOE authentication Principal on the AD KDC

An account must exist on the AD KDC for communication between the ESOE and the KDC. This account will have an associated Kerberos format keytab file and SPN generated in order to perform kerberos validation of the client credentials. The following steps must be performed on the AD domain controller in order to allow the ESOE to communicate with the KDC.

  1. Create the account that will be used by the ESOE. A normal user account will do fine. The placement of the account within the domain structure of Active Directory is up to you.
  2. Map the user account to the KDC by running the ktpass command. The ktpass command will map default SPN's to the specified user and create a kerberos keytab file that must be used by the ESOE to authenticate against the target Kerberos AS.
Example:
ktpass princ HTTP/esoe-dev.qut.edu.au@ADDEV.QUT.EDU.AU rndPass out HTTP.esoe-dev.qut.edu.au.keytab ptype KRB5_NT_PRINCIPAL mapuser esoe
...........
Targeting domain controller: qutadgp01-dev.addev.qut.edu.au
Using legacy password setting method
Successfully mapped HTTP/esoe-dev.qut.edu.au to esoe.
Key created.
Output keytab to HTTP.esoe-dev.qut.edu.au.keytab:
Keytab version: 0x502
keysize 76 HTTP/esoe-dev.qut.edu.au@ADDEV.QUT.EDU.AU ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x17
(RC4-HMAC) keylength 16 (0xc9e45125e632aa422a2ec781b0ea300c)
............

Where:

'princ' is the EXACT name of the service that will be providing the Kerberos SNPEGO authentication, prepended to the configured Kerberos realm. There must must also be a reverse mappable A record in DNS for this service DNS name. The SSO enabled client will use this name when presenting the Kerberos AS ticket via the SPNEGO protocol.

For example:

If the ESOE is hosted at http(s)://esoe.yourcompany.org, the principal specified must be HTTP/esoe.yourcompany.org@YOUR.REALM.ORG. Note the HTTP protocol identifier must match as well. When a client machine on the configured domain connects to [http://esoe.yourcompany.org], it will be challenged for a Kerberos ticket by the ESOE via the SPNEGO Negotiate protocol. The client will send a request to the KDC for a TGT for the service it was challenged by, which will then be mapped to the SPN by the Kerberos AS. If the mapping is successful then the GSS negotiation can continue.

And where:

mapuser 'user' is the AD account created in step 1 above. Note if you choose to use a machine account or other you will need to change the value of ptype to a suitable option.

It is suggested that you use the 'rndPass' switch to avoid password policy issues on the domain controller.

Configuring SPNEGO parameters in esoe.config

Your esoe.config file located at esoe.data/config/esoe.config must be updated with the key data and other configuration to advise ESOE of your AD environment. This only needs to be undertaken once, not each time you upgrade unlike WAR rebuilding. Each of the configuration options below are disabled by default with a leading '#' character. Be sure to remove that.

Before challenging the client with an SPNEGO Negotiate header, the ESOE SPNEGO handler will look for a configured user-agent header supplied by the client. This is to ensure that the authenticating client is in fact a member of an AD (or Kerberos) domain, thus having the required credentials to complete a successful Kerberos authentication. Ie: The presence of the header is an assumption that the client browser has been configured for SSO.

The header string that the SPNEGO handler will look for is configured at the following parameter:
# Identifier name for browsers integrated into Active Directory
activeDirectoryBrowserId=someStringSSOEnabled

The configured string MUST be the same as the string used in the browser configuration guides below. Note: The user-agent header provided by the client browser does not need to exactly match this string, it must simply contain the exact string. Your also required to configure the server principal and keyTab details you created above in interacting with the domain controller.
# Identifier for server principal in Active Directory
serverPrincipal=HTTP/esoe-dev.qut.edu.au

The above parameter must be set to the SPN mapped to the Kerberos user in '2' above.
# Keytab for communication with Active Directory
keyTab=file://${esoe.data}/config//HTTP.esoe-dev.qut.edu.au.keytab

The above parameter must be set to the keytab file generated in '2' above, copied to the ESOE host.

To communicate with domain contollers ensure you've correctly copied the keytab file you've created to esoe.data/config/<keytabfilename> on each host running ESOE.

For the following lines in esoe.config please remove the leading '#' character to enable this configuration

spnegohandler.successURL=${successURL}
spnegohandler.spnegoUserAgentID=${activeDirectoryBrowserId}
spnegohandler.securityLevelIdentifier=${securityLevelIdentifer}
spnegohandler.securityLevel=${securityLevel1}

...

kerberosV5Authenticator.option.serverPrincipal=${serverPrincipal}
kerberosV5Authenticator.option.useKeyTab=true
kerberosV5Authenticator.option.storeKey=true
kerberosV5Authenticator.option.doNotPrompt=true
kerberosV5Authenticator.option.debug=true
kerberosV5Authenticator.file.keyTab=${keyTab}

Browser configuration settings

The most important part of browser configuration is ensuring the value of activeDirectoryBrowserId is presented by the browser when making requests of the ESOE.

The browser ID header can be configured manually in the browser for non IE browsers, or by group policy application by the domain controller for IE browsers on computers joined to an AD domain.

Firefox configuration:

Internet explorer Configuration;

Note: This method has only been tested on WinXp SP2. Configurations may vary on other versions.

AD policy configuration:

You can configure Active directory to globally apply the required settings to IE so that manual configuration is not required.

Useful tools:

Kerbtray

TroubleShooting

  1. SPNEGO auth fails with the browser displaying a 401 error stating 'SPNEGO Negotiate protocol required'.

This indicates that the browser has been configured to send the user-agent string that informs the ESOE that it is a member of the configured kerberos realm, yet it has not been configured to send SPNEGO data. Ensure that the activeDirectoryBrowserId parameter has been set in esoe.config. Recheck the browser configuration steps above to ensure the trusted domain has been setup correctly.

  1. SPNEGO auth keeps failing, with the esoe-core logs stating the browser did not send the correct token.
Ensure that your kerberos domain realm configuration is correct. The domain portion of the krb5.conf file must match the service that the user is attempting to access (Ie the ESOE), else the browser will attempt to provide NTLM authentication instead of an SPNEGO token. For example
[domain_realm]

        .your.esoe.com = YOUR.CONFIGURED.KERB.REALM
         your.esoe.com  = YOUR.CONFIGURED.KERB.REALM


If the esoe was actually hosted on my.esoe.com, or even esoe1.your.esoe.com, the SPNEGO auth will fail.

http://forum.java.sun.com/rss/rssmessages.jspa?RssUsername=Seema-1&numItems=60
http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.html
http://docs.sun.com/app/docs/doc/816-5174/6mbb98ugh?a=view

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup Active Directory integration for ESOE. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE to OpenID Authentication Delegator Installation Guide

Authors
Bradley Beddoes

Applicable versions
Beta 2

Overview

The OpenID authentication delegator allows the ESOE to accept openID credentials as authoritative sources of authentication for access to the ESOE and its associated applications. Enabling OpenID however does not mean that all your applications are able to be accessed by clients using this technology to authenticate. By carefully setting authorization policies for your services you can ensure that external clients are only able to access a small subset of services and content within services that you explicitly wish to make available to them.

OpenID is largely an untrusted technology, anyone can create an OpenID for themselves, you should carefully consider where it makes sense to trust this technology. Some examples to date have been applications which would otherwise allow anonymous sign up and/or access anyway such as shopping carts and collaborative tools such as wiki's where everyone is allowed to participate but you need some kind of identifier to track comments and edits.

Preparing Installation

You need to make a few decisions about your environment before continuing with the delegator installation.

  1. Where will the delegator live host wise? It must be deployed either in the same container as the ESOE itself or on a host that is part of your ESOE subdomain hierachy.
    For example if your ESOE instance is available at https://esoe.company.com you may deploy the delegator on a server accessed by https://openid.esoe.company.com or https://esoe.company.com but not a server accessed by http://openid.company.com
  2. Where you intend to run the setup program from. The OpenID delegator has an interactive console based process to setup your new delegator instance. It needs read access to both esoe.config and esoeKeystore.ks - Some users may choose to do this on the live ESOE host, we reccomend copying both these files to a work space somewhere and basing access to these copies.

To install create a directory called openid and extract openiddelegator.tar.gz to it.

Run the following command:
java -jar installer.jar Startup
You will then be presented with "Welcome to the Enterprise Sign On Engine, OpenID installation process". A series of questions will follow as shown below:
Please enter the ESOE keystore location (eg: ${esoe.data}/config/esoeKeystore.ks):
Please enter the ESOE configuration file location (eg: ${esoe.data}/config/esoe.config):
Please enter the URL where users will interact with the ESOE OpenID component (eg: https://esoe.company.com/openiddelegator - must end in openiddelegator):
Are you deploying the delegator in a https offloaded, load balanced environment (n): n
Please enter the amount of time in years the openID delegator should have a valid key for ESOE communication (eg: 2): 2
Please enter the directory where you have extracted the openid delegator files to (eg: /home/username/openiddelegator): 
Please enter a directory this application can write to (eg: /tmp/openiddelegator): 
This will lead to a prompt to ensure everything is correct as below:
Is the following information correct?:
ESOE keystore location: /usr/local/site/esoe/data/core/config/esoeKeystore.ks
ESOE configuration file: /usr/local/site/esoe/data/core/config/esoe.config
OpenID URL: https://esoe-tst.qut.edu.au/openiddelegator
Key validity period in years: 2
Location of extracted files: /home/beddoes/0.3.99/openid
Output Directory: /home/beddoes/0.3.99/openid
Yes (Y) / No (N) [N] :    
When you're happy enter Y, a N value will allow you to correct mistakes. A Y value will lead to:
*** Configuring your openID delegator please wait....
*** Created keystores...
*** Rendered config...
Completed, files written to /dir. Copy openiddeleg.war to your tomcat instance, copy created files to ${openiddeleg.data}/config and after backing up your current esoeKeystore.ks replace with the newly generated version.

Configuration

The OpenID delegator relies on a Java property called openiddeleg.data. If your running on the same host as ESOE we reccomend you point this to a new directory in the same structure as your ESOE files e.g.
You already have /opt/data/core
Create a directory called /opt/data/openid
Set openiddeleg.data to /opt/data/openid

If your running on a different host we recommend you try and mirror the location you store config as best as possible.

Once openiddeleg.data is setup you should create a sub directory called config. Copy the files openidKeystore.ks and openiddelegator.config which were created in the previous stage to this location.

The next task is replacing esoeKeystore.ks. BEFORE DOING THIS TAKE A BACKUP OF YOUR CURRENT KEYSTORE, infact take 2 and feel extra safe. Copy the new esoeKeystore.ks to esoe.data/config/esoeKeystore.ks over writing the current Keystore.

User interaction

Login

Obviously to login using OpenID your users need somewhere to enter their domain details. We recommend this be accessible from your default login environment. You'll notice the default supplied web war has a space for this on the front page. Other implementors have chosen to have a link from the main page to a dedicated openID page. Regardless of the choice the requirements are the same. a Simple HTML form which looks like the following:
<form method="post" name="openidAuthenticator" action="/openiddelegator/login" id="esoe_login_form" autocomplete="off">

<input type="text"    name="openid_identifier" value="http://" id="openid_identifier">

<input type="submit" value="Login">

You may need to change the action target if the openID delegator does not run on the same host as your web application. Of course your also free to add any kind of fancy styling identifiers you wish. However the names of the form and elements are important and must be maintained as is.

Acceptance of attribute release

Users of the openID system must accept to release attributes about themselves before they are able to continue with a successful openID authentication. The content which is displayed at this stage is stored in your openiddelegator.war file. To customize it simply edit the page border-template.htm

You may place any HTML content to match your environment you wish to. however the following sections must be retained:

<head>
$imports
#if ($headInclude)
#parse($headInclude)
#end

<!-- add your head content if needed -->

</head>

and with the body you must keep the code:
 #parse($path)

where you wish the main content to appear.

We recommend you keep a copy of this customization as it will need to be re-applied after performing updates. We also recommend you rebuild the openiddelegator.war file at this time to save any loss o data on container restart.

Deployment

You should now be able to successfully copy your openiddelegator.war to your containers webapps directory and restart your container. You will also need to restart the ESOE container if its hosted elsewhere to pickup the change in keydata.

By attempting to access protected SPEP resources, being redirected to the ESOE login portal and then using your openID form created above you should be able to login to your systems using your openID successfully.

Logging

If you require assistance in debugging a problem the openID delegator uses log4j to provide output. You can access it by adding to your logging environment configuration similar to the following:
    <logger name="com.qut.middleware.delegator.openid">
        <level value="DEBUG" />
        <appender-ref ref="esoe-openid-logger" />
    </logger>

    <appender name="esoe-openid-logger" 
        class="org.apache.log4j.FileAppender">
        <param name="File" value="${openiddelegator.data}/logging/openid.log" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p %c - %m%n" />
        </layout>
    </appender>

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup openID integration. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE to Shibboleth Authentication Delegator Installation Guide

Authors
Bradley Beddoes

Applicable versions
Beta 2

Applicable Shibboleth Versions
Shibboleth 1.3f

Overview

The shibboleth authentication delegator allows the ESOE to accept shibboleth credentials as authoritative sources of authentication for access to the ESOE and its associated applications. Enabling shibboleth however does not mean that all your applications are able to be accessed by clients using this technology to authenticate. By carefully setting authorization policies for your services you can ensure that external clients are only able to access a small subset of services and content within services that you explicitly wish to make available to them.

Shibboleth is a technology used largely within education arenas for federation of identities and to provide access to resources. By combining ESOE with shibboleth your Education partners can access your local content without requiring local accounts. Furthermore you can get trusted attribute data about that client from their institution for use in local provisioning activities.

Preparing Shibboleth Installation

Going through shibboleth deployment is out of scope for this document. We instead point you towards the shibboleth configuration guide at https://spaces.internet2.edu/display/SHIB

For the purposes of ESOE integration you must setup an SP which is protecting the resource https://<yourhostname>/shibdelegator which in turn must be exported to Tomcat using the Mod Jk tomcat connector for Apache. The configuration to do this for Mod Jk is:
# Integrate into ESOE Shibboleth delegator
<Location /shibdelegator>
  AuthType shibboleth
  ShibRequireSession On
  require valid-user
</Location>

JkMount /shibdelegator/* ajp13

Preparing Installation

You need to make a few decisions about your environment before continuing with the delegator installation.

  1. Where will the delegator live host wise? It must be deployed either in the same container as the ESOE itself or on a host that is part of your ESOE subdomain hierachy.
    For example if your ESOE instance is available at https://esoe.company.com you may deploy the delegator on a server accessed by https://shibboleth.esoe.company.com or https://esoe.company.com but not a server accessed by https://shibboleth.company.com. For the shibboleth delegator we recommend that a separate server be used due to added requirements of deploying apache and the shibboleth SP.
  2. Where you intend to run the setup program from. The Shibboleth delegator has an interactive console based process to setup your new delegator instance. It needs read access to both esoe.config and esoeKeystore.ks - Some users may choose to do this on the live ESOE host, we reccomend copying both these files to a work space somewhere and basing access to these copies.

To install create a directory called shibboleth and extract shibdelegator.tar.gz to it.

Run the following command:
java -jar installer.jar Startup
You will then be presented with "Welcome to the Enterprise Sign On Engine, Shibboleth installation process". A series of questions will follow as shown below:
Please enter the ESOE keystore location (eg: ${esoe.data}/config/esoeKeystore.ks):
Please enter the ESOE configuration file location (eg: ${esoe.data}/config/esoe.config): 
Please enter the URL where users will interact with the ESOE shibboleth component (eg: https://esoe.company.com/shibdelegator - must end in shibdelegator):
Please enter the amount of time in years the shibboleth delegator should have a valid key for ESOE communication (eg: 2):
Please enter the directory where you have extracted the shibboleth delegator files to (eg: /home/username/shibdelegator):
Please enter a directory this application can write to (eg: /tmp/openiddelegator):
This will lead to a prompt to ensure everything is correct as below:
Is the following information correct?:
ESOE keystore location: /usr/local/site/esoe/data/core/config/esoeKeystore.ks
ESOE configuration file: /usr/local/site/esoe/data/core/config/esoe.config
Shibboleth URL: https://esoe-tst.qut.edu.au/shibdelegator
Key validity period in years: 2
Location of extracted files: /home/beddoes/0.3.99/shibboleth
Output Directory: /home/beddoes/0.3.99/shibboleth
Yes (Y) / No (N) [N] :Y  
When you're happy enter Y, a N value will allow you to correct mistakes. A Y value will lead to:
*** Configuring your shibboleth delegator please wait....
*** Created keystores...
*** Rendered config...
Completed, files written to /home/beddoes/0.3.99/shibboleth. Copy shibdelegator.war to your tomcat instance, copy created files to ${shibdeleg.data}/config and after backing up your current esoeKeystore.ks replace with the newly generated version.

Configuration

The Shibboleth delegator relies on a Java property called shibdeleg.data. If your running on the same host as ESOE we recommend you point this to a new directory in the same structure as your ESOE files e.g.
You already have /opt/data/core
Create a directory called /opt/data/shibboleth
Set shibdeleg.data to /opt/data/shibboleth

If your running on a different host we recommend you try and mirror the location you store config at as best as possible.

Once shibdeleg.data is setup you should create a sub directory called config. Copy the files shibKeystore.ks and shibdelegator.config which were created in the previous stage to this location.

The next task is replacing esoeKeystore.ks. BEFORE DOING THIS TAKE A BACKUP OF YOUR CURRENT KEYSTORE, infact take 2 and feel extra safe. Copy the new esoeKeystore.ks to esoe.data/config/esoeKeystore.ks over writing the current Keystore.

User interaction

Login

To login to Shibboleth users need a link somewhere to access your Federation WAYF. This redirection is configured as part of your shibboleth SP. All thats required is a basic HTML link that points at your shibdelegator installation such as
<a href="https://shibboleth.esoe.mycompany.com/shibdelegator/login">Login using Shibboleth for Australian Higher Education</a>

The normal shibboleth SP interaction then takes over from that point doing WAYF access and remote IDP communication. Note it must point at /shibdelegator/login not just vanilla /shibdelegator

If in fact you wanted to participate in multiple federations you could deploy multiple Shibboleth SP's which have membership in each and simply provide multiple links.

Acceptance of attribute release

Users of the shibboleth system must accept to release attributes about themselves before they are able to continue with a successful shibboleth authentication. The content which is displayed at this stage is stored in your shibdelegator.war file. To customize it simply edit the page border-template.htm

You may place any HTML content to match your environment you wish to. however the following sections must be retained:

<head>
$imports
#if ($headInclude)
#parse($headInclude)
#end

<!-- add your head content if needed -->

</head>

and with the body you must keep the code:
 #parse($path)

where you wish the main content to appear.

We recommend you keep a copy of this customization as it will need to be re-applied after performing updates. We also recommend you rebuild the shibdelegator.war file at this time to save any loss of data on container restart.

Deployment

You should now be able to successfully copy your openiddelegator.war to your containers webapps directory and restart your container. You will also need to restart the ESOE container if its hosted elsewhere to pickup the change in keydata.

By attempting to access protected SPEP resources, being redirected to the ESOE login portal and then clicking on the Shibboleth federation link created above you should be able to login to your systems using remote shibboleth credentials successfully.

Logging

If you require assistance in debugging a problem the shibboleth delegator uses log4j to provide output. You can access it by adding to your logging environment configuration similar to the following:
    <logger name="com.qut.middleware.delegator.shib">
        <level value="DEBUG" />
        <appender-ref ref="esoe-shib-logger" />
    </logger>

    <appender name="esoe-shib-logger" 
        class="org.apache.log4j.FileAppender">
        <param name="File" value="${shibdelegator.data}/logging/shib.log" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p %c - %m%n" />
        </layout>
    </appender>

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup Shibboleth integration. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


ESOE Users

Welcome to the Enterprise Sign On Engine users space.

This space contains all the downloads, documentation and links to helpful places you will need to get the ESOE functioning quickly and correctly in your environment. We suggest that you take advantage of some of the features here such as RSS feeds, page watches and space watches to ensure your up to date with all the information which will be collated here.

Installation Documentation

Core components

ESOE Installation Guide
- ESOE Installation Additions - Debian
- ESOE Installation Additions - Redhat
- ESOE Installation Additions - Apache and Mod Proxy AJP
Securing ESOE in Unix Environments
Registering an SPEP with ESOE Manager
Java SPEP Installation Guide
Apache SPEP Installation Guide
- OSX Apache SPEP

Authentication Handlers

ESOE to Active Directory Authentication Handler Installation Guide

Authentication Delegators

ESOE to Shibboleth Authentication Delegator Installation Guide
ESOE to OpenID Authentication Delegator Installation Guide

Application Integrators

Integrating ESOE with Google Apps for your domain
Integrating ESOE with Blackboard
Integrating ESOE with Oracle Single Sign-On
Integrating ESOE with Confluence
SPEP Grails Plugin

Administration Documentation

ESOE Administration

ESOE Administrators Guide
Configuring Authorization Policies
Policy Templates

SPEP Administration

Configuring Authorization Policies
Policy Templates

Support and Mailing Lists

ESOE Features
ESOE License
ESOE Users Mailing List
ESOE Developers Mailing List

Downloads

ESOE

ESOE Downloads

SPEP

SPEP Downloads

Application Integration

Application Integration Downloads


ESOE Web Services Design

Enterprise Sign On Engine Technical Architecture
Written by Bradley Beddoes
September 2006

Architecture design by Bradley Beddoes
Incorporates SAML 2.0, and (L)XACML 2.0 OASIS standards

Contributions by:
Shaun Mangelsdorf
Andre Zitelli

Edited by:
Bradley Beddoes
Shaun Mangelsdorf
Andre Zitelli

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119

Web Services Interfaces

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.ws.\*

Web service interfaces in the ESOE are created using the Axis2, the ESOE makes use of RAWXMLInputOutput to ensure it gets the lowest level access possible to the creation and handling of the SOAP envelope.

All web serivce endpoints in the system are exposed using the Axis2 <-> Spring 2.0 IoC wiring interfaces to allow for customisable deployments.

WSClient

Component Lead Shaun Mangelsdorf
Package com.qut.middleware.esoe.ws.clients.WSClient
Exceptions WSClientException

The WSClient is responsible for communicating to SPEP's using web services when the IDP needs to provide them some kind of update.

This interface is only used to connect to SPEP, it does not specify an endpoint on which to receive incoming requests.

At the current time it implements functions for initiating an authz cache clear and single logout. These functions MUST be supplied with a valid SAML request document and a valid endpoint URI to connect to. The WSClient is solely responsible for handling all SOAP interactions and envelope wrapping/unwrapping.

Should the WSClient at any stage of communication encounter an exception or error state it MUST wrap this error or exception in WSClientException and throw for the caller to deal with.

WSProcessor

WSProcessor is the implementation of all logic for web services interfaces that the ESOE exposes for SPEP's to connect to. It is configured as the service class for Axis2 services.xml file and currently exposes three core functions.

Attribute Authority

This endpoint is responsible for receiving requests from the SPEP, this webservice does not initiate requests.

This service is accessible at the URL https://esoe.url/axis2/services/esoe/attributeAuthority

Using Spring, a processor will be injected into this descriptor, this object MUST implement the com.qut.middleware.esoe.aa.AttributeAuthorityProcessor interface. A bean which implements the interface com.qut.middleware.esoe.aa.bean.AAProcessorData interface must be created and SAML request object stored at com.qut.middleware.esoe.aa.bean.AAProcessorData.requestDocument. Once generated the execute function on the injected AttributeAuthorityProcessor MUST be called with the created bean as an argument.

Handled return values and actions

com.qut.middleware.esoe.aa.om.qut.middleware.esoe.aa.AttributeAuthorityProcessor.result.Successful

The value stored at com.qut.middleware.esoe.aa.bean.AAProcessorData.responseDocument should be wrapped in a SOAP response and sent back to the requestor.

Handled exceptions and actions

com.qut.middleware.esoe.aa.exception.InvalidRequestException

The value stored at com.qut.middleware.esoe.aa.bean.AAProcessorData.responseDocument should be wrapped in a SOAP response and sent back to the requestor.

Policy Decision Point

This endpoint is responsible for receiving requests from the SPEP, this webservice does not initiate requests.

This service is accessible at the URL https://esoe.url/axis2/services/esoe/policyDecisionPoint

Using Spring, a processor for lxacml requests will be injected into this descriptor, this object MUST implement the com.qut.middleware.esoe.pdp.AuthorizationProcessor interface. A bean which implements the interface com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData interface must be created. The SAML request document MUST be unwrapped from the SOAP message and stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.requestDocument. Once generated the execute function on the injected AuthorizationProcessor MUST be called with the created bean as an argument.

Handled return values and actions

com.qut.middleware.esoe.pdp.AuthorizationProcessor.result.Successful

The value stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.responseDocument should be wrapped in a SOAP response and sent back to the requestor.

Handled exceptions and actions

com.qut.middleware.esoe.pdp.exception.InvalidRequestException
The value stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.responseDocument should be wrapped in a SOAP response and sent back to the requestor.

com.qut.middleware.esoe.pdp.exception.InvalidPrincipalException
The value stored at com.qut.middleware.esoe.pdp.bean.AuthorizationProcessorData.responseDocument should be wrapped in a SOAP responseand sent back to the requestor.

SPEP Startup

This endpoint is responsible for receiving requests from the SPEP, this webservice does not initiate requests.

This service is accessible at the URL https://esoe.url/axis2/services/esoe/spepStartup

Using Spring, a processor for esoe requests will be injected into this descriptor, this object MUST implement the com.qut.middleware.esoe.spep.SPEPProcessor interface. A bean which implements the interface com.qut.middleware.esoe.spep.bean.SPEPProcessorData interface must be created and contain the SAML request object. Once generated the execute function on the injected ESOEProcessor MUST be called with the created bean as an argument.

Handled return values and actions

The startup service will not return a value, if no exception is thrown the value stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument should be wrapped in a SOAP evelope and HTTP document and sent back to the requestor.

Handled exceptions and actions

com.qut.middleware.esoe.spep.exception.CacheUpdateFailureException

The value stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument should be wrapped in a SOAP evelope and HTTP document and sent back to the requestor.

com.qut.middleware.esoe.spep.exception.InvalidRequestException

The value stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument should be wrapped in a SOAP evelope and HTTP document and sent back to the requestor.

com.qut.middleware.esoe.spep.exception.NoSuchSPEPException

The value stored at com.qut.middleware.esoe.spep.bean.SPEPProcessorData.responseDocument should be wrapped in a SOAP evelope and HTTP document and sent back to the requestor.

Delegated AuthN

This endpoint is responsible for receiving requests from the delegated Authn handlers with unique knowledge of some particular protocol, this webservice does not initiate requests.

This service is accessible at the URL https://esoe.url/axis2/services/esoe/delegatedAuthn

Further design doco to follow.


The Enterprise Sign On Engine (ESOE) allows an enterprise to achieve integrated identity management, single sign on, authorization, federation and accountability for resource access across multiple platforms and technology stacks. ESOE is built and maintained at the Queensland University of Technology, and open sourced to foster continued development in the community.

ESOE has been built utilizing open standards from OASIS such as SAML 2.0 and XACML 2.0 to provide the greatest amount of flexibility for implementors possible. This focus on open standards ensures that ESOE can integrate with solutions from other vendors easily who support these industry wide standards. These vendors include Google, Sun, Oracle and IBM.

Being heavily standards based, existing identity infrastructure such as LDAP compliant directories and databases can be easily leveraged in implementation. Additionally advanced enterprise deployments of Active Directory can be fully exposed to provide true single sign on from Windows desktops.

As the identity space is always changing, ESOE has future proofed itself with an ability to translate tokens between different formats. That means ESOE can support identities from remote sources such as those provided by OpenID. If a new or implementation specific token type comes up ESOE can be quickly expanded to take advantage.

All this functionality and all our source code is available for free under the Apache 2.0 license with community support.

Adopters

Projects used in ESOE


Integrating ESOE with Blackboard

Authors
Bradley Beddoes
Craig Comerford

Applicable versions (ESOE)
Beta 2, 0.51+

Applicable versions (Blackboard)
7.1+ 7.2+ 8.x to be testing Sept 08. NG will be configured and tested as soon as it is available.

Overview

Blackboard is an online learning and teaching environment in use at many large education institutions today. We have worked with the Blackboard API to integrate ESOE into Blackboard to handle all user authentication.

Installation

Blackboard installation builds from a standard Java SPEP install. You should first be familiar with the document Java SPEP Installation Guide and comfortable with a generic SPEP install. For blackboard locations and steps vary slightly from a standard install so we'll follow the guidelines below.

This document assumes that $blackboard is the home directory of your blackboard installation. e.g: /usr/local/blackboard

You will need to download the SPEP and Blackboard integrator binaries to undertake this work from Downloads and have them available on your host before continuing.

spepinteg-blackboard.tar.gz (contains spepinteg-blackboard.jar), spep.tar.gz (contains spep-endorsed.tar.gz, spep.config and spep.war), spepfilter.tar.gz.

Preparing your server

To successfully operate the Blackboard SPEP integration your server must be accessible on port 443 from the ESOE system. You can ask your ESOE system administrator for the IP addresses ESOE will connect from if your running a restrictive firewall policy and update it appropriately. In some circumstances your administrator may allow you to configure port 80 unsecured SPEP instances. This is a per installation decision which your ESOE system administrator can advise you of.

The procedure for installing binaries is as follows (ensure permissions are set correctly for your blackboard user):
  1. Backup jar files in $blackboard/apps/tomcat/common/endorsed. For Version 9 (Tomcat 6) the endorsed directory by default is no longer used so create a new directory "endorsed" $blackboard/apps/tomcat so you will copy the jars to $blackboard/apps/tomcat/endorsed. Point 13 relates to this. For further reference see http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html and http://java.sun.com/javase/6/docs/technotes/guides/standards/index.html.
  2. Extract spep-endorsed.tar.gz to $blackboard/apps/tomcat/common/endorsed
  3. Extract spep.tar.gz to a local working directory
  4. Create a directory called spep in your local working directory and extract the spep.war file inside this directory (this will look like the spep directory for a normal tomcat webapps deployment of spep.war)
  5. Copy the spep directory to $blackboard/webapps/spep
  6. Create a core directory to store spep artifacts, a sub directory called config to store configuration and a sub directory called logging for log files. This must be readable by the user blackboard runs as. e.g /opt/spep/config and /opt/spep/logging
  7. Copy the spep.config file to the configuration directory e.g /opt/spep/config/spep.config
  8. At this point you have a choice in how to advise the SPEP install of your configuration location
    1. Java Property (RECOMMENDED). Export a java property called spep.data to your Java environment when blackboard starts. This should be set to the top level artifacts directory. e.g -Dspep.data=/opt/spep
      To do this correctly for blackboard edit the file $blackboard/apps/tomcat/bin/blackboard-tomcat.sh.bb, look for the settings of JAVA_OPTS, append the line:
      JAVA_OPTS="$JAVA_OPTS -Dspep.data=/opt/spep"
    2. Create a Java properties file called spepvars.config and place it in $blackboard/webapps/spep/WEB-INF/ this is a standard java properties file format, set the variable spep.data to the same value you would above. We don't recommend this method though it may be useful in a multi spep environment, be sure to save your spepvars.config file safely, it will need to be copied back to the web application on each upgrade you perform. This seems to be the preferred option for Blackboard V9.
  9. Extract the file spepfilter.tar.gz to your local working directory and copy the resulting jar files to $blackboard/webapps/login/WEB-INF/lib/ AND $blackboard/webapps/portal/WEB-INF/lib
  10. Extract the file spepinteg-blackboard.tar.gz to your local working directory and copy spepinteg-blackboard.jar:
    $blackboard/systemlib
  11. Navigate to the directory $blackboard/config/tomcat/classpath
  12. Create a file called 'spep-common.classpath.bb'
  13. Edit $blackboard/config/tomcat/conf/wrapper.conf.bb and add the line wrapper.java.additional.20=-Djava.endorsed.dirs=@bbconfig.basedir@/apps/tomcat/endorsed (make sure additional.20 isn't already taken otherwise increment the number).
  14. In this file add a single line of:
    $blackboard/systemlib/spepinteg-blackboard.jar
    YOU MUST MANUALLY EXTRACT $blackboard e.g.: /usr/local/blackboard/systemlib/spepinteg-blackboard.jar
  15. Open $blackboard/system/build/bin/launch-tool. sh | bat.
    Add the lines BB_CP=$BB_CP:spepinteg-blackboard.jar and BB_CP=$BB_CP:log4j.jar under other BB_CP lines.
  16. Add a reference to spepinteg-blackboard.jar in the PERL file that calls the Java email sending routine - more specific details to come shortly (sept 08). (resolves an email send issue)
  17. Check to ensure all instances of email.jar have a corresponding activation.jar in the same directory. (resolves an email send issue) - mail.jar added to /usr/local/blackboard/apps/tomcat/common/endorsed/
  18. (probably do NOT need these - possible xercesImpl.jar and xml-apis.jar needed in $blackboard/systemlib/)

SPEP Registration

Navigate to the "Register Service" page of the ESOE Manager.

Enter values for the following fields:

Field Description
Service name Human readable name for the service
Service URL Base URL or "home" of the service - the main entry point for a user agent e.g. https://blackboard.company.com
Service Identifier Identifier of the service must be a URI, generally this is the same as the value entered above
Service description A description of what the service does
Service Authz Failure A message to be displayed by the central authorization failure page when access to one of your resources has been denied. This may contain HTML markup.

Click Next.

Add Service Contacts

Select the contact type from the list, and enter the other details for the contact.
When this is filled in, click "Save contact".

You may edit and delete contacts after they have been saved. After you have finished entering contacts, click Next.

Add Service Nodes

The "SPEPNode URL" is used as the base URL for the SPEP endpoints. If your running blackboard on multiple nodes in a Layer 7 load balanced environment you will need to enter each of them here (you do not need a node for the service URL). The node domain names may be unrelated to the service domain if this is how your setup. e.g. https://blackboard.company.com as a service address may have node URL's of https://somenode.company.com and https://someothernode.company.com

The different service locations here are paths to the service endpoints, using the SPEPNode URL as a base.

Select the server technology you are using. The default values for the endpoint paths will work for a default SPEP deployment. For Blackboard you need Java.

Click Save Node. You may add more nodes and edit or delete nodes that have already been added.

After you have finished entering nodes, click Next.

Finalize registration process

From this page you may check the information you have entered, and also navigate back to previous pages to make any alterations by clicking the Previous button.

Once you are happy with the configuration, click Complete.

Service configuration

Navigate to your service in the ESOE Manager application. Click on the "get service configuration" link. In the service description, click on the "service node configuration" link.

This page shows you the configuration values that need to be set up in the spep.config file, which can be found at the location you've earlier configured for spep.data.

For each of the configuration options shown by the ESOE Manager service node configuration page, enter the corresponding value for the current node in its spep.config file.

It is very important that each node's configuration be correct. There may be some differences between them.

Add the following line to spep.config under the definitions for logoutClearCookie.1
logoutClearCookie.2=session_id

BELOW the line (in the part it says not to edit anything), check the following:

# Time that sessions which have yet to complete an authentication event are considered valid
sessionCacheTimeout=3600 (default value was 120, should be 3600)

Save the keystore file by clicking the "download keystore" link. The keystore will be the same for all nodes. Store the keystore as spep.data/config/spepKeystore.ks

Blackboard configuration

Integrate with the core Blackboard session handler

Edit the file $blackboard/config/authentication.properties

At the very top of this file add the following:
########################################################
##
##    ESOE SPEP Authentication Properties
##
########################################################

auth.type.esoe-spep.impl=com.qut.middleware.spep.integrators.blackboard.BlackboardIntegrator
auth.type.esoe-spep.userID=uid
auth.type.esoe-spep.fullName=name
auth.type.esoe-spep.mail=mail
auth.type.esoe-spep.roles=roles
auth.type.esoe-spep.logoutURL=https://esoe-tst.qut.edu.au/web/logout.htm

N.B: The values for userID, fullName, mail, roles and logoutURL are specific to each sites installation and attribute release policies. Query your ESOE system administrator for the values which should be placed here. Edit the file $blackboard/config/bb-config.properties
Change the value of bbconfig.auth.type to esoe-spep
bbconfig.auth.type=esoe-spep

Integrate with the Login Webapp

To integrate with the webapp you must edit BOTH web.xml.template and web.xml

Edit the file $blackboard/webapps/login/WEB-INF/web.xml.template and change it to read as follows:
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app 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 web-app_2_4.xsd" 
         version="2.4">

  <display-name>LoginBrokerServlet</display-name>

  <filter>
        <filter-name>spep-filter</filter-name>
        <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

        <init-param>
                <param-name>spep-context</param-name>
                <param-value>/spep</param-value>
        </init-param>
  </filter>

  <servlet>
        <servlet-name>LoginBrokerServlet</servlet-name>
        <servlet-class>blackboard.platform.security.authentication.servlet.LoginBrokerServlet</servlet-class>
  </servlet>

  <filter-mapping>
        <filter-name>spep-filter</filter-name>
        <url-pattern>/*</url-pattern>
  </filter-mapping>

  @web-jsp-declarations@

  <servlet-mapping>
        <servlet-name>LoginBrokerServlet</servlet-name>
        <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>
Likewise edit the $blackboard/webapps/login/WEB-INF/web.xml file and modify the header to read as follows (... indicates extra content already present in the file you MUST leave inline):
...
  <display-name>LoginBrokerServlet</display-name>

  <filter>
        <filter-name>spep-filter</filter-name>
        <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

        <init-param>
                <param-name>spep-context</param-name>
                <param-value>/spep</param-value>
        </init-param>
  </filter>

  <servlet>
        <servlet-name>LoginBrokerServlet</servlet-name>
        <servlet-class>blackboard.platform.security.authentication.servlet.LoginBrokerServlet</servlet-class>
  </servlet>

  <filter-mapping>
        <filter-name>spep-filter</filter-name>
        <url-pattern>/*</url-pattern>
  </filter-mapping>

<!--
Automatically created by Apache Jakarta Tomcat JspC.
Place this fragment in the web.xml before all icon, display-name,
description, distributable, and context-param elements.
-->
...

Integrate with the Portal Webapp

To integrate with the webapp you must edit BOTH web.xml.template and web.xml

Edit the file $blackboard/webapps/portal/WEB-INF/web.xml.template and change it to read as follows (... indicates extra content already present in the file you MUST leave inline):
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app 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 web-app_2_4.xsd" 
         version="2.4">

  <display-name>Portal</display-name>

        <filter>
                <filter-name>spep-filter</filter-name>
                <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

                <init-param>
                        <param-name>spep-context</param-name>
                        <param-value>/spep</param-value>
                </init-param>
         </filter>

        <servlet>
                <servlet-name>TabPortalServlet</servlet-name>
                <servlet-class>blackboard.portal.servlet.TabPortalServlet</servlet-class>
        </servlet>
....
   @web-jsp-declarations@

        <filter-mapping>
                <filter-name>spep-filter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

    <servlet-mapping>
                <servlet-name>TabPortalServlet</servlet-name>
                <url-pattern>/myinst/*</url-pattern>
        </servlet-mapping>
...

</web-app>

Likewise edit the $blackboard/webapps/portal/WEB-INF/web.xml file and modify the header to read as follows (... indicates extra content already present in the file you MUST leave inline):
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app 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 web-app_2_4.xsd" 
         version="2.4">

  <display-name>Portal</display-name>

         <filter>
                <filter-name>spep-filter</filter-name>
                <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

                <init-param>
                        <param-name>spep-context</param-name>
                        <param-value>/spep</param-value>
                </init-param>
         </filter>

        <servlet>
                <servlet-name>TabPortalServlet</servlet-name>
                <servlet-class>blackboard.portal.servlet.TabPortalServlet</servlet-class>
        </servlet>
...
        <filter-mapping>
                <filter-name>spep-filter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

    <servlet-mapping>
        <servlet-name>blackboard.web.caret_jsp</servlet-name>
        <url-pattern>/caret.jsp</url-pattern>
    </servlet-mapping>
...
</webapp>

Integrate with Blackboard Apache Instance

Edit the file $blackboard/apps/httpd/conf/httpd.conf.bb
Add the line:

JKMount       /spep/*                     @bbconfig.tomcat.main_worker@

after similar configuration lines in this file.

Integrate with the Blackboard Tomcat Instance

Edit the file $blackboard/config/tomcat/conf/server.xml.bb
Add the line:

<Context docBase="@@bbconfig.basedir@@/webapps/spep"       path="/spep"       crossContext="true"/>

after similar configuration lines in this file.

Integrate with Blackboard logging

Edit the file $blackboard/config/tomcat/common/classes/log4j.properties.bb to look like:
################################################################################
#
# Blackboard log4j logging options for Tomcat
#
# See http://logging.apache.org/log4j/docs/manual.html for more details.
#
################################################################################

log4j.rootLogger=INFO, R
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.DatePattern='.'yyyy-MM-dd'.txt'
log4j.appender.R.File=@@bbconfig.basedir@@/logs/tomcat/${bbconfig.appserver.cluster.id}${cluster.divider}catalina-log.txt

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

#
# Uncomment the following three log4j lines to use size-based logfile rotation
#
#log4j.appender.R=org.apache.log4j.RollingFileAppender
#log4j.appender.R.MaxFileSize=10MB
#log4j.appender.R.MaxBackupIndex=10

log4j.appender.spep=org.apache.log4j.DailyRollingFileAppender
log4j.appender.spep.DatePattern='.'yyyy-MM-dd'.txt'
log4j.appender.spep.File=/opt/spep/logging/spep.log
log4j.appender.spep.layout=org.apache.log4j.PatternLayout
log4j.appender.spep.layout.ConversionPattern=%p %t %c - %m%n

log4j.appender.spepauthn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.spepauthn.DatePattern='.'yyyy-MM-dd'.txt'
log4j.appender.spepauthn.File=/opt/spep/logging/spep-authn.log
log4j.appender.spepauthn.layout=org.apache.log4j.PatternLayout
log4j.appender.spepauthn.layout.ConversionPattern=%p %t %c - %m%n

log4j.appender.spepauthz=org.apache.log4j.DailyRollingFileAppender
log4j.appender.spepauthz.DatePattern='.'yyyy-MM-dd'.txt'
log4j.appender.spepauthz.File=/opt/spep/logging/spep-authz.log
log4j.appender.spepauthz.layout=org.apache.log4j.PatternLayout
log4j.appender.spepauthz.layout.ConversionPattern=%p %t %c - %m%n

#
# Use less verbose logging for the DWR package
#
log4j.category.uk.ltd.getahead.dwr.convert=WARN, R
log4j.category.uk.ltd.getahead.dwr.impl=WARN, R
log4j.category.uk.ltd.getahead.dwr.util=WARN, R

log4j.category.com.qut.middleware.spep=DEBUG, spep
log4j.category.spep.authn=DEBUG, spepauthn
log4j.category.spep.authz=DEBUG, spepauthz

NB: If your spep.data location isn't /opt/spep then you'll need to adjust this file accordingly

Deploy changes and restart Blackboard

The last step is simply to restart the Blackboard instance and push out our configuration changes by using the command PushConfigUpdate bin | sh. Don't forget to enable your service in ESOE Manager and ensure you have an authorization policy giving you access (everyone is denied access to new services by default).

Troubleshooting

If you encounter Server 500 errors, check that the JAVA_OPTS setting we added at step 8.1 has persisted after the PushConfigUpdate (in the file $blackboard/apps/tomcat/bin/blackboard-tomcat.sh.bb).

Also ensure if you are using a load balancer that you employ a suitable persistence method for the nodes in your pools. Do NOT use IP address as user traffic via HTTP proxies may come from a different IP address to their HTTPS traffic and break the session establishment. Cookie persistence (set by the load balancer, ie F5 BigIP) is known to work fine.

ALSO NOTE THAT A PUSHCONFIGUPDATE.SH POTENTIALLY messes with the $BLACKBOARD/apps/tomcat/conf/server.xml configuration. Check it esp if you have Server 500/javax.servlet.ServletException: Couldn't initialize SPEP/com.qut.middleware.spep.filter.exception.SPEPInitializationException: SPEP couldn't be initialized. No SPEP in this servlet context (yet?)type messages.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup Blackboard integration. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Integrating ESOE with Confluence

Authors
Bradley Beddoes

Applicable versions (ESOE)
Beta 2

Applicable versions (Confluence)
2.4+

Overview

Confluence is a wiki and content management solution in use at many large education institutions today. We have worked with the Confluence API to integrate ESOE to handle all user authentication and where desired add an extra layer of authorization control (which can be much deeper then the current limitations of Confluence).

Installation

Confluence installation builds from a standard Java SPEP install. You should first be familiar with the document Java SPEP Installation Guide and comfortable with a generic SPEP install. For Confluence locations and steps vary slightly from a standard install so we'll follow the guidelines below.

This document assumes that $confleunce is the home directory of your confluence web application (and that its an extracted WAR per Atlassian install documentation) and that $tomcat is the home directory of your tomcat installation. Installation with Generic war files is fine if you wish to take that path.

The procedure for installing binaries is as follows (ensure permissions are set correctly for your tomcat and confluence users):

  1. Backup jar files in $tomcat/common/endorsed
  2. Extract spep-endorsed.tar.gz to $tomcat/common/endorsed
  3. Extract spep.tar.gz to a local working directory
  4. Create a directory called spep in your local working directory and extract the spep.war file inside this directory (this will look like the spep directory for a normal tomcat webapps deployment of spep.war)
  5. Copy the spep directory to the same parent directory that houses $confluence
  6. Create a core directory to store spep artifacts, a sub directory called config to store configuration and a sub directory called logging for log files. This must be readable by the user tomcat runs as. e.g /opt/spep/config and /opt/spep/logging
  7. Copy the spep.config file to the configuration directory e.g /opt/spep/config/spep.config
  8. At this point you have a choice in how to advise the SPEP install of your configuration location
    1. Java Property (RECOMMENDED). Export a java property called spep.data to your Java environment when tomcat starts. This should be set to the top level artifacts directory. e.g -Dspep.data=/opt/spep
    2. Create a Java properties file called spepvars.config and place it in $tomcat/webapps/spep/WEB-INF/ this is a standard java properties file format, set the variable spep.data to the same value you would above. We don't recommend this method though it may be useful in a multi spep environment, be sure to save your spepvars.config file safely, it will need to be copied back to the web application on each upgrade you perform.
  9. Edit the confluence.xml file in $tomcat/conf/Catalina/localhost adding crossContext="true" to the Context element for your Confluence installation.
  10. Create a file called spep.xml in $tomcat/conf/Catalina/localhost and enter the data:
    <Context path="/spep" docBase="<webappbasedir>/spep" debug="0" reloadable="true" crossContext="true">

    NB: The previous two steps can be implemented a number of ways depending on your deployment methods, the Context elements above may be solely listed in $tomcat/conf/server.xml or in the META-INF/context.xml files of each web application your deploying if your deploying WAR files.
  11. Extract the file spepfilter.tar.gz to your local working directory and copy the contained jar files to $confluence/WEB-INF/lib/
  12. Extract the file spepinteg-confluencejira.tar.gz to your local working directory and copy spepinteg-confluencejira.jar to $confluence/WEB-INF/lib
  13. Make the directory structure $confluence/WEB-INF/classes/com/qut/middleware/spep/integrators/atlassian/
  14. Copy the file integrator.properties to this location

SPEP Registration

Navigate to the "Register Service" page of the ESOE Manager.

Enter values for the following fields:

Field Description
Service name Human readable name for the service
Service URL Base URL or "home" of the service - the main entry point for a user agent e.g. https://confluence.company.com
Service Identifier Identifier of the service must be a URI, generally this is the same as the value entered above
Service description A description of what the service does
Service Authz Failure A message to be displayed by the central authorization failure page when access to one of your resources has been denied. This may contain HTML markup.

Click Next.

Add Service Contacts

Select the contact type from the list, and enter the other details for the contact.
When this is filled in, click "Save contact".

You may edit and delete contacts after they have been saved. After you have finished entering contacts, click Next.

Add Service Nodes

The "SPEPNode URL" is used as the base URL for the SPEP endpoints. If your running confluence on multiple nodes in a Layer 7 load balanced environment you will need to enter each of them here (you do not need a node for the service URL). The node domain names may be unrelated to the service domain if this is how your setup. e.g. https://confluence.company.com as a service address may have node URL's of https://somenode.company.com and https://someothernode.company.com

The different service locations here are paths to the service endpoints, using the SPEPNode URL as a base.

Select the server technology you are using. The default values for the endpoint paths will work for a default SPEP deployment. For confluence you need Java.

Click Save Node. You may add more nodes and edit or delete nodes that have already been added.

After you have finished entering nodes, click Next.

Finalize registration process

From this page you may check the information you have entered, and also navigate back to previous pages to make any alterations by clicking the Previous button.

Once you are happy with the configuration, click Complete.

Service configuration

Navigate to your service in the ESOE Manager application. Click on the "get service configuration" link. In the service description, click on the "service node configuration" link.

This page shows you the configuration values that need to be set up in the spep.config file, which can be found at the location you've earlier configured for spep.data.

For each of the configuration options shown by the ESOE Manager service node configuration page, enter the corresponding value for the current node in its spep.config file.

It is very important that each node's configuration be correct. There may be some differences between them.

Save the keystore file by clicking the "download keystore" link. The keystore will be the same for all nodes. Store the keystore as spep.data/config/spepKeystore.ks

Confluence configuration

Integrate with the core Confluence session handler

  1. Take a backup copy of $confluence/WEB-INF/classes/seraph-config.xml
  2. Edit the file $confluence/WEB-INF/classes/seraph-config.xml
  3. Replace the init-param entries at the top of the file with:
        <parameters>
            <init-param>
                <param-name>login.url</param-name>
                <param-value>/login?os_redirect=${originalurl}</param-value>
            </init-param>
            <init-param>
                <param-name>link.login.url</param-name>
                <param-value>/login?os_redirect=/dashboard.action</param-value>
            </init-param>
            <init-param>
                <param-name>cookie.encoding</param-name>
                <param-value>cNf</param-value>
            </init-param>
            <init-param>
                <param-name>login.cookie.key</param-name>
                <param-value>seraph.confluence</param-value>
            </init-param>
    
            <!--only basic authentication available-->
            <init-param>
                <param-name>authentication.type</param-name>
                <param-value>os_authType</param-value>
            </init-param>
        </parameters>
    
  4. Find the <authenticator> element and replace the class value with "com.qut.middleware.spep.integrators.atlassian.ConfluenceJiraIntegrator"
  5. Take a backup copy of $confluence/WEB-INF/web.xml
  6. Edit the file $confluence/WEB-INF/web.xml
  7. Add the following filters above the filter of 'johnson':
        <filter>
            <filter-name>spep-filter</filter-name>
            <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>
    
            <init-param>
                    <param-name>spep-context</param-name>
                    <param-value>/spep</param-value>
            </init-param>
       </filter>
    
       <filter>
            <filter-name>spep-redirect</filter-name>
            <filter-class>com.qut.middleware.spep.integrators.atlassian.LoginRedirectFilter</filter-class>
       </filter>
    
  8. Add the following filter mappings above the filter mapping for 'login'
        <filter-mapping>
            <filter-name>spep-filter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <filter-mapping>
            <filter-name>spep-redirect</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
  9. Edit the file $confluence/WEB-INF/classes/com/qut/middleware/spep/integrators/atlassian/integrator.properties and set values for each field, the defaults may suffice but speack to your ESOE system administrator to ensure they match your sites attribute release policy.

Logging configuration

We recommend (but it is not essential) you configure a log4j.xml file at $tomcat/shared/classes as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
        <logger name="com.qut.middleware.spep">
                <level value="DEBUG" />
                <appender-ref ref="spep-logger" />
        </logger>

        <logger name="spep.authn">
                <level value="DEBUG" />
                <appender-ref ref="spep-authn-logger" />
        </logger>

        <logger name="spep.authz">
                <level value="DEBUG" />
                <appender-ref ref="spep-authz-logger" />
        </logger>

        <appender name="spep-logger" class="org.apache.log4j.FileAppender">
                <param name="Append" value="false" />
                <param name="File" value="$spep.data/logging/spep.log" />
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="ConversionPattern" value="%d %-5p %c - %m%n" />
                </layout>
        </appender>

        <appender name="spep-authn-logger" class="org.apache.log4j.FileAppender">
                <param name="Append" value="false" />
                <param name="File" value="$spep.data/logging/spep-authn.log" />
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="ConversionPattern" value="%d %-5p %c - %m%n" />
                </layout>
        </appender>

        <appender name="spep-authz-logger" class="org.apache.log4j.FileAppender">
                <param name="Append" value="false" />
                <param name="File" value="$spep.data/logging/spep-authz.log" />
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="ConversionPattern" value="%d %-5p %c - %m%n" />
                </layout>
        </appender>

</log4j:configuration>

NB: You should replace $spep.data with the directory your storing spep artifacts in.

Deploy changes and restart Confluence

The last step is simply to restart the Confluence tomcat instance. You should watch the log files configured above for any problems on startup then access your confluence repository. Don't forget to enable your service in ESOE Manager and ensure you have an authorization policy giving you access (everyone is denied access to new services by default).

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup Confluence integration. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Integrating ESOE with Google Apps for your domain

Authors
Bradley Beddoes

Applicable versions
Beta 2

Overview

Google offers a service called "Google Apps for your domain" which exposes various functionality to your users such as GMail, Google Calendar, Google documents and other services. Through our work with Google engineering ESOE is able to assist in this process by acting as an identity broker between Google and your enterprise allowing true single sign on to these applications.

To enable this functionality you will require an educational or premium Google service.

Required attributes

It is a requirement of using the Google service that you expose the email addresses of your users to the ESOE locally. By default this will be resolved from an attribute called 'mail', ensure using ESOE Manager that your attribute resolution is setup correctly.

Provisioning Accounts

ESOE does not yet automatically provision accounts to Google on your behalf, you will need to do this in advance either manually or using the Google provisioning API.

Exporting crypto

To communicate with Google you need to have available the ESOE public key in der format.

To retrieve navigate to the directory esoe.data/config and perform the following actions:

  1. Read the esoe.config file and make note of the values for keyAlias-1 and keystorePassword-1 this will be randomly assigned data that won't mean much to you.
  2. execute the following command "keytool -export -keystore ./esoeKeystore.ks -alias <keyAlias-1> -file google.crt" (ensure you replace keyAlias-1 with its value above)
  3. You will be prompted for the password, enter the value of keystorePassword-1

Configuring Google Apps

As an administrator in the Google apps domain you will have an option called 'Advanced Tools' within this you should see an option for 'Set up single sign-on (SSO)'

  1. Tick the Enable Single Sign On box
  2. Set Sign-in page URL to https://<host>/sso e.g https://esoe.intient.com/sso
  3. Set Sign-out page URL to https://<host>/logout e.g https://esoe.intient.com/logout
  4. Set Change password URL to the URL users use to manage their identity at your enterprise.
  5. Set Network masks to 0-255.0.0.0/1
  6. Click save
  7. For Verification certificate click browse and locate your google.crt file (you may need to copy this from the ESOE to your local machine), then click upload

Google is now configured, you can logout of the administrator account.

Testing

To test the account simply navigate to http://partnerpage.google.com/<yourdomain>, you should be redirected to the ESOE login service then back to Google successfully.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup Google integration. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Integrating ESOE with Oracle Single Sign-On

Please note: This documentation is written for integrating the Oracle SSO product, not ordinary applications running under OC4J.

IMPORTANT This document refers to an old version of the SPEP libraries, as the newer build has not been successfully tested with Oracle SSO.
The distribution files related to this document can be found at http://esoeproject.org/releases/0.4/java4/

Note: It is important that the SPEP war be deployed in the same container as Oracle SSO, as the SPEP filter relies on cross context communication to operate.

SPEP Setup

Download the SPEP archive

Download the spep.tar.gz and spepfilter.tar.gz files for your version of Java from the [Downloads] page, and extract to a temporary folder. This will create the files spep.config spep-endorsed.tar.gz spep-shared.tar.gz spep.war and the SPEP filter jar file for use during installation.

Preparing SPEP data directory

Make the following directories under $ORACLE_HOME
spep spep/lib spep/config spep/logging

Installing shared libraries

Extract the spep-shared.tar.gz archive from the distribution into $ORACLE_HOME/spep/lib

Installing endorsed libraries

Under $ORACLE_HOME/jdk/jre/lib ensure that a directory called endorsed exists. If not, create it. Then extract the spep-endorsed.tar.gz archive from the distribution into $ORACLE_HOME/jdk/jre/lib/endorsed

Performing SPEP configuration

Set up the SPEP according to the SPEP Registration section of Java SPEP Installation Guide. Copy your spep.config file to $ORACLE_HOME/spep/config/

Configuring OC4J

Adding the shared library directory

In the Oracle Enterprise Manager admin control webpage, select the container for 'Oracle SSO (OC4J_SECURITY)' and navigate to the Applications page.

Follow the link to the default application. Usually this is called "default". Down the bottom under Administration click the General link under the Properties header.

Add a new library path and point this at the SPEP library directory created in step 1. In a default installation this can be "../../../spep/lib"

Configuring Java VM arguments

Navigate to the Administration page for the OC4J_SECURITY container. Scroll down to the section labelled "Command Line Options" and add the following options (on the same line, seperated by spaces):

-Dspep.data=$ORACLE_HOME/spep
-Djavax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema=org.apache.xerces.jaxp.validation.XMLSchemaFactory
-Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl

Note that you will need the absolute path to $ORACLE_HOME for the spep.data property, not the shell variable.

Deploying the SPEP webapp

Navigate back to the Applications page for the OC4J_SECURITY container. Click the "Deploy WAR file" link and proceed to deploy the spep.war file from the distribution.

Filtering the Oracle SSO URL

[oraas@oraashost ~]$ cd $ORACLE_HOME/j2ee/OC4J_SECURITY/applications/sso/web/WEB-INF
[oraas@oraashost WEB-INF]$ cp /path/to/spepfilter.jar ./lib/
Edit web.xml in this directory and add the following:
<filter>
        <filter-name>spep-filter</filter-name>
        <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

        <init-param>
                <param-name>spep-context</param-name>
                <param-value>/spep</param-value>
        </init-param>
</filter>
<filter-mapping>
        <filter-name>spep-filter</filter-name>
        <url-pattern>/auth</url-pattern>
</filter-mapping>

Change to the directory $ORACLE_HOME/j2ee/OC4J_SECURITY/applications/sso/web/META-INF

Edit context.xml there to add the attribute crossContext="true" to the Context element. If the META-INF directory or the context.xml file do not exist, create them, and give the context.xml file the following content:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/sso" crossContext="true">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>META-INF/context.xml</WatchedResource>
</Context>

Installing the Oracle SSO plugin

Download the Oracle SSO Integrator tarball and extract it into $ORACLE_HOME/sso/plugin/

Edit the file $ORACLE_HOME/sso/plugin/com/qut/middleware/spep/integrators/oracle/spep.oraclesso.properties and ensure that the SPEP attributes name is set to the name that the SPEP filter gives to the attribute map in a session (by default this is "attributes"). Also, set the user identifier attribute value to the name of the attribute that you want to be passed to Oracle SSO.


Java SPEP Installation Guide

Authors
Bradley Beddoes

Applicable versions
0.9+

We no longer support JVM 1.4 releases.

For OC4J installations, please also refer to the OC4J SPEP Installation Guide

Preparing your server

To successfully operate the Java SPEP your server must be accessible on port 443 from the ESOE system. You can ask your ESOE system administrator for the IP addresses ESOE will connect from if your running a restrictive firewall policy and update it appropriately. In some circumstances your administrator may allow you to configure port 80 unsecured SPEP instances. This is a per installation decision which your ESOE system administrator can advise you of.

The distribution of SPEP comes with 3 gziped tared files:

  1. Extract spep-endorsed.tar.gz to your $TOMCAT/common/endorsed directory
  2. Extract spep.tar.gz and copy the spep.war file to $TOMCAT/webapps
  3. Create a core directory to store spep artifacts, a sub directory called config to store configuration and a sub directory called logging for log files. This must be readable by the user tomcat runs as. e.g /opt/spep/config and /opt/spep/logging
  4. Copy the spep.config file to the configuration directory e.g /opt/spep/config/spep.config
  5. At this point you have a choice in how to advise the SPEP install of your configuration location
    1. Java Property (RECOMMENDED). Export a java property called spep.data to your Java environment when tomcat starts. This should be set to the top level artifacts directory. e.g -Dspep.data=/opt/spep
    2. Create a Java properties file called spepvars.config and place it in $tomcat/webapps/spep/WEB-INF/ this is a standard java properties file format, set the variable spep.data to the same value you would above. We don't recommend this method though it may be useful in a multi spep environment, be sure to save your spepvars.config file safely, it will need to be copied back to the web application on each upgrade you perform, it may also be wise to recreate the shipped spep.war file with this file stored inside before starting tomcat.

The distribution of SPEP also comes with another gziped tared file called spepfilter.tar.gz this contains several jar files which you must locate in each web applications WEB-INF/lib directory that your deploying.

Registering the SPEP with ESOE Manager

Ask your ESOE administrator, or see this page for information if you manage your ESOE instance.

Service configuration

Retrieve your service configuration and keystore from ESOE Manager, or from your ESOE administrator.

This page shows you the configuration values that need to be set up in the spep.config file, which can be found at the location you've earlier configured for spep.data.

For each of the configuration options shown by the ESOE Manager service node configuration page, enter the corresponding value for the current node in its spep.config file.

It is very important that each node's configuration be correct. There may be some differences between them.

The keystore will be the same for all nodes. Store the keystore as spep.data/config/spepKeystore.ks

Protecting your webapp

There are 2 steps to configuring a web application to be protected by the SPEP:

  1. Edit the tomcat/webapps/_yourapp_/WEB-INF/web.xml file so that it uses the filter.
  2. Configure your webapp for cross context access.

The following should be placed in the web.xml file for your webapp to protect it with the filter:

<filter>
    <filter-name>spep-filter</filter-name>
    <filter-class>com.qut.middleware.spep.filter.SPEPFilter</filter-class>

    <init-param>
        <param-name>spep-context</param-name>
        <param-value>/spep</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>spep-filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

The param-value for the spep-context parameter should be changed to the location of the SPEP webapp in your Tomcat instance. By default this is /spep. The url-pattern in the filter-mapping section describes which part of the webapp to protect. By matching /* we protect the entire webapp.

Important note about cross context access
The SPEP webapp by default operates in the /spep context, or in whichever context it is placed. In order to have different paths such as /secure which are protected by an SPEP filter, cross context access needs to be enabled. This is enabled by default, by the context.xml file in the META-INF/context.xml.

Your application MUST also be enabled for cross context. To enable cross context access, the following should be placed in tomcat/webapps/_yourapp_/META-INF/context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/secure" crossContext="true">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>META-INF/context.xml</WatchedResource>
</Context>

Logging

SPEP ships with support for Log4j logging. Each spep.war ships with a log4j configuration pointing at spep.data/logging for file output and by default logs at the INFO level. You may choose to modify this to suit your own needs but for general production usage INFO is considered sufficient.

Run the environment

Your environment is now able to be started, we reccomend you watch logging closely for the first little while to make sure all configuration is in order at which time you can lower the output of SPEP logging from DEBUG to INFO. To invoke spep simply point your browser at http://<<server [:port]>/__your__app/

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup an SPEP. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


Migration from Confluence

The content previous on the Confluence wiki has been migrated, and is no longer available at the original location. Please update any links to point at the correct location.

Sections

ESOE Users
ESOE Developers


OC4J SPEP Installation Guide

This document outlines the deviations from standard installation which are required for running an SPEP on OC4J.

Shared libraries

OC4J ships with the Oracle JAXP implementation, which is incompatible with the standard. To work around this, we create a shared library configuration for the Apache implementation.

In the OC4J administration page, under Shared Libraries, click Create. Enter the following details:

Add the JAR files from the SPEP endorsed distribution.

Ensure no other shared libraries are imported, and click Finish.

Deploying spep.war

Repackage the spep.war with the following changes:

Proceed as normal for WAR deployment, but in the final stage of Deployment Settings, click the link to Configure Class Loading.

Click OK and complete the deployment.

Deploying your protected web application

Ensure that the oracle.xml shared library is not imported when your application is deployed.

Proceed as normal for a standard Java SPEP installation.

High availability deployment

One possible high availability deployment scenario is:

(Load balancer) - (Oracle HTTPD) - (OC4J)

In these situations, both the Load balancer and Oracle HTTPD (i.e. Apache) will need to persist connections to the same backend OC4J instance. When deployed with the Oracle HTTPD load balancer, this option is referred to as "local affinity". For more information, consult your Application Server administrator or Oracle documentation.


OSX Apache SPEP

Authors
Bradley Beddoes
Shaun Mangelsdorf

Applicable versions
Beta 2 (0.5, 0.5.2)

OSX Requirements for Apache SPEP

The following instructions were developed on an OSX 10.5 Intel platform, they should work on alternate OSX platforms as well. If you locate any discrepancies please let our users email list know so we can revise accordingly.

Macports

To make installation as easy as possible we have worked with packages from the macports project ( http://www.macports.org/ ), please follow this document for configuring your system before continuing. Additionally the macports guide is a useful resource to refer to when performing installs and updates documented below.

Once Macports is configured please install the following:

Note: For Intel Mac, there is a bug in Xerces 2.8.0. To correct this, edit the Portfile before installing. By default this file is at /opt/local/var/macports/sources/rsync.macports.org/release/ports/textproc/xercesc/Portfile

Add the following section:
pre-build {
        if {${os.endian} == {little}} {
                reinplace {s|ENDIANMODE_BIG|ENDIANMODE_LITTLE|} ${worksrcpath}/src/xercesc/util/Platforms/MacOS/MacOSDefs.hpp
        }
}

After that, install as usual.

Choosing an Apache instance

You have two choices here, either the Apache instance that is supplied by Macports or the apache instance supplied by Apple. We recommend using the version supplied by Macports if you have a choice.

Using Macports Apache

For this we need to install the port apache2 2.2.8, this requires a correction to the port to alleviate a problem with Apache and OpenSSL on OSX. Please follow the below instructions which were taken from the bug report at ( http://trac.macports.org/ticket/13182 )

 
(1) If installed the apache2 port should first be uninstalled
(2) Extract the apache2 source:# port extract apache2
--->  Fetching apache2
--->  Verifying checksum(s) for apache2
--->  Extracting apache2
(3) Search (recursive grep) where in the source the option "-export-symbols-regex" is defined to confirm the problem that this ticket on Leopard exists:bash-3.2# grep -r "-export-symbols-regex" /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_apache2/
[SNIP]
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_apache2/work/httpd-2.2.6/configure:    test "x$silent" != "xyes" && echo "  setting MOD_SSL_LDADD to \"-export-symbols-regex ssl_module\"" 
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_apache2/work/httpd-2.2.6/configure:    MOD_SSL_LDADD="-export-symbols-regex ssl_module" 
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_www_apache2/work/httpd-2.2.6/configure:    apr_addto_bugger="-export-symbols-regex ssl_module" 
[SNIP]
(4) Manually patch the apache2 Portfile (/opt/local/var/macports/sources/rsync.macports.org/release/ports/www/apache2/Portfile) with regard to the configure script in the section specific to Leopard (Darwin 9) by changing:platform darwin 9 {
        depends_build-append port:gawk
}
to:platform darwin 9 {
        depends_build-append port:gawk
        post-extract {
                reinplace "s|-export-symbols-regex ssl_module||g" ${worksrcpath}/configure
        }
}
(5) Clean the apache2 port:# port clean apache2
(6) Build and *install* the apache2 port:$ sudo port -v install apache2
Tail of the expected output looks like this --->--->  Archive apache2-2.2.6_0.powerpc.tgz packaged
--->  Archive for apache2 2.2.6_0 packaged
--->  Installing apache2 2.2.6_0
--->  Activating apache2 2.2.6_0
--->  Cleaning apache2
--->  Removing workpath for apache2
(7) Read object information from mod_ssl with the otool tool, confirming that mod_ssl was built against the MacPort installation of OpneSSL (such as OpenSSL version 0.9.8g):$ cd /opt/local/apache2/modules
$ otool -L mod_ssl.so
Expect output quite similar to if not the same as --->mod_ssl.so:
    /opt/local/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /opt/local/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
(8) Run apache2 and expect the once mod_ssl.so error regarding symbols to *vanish*:$ /opt/local/apache2/bin/apachectl start

Using Apple Apache

If your choosing to use the httpd binaries shipped by Apple then we require the removal of the universal binary components. This is due to a dependency we rely on (Xerces 2.x) not being compatible with Universal binaries. The next release (Xerces 3.x) will be compatible with Universal binary formats and we will revist this section then.

To make httpd compatible undertake the following: * use lipo to strip the httpd binary down to an i386-only binary (as root):
lipo /usr/sbin/httpd -thin i386 -output /usr/sbin/httpd.i386

Manual Dependencies

Unfortunately Macports does not contain support for two of our dependencies. This will need to be installed manually as follows.

Manual Downloads:

XSD 3.0 - www.codesynthesis.com

Download the 3.0 release tar from codesynthesis, untar and simply execute - sudo cp -r libxsd/xsd /opt/local/include

Apache XML Security C

Download an Apache XML security for C 1.4.x release from http://xml.apache.org/security/dist/c-library/ and undertake the following:
- Extract the tar file
- ./configure --prefix=/opt/local --with-xerces=/opt/local --with-openssl=/opt/local
- make
- sudo make install

Setting up the SPEP environment

Firstly ensure you have downloaded source tars for the current SPEP release, you can find details about the current release and links to files at [Downloads] under the heading Apache SPEP.
To create all the required binaries for OSX undertake the following (this section assumes you have a previous knowledge of the standard configure, make type tools, if not many excellent references exist online to assist here).

Before continuing be sure to export the following environment variable
export CPPFLAGS=-I/opt/local/include/apr-1

SAML2CPP

untar saml2-x.y.tar.gz; then:

# ./configure --prefix=/opt/local --with-xmlsec=/opt/local --with-openssl=/opt/local --with-boost=/opt/local --with-xsd=/opt/local
# make
# sudo make install

SPEPCPP

untar spep-x.y.tar.gz; then

# ./configure --prefix=/opt/local --with-xmlsec=/opt/local --with-openssl=/opt/local --with-boost=/opt/local --with-xsd=/opt/local --with-saml2cpp=/opt/local
# make
# sudo make install

SPEPCPPDAEMON

untar spepd-x.y.tar.gz; then

# ./configure --prefix=/opt/local --with-xmlsec=/opt/local --with-openssl=/opt/local --with-boost=/opt/local --with-xsd=/opt/local --with-saml2cpp=/opt/local --with-spepcpp=/opt/local --with-boost-suffix=-mt
# make
# sudo make install

MODSPEP

untar modspep-x.y.tar.gz; then:

* If you're using the Apple supplied httpd instance use the following configure command
# ./configure --prefix=/opt/local --with-xmlsec=/opt/local --with-openssl=/opt/local --with-boost=/opt/local --with-xsd=/opt/local --with-saml2cpp=/opt/local --with-spepcpp=/opt/local --with-boost-suffix=-mt --with-apache2=/usr --with-apreq=/opt/local --with-curl=/opt/local -with-icu=/opt/local CPPFLAGS="-I/usr/include/apr-1 -I/usr/include/apache2" 
* If you're using the Macports http instance use the following configure command
# ./configure --prefix=/opt/local --with-xmlsec=/opt/local --with-openssl=/opt/local --with-boost=/opt/local --with-xsd=/opt/local --with-saml2cpp=/opt/local --with-spepcpp=/opt/local --with-boost-suffix=-mt --with-apache2=/opt/local/apache2 --with-apreq=/opt/local --with-curl=/opt/local --with-icu=/opt/local 
# make
# sudo make install

Once completed those using Macports httpd should create a symlink as follows:

# cd /opt/local/apache2/modules
# ln -s /opt/local/lib/modspep.so .

Final tasks

The custom requirements for OSX are now completed. You can continue with the document Apache SPEP Installation Guide from the heading SPEP Registration as per normal SPEP deployment.

A final note for those wishing to deploy webobjects behind the Maports version of Apache httpd you can also now configure the WebObjects connector in the same way you would for the standard OS X httpd, please see the WebObjects connector documentation for more details.


Policy Templates

Authors
Bradley Beddoes
Andre Zitelli
Shaun Mangelsdorf

Applicable Versions
Beta 2

Overview

This page lists simple templates for Rules which may be included in policies.

Templates

Allow access for all authenticated users

<Rule Effect="Permit" RuleId="spep-rule-0">
  <Description>
  This rule causes all resources to be permitted by default for all users, internal and external that are matched by the policy.
  </Description>
</Rule>

Deny access for all users who are considered to be external

<Rule Effect="Deny" RuleId="spep-rule-0">
    <Description>This rule causes all users who authenticated via an external protocol (shibboleth or openID) to be denied access to content</Description>
    <Condition>
    <Apply FunctionId="string-equal">
            <SubjectAttributeDesignator AttributeId="esoe-externalised-identity" />
        <AttributeValue>true</AttributeValue>
    </Apply>
    </Condition>
  </Rule>

Submissions

We welcome your rule submissions for inclusion on this page.


Registering an SPEP with ESOE Manager

Navigate to the "Register Service" page of the ESOE Manager.

Enter values for the following fields:

Field Description
Service name Human readable name for the service
Service URL Base URL or "home" of the service - the main entry point for a user agent
Service Identifier Identifier of the service must be a URI, generally this is the same as the value entered above
Service description A description of what the service does
Service Authz Failure A message to be displayed by the central authorization failure page when access to one of your resources has been denied. This may contain HTML markup.

Click Next.

Add Service Contacts

Select the contact type from the list, and enter the other details for the contact.
When this is filled in, click "Save contact".

You may edit and delete contacts after they have been saved. After you have finished entering contacts, click Next.

Add Service Nodes

The "SPEPNode URL" is used as the base URL for the SPEP endpoints. The different service locations here are paths to the service endpoints, using the SPEPNode URL as a base.

Select the server technology you are using. The default values for the endpoint paths will work for a default SPEP deployment.

Click Save Node. You may add more nodes and edit or delete nodes that have already been added.

After you have finished entering nodes, click Next.

Finalize registration process

From this page you may check the information you have entered, and also navigate back to previous pages to make any alterations by clicking the Previous button.

Once you are happy with the configuration, click Complete.


Securing ESOE in Unix Environments

Authors
Paul Stepowski

Applicable versions
Beta 1

Configure Your System

Taking a backup

If you're using versions of software that already exist on the system, particularly the tomcat instance we can't stress enough the need to MAKE A BACKUP before continuing. The best of us make mistakes, a backup makes them small mistakes, not backing up can make them a nightmare.

System accounts

To configure ESOE you need root access to the system. It's generally bad practice to use full root access, so the first thing you should do is create yourself a local account and provision that account with root access via sudo.

* Create yourself a local account and set your password. E.g.
# useradd bloggsj
# passwd bloggsj

NOTE: The password should be at least eight characters in length and use a mix of letters (upper and lower case), numbers and punctuation characters. * Provision root access to your local account via sudo. E.g.
# visudo
* Add your local account to the sudo configuration. E.g.
bloggsj ALL = (ALL) ALL
* Save your changes. This will allow your user to run any command as any user via sudo.

Configure Firewall Rules

NOTE: You can skip this step if the system you are installing ESOE on does not have a firewall.  We strongly recommend that you use a firewall.

ESOE requires the following firewall rules: You may need additional firewall rules if your database and/or LDAP servers are not on the local machine. E.g. Here's a sample iptables configuration file.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:Firewall-1-INPUT - [0:0]
:Firewall-1-OUTPUT - [0:0]
-A INPUT -j Firewall-1-INPUT
-A FORWARD -j Firewall-1-INPUT
-A OUTPUT -j Firewall-1-OUTPUT
-A Firewall-1-INPUT -i lo -j ACCEPT
-A Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A Firewall-1-INPUT -p tcp --dport 22 -j ACCEPT
-A Firewall-1-INPUT -p tcp --dport 80 -j ACCEPT
-A Firewall-1-INPUT -p tcp --dport 443 -j ACCEPT
-A Firewall-1-INPUT -p tcp --dport 8080 -j ACCEPT
-A Firewall-1-INPUT -p tcp --dport 8443 -j ACCEPT
-A Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A Firewall-1-INPUT -j LOG --log-level debug
-A Firewall-1-INPUT -j DROP
-A Firewall-1-OUTPUT -i lo -j ACCEPT
-A Firewall-1-OUTPUT -p icmp --icmp-type any -j ACCEPT
-A Firewall-1-OUTPUT -p tcp --dport 53 -j ACCEPT
-A Firewall-1-OUTPUT -p udp --dport 53 -j ACCEPT
-A Firewall-1-OUTPUT -p tcp --dport 80 -j ACCEPT
-A Firewall-1-OUTPUT -p tcp --dport 443 -j ACCEPT
-A Firewall-1-OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A Firewall-1-OUTPUT -j LOG --log-level debug
-A Firewall-1-OUTPUT -j DROP
COMMIT

You should use ACLs to further restrict which IP address(es) may connect to these ports where necessary. Also, this example sends firewall logs to syslog using the "kernel" facility and priority "debug". It's a good idea to send these logs to a separate log file. To do this, add the following to /etc/syslog.conf and then restart syslogd.

# iptables logging
kern.=debug /var/log/iptables
Make sure that only root can read and write the iptables log. E.g.
$ sudo chown root.root /var/log/iptables
$ sudo chmod 600 /var/log/iptables

Configure Java

You need to know which directory Java is installed in. It's usually something like /usr/local/jdk1.6.0_01. From now on, this document will refer to your Java directory as $JAVA_HOME. You should export this as an environment variable when starting or stopping tomcat. One method of doing this is by adding the export to the startup.sh and shutdown.sh files.

ESOE requires more memory then the defaults. You should set JAVA_OPTS to have memory sizes simillar to the following -Xms128m -Xmx512m, this will work for most testing environments.

Configure Tomcat

Tomcat runs as root by default. This is generally bad practice because if tomcat's security is compromised, an attacker will get root access to your system. It is best to run tomcat as a non root user. That way, even if tomcat is compromised, the attacker still must defeat additional layers of security to get root access.

In addition to this, tomcat's configuration files should be owned by a separate user again. This way even if an attacker compromises tomcat, they cannot change the configuration of web server. This really restricts what an attacker can do.

Create two users as follows:

E.g.

$ sudo useradd tcadmin
$ sudo passwd tcadmin
$ sudo groupadd -r tomcat
$ sudo useradd -r -g tomcat -s /sbin/nologin tomcat

The "tcadmin" user needs to own and have write access to most of the files under the tomcat directory. If you are installing tomcat from source, here's how you could set permissions.

$ sudo -u tcadmin tar xzf apache-tomcat-5.5.23.tar.gz
$ sudo mv apache-tomcat-5.5.23 /usr/local/
$ cd /usr/local/
$ sudo ln -s apache-tomcat-5.5.23 tomcat
Tomcat needs to know where you installed Java. You can tell tomcat the directory Java is installed in using the $JAVA_HOME environment variable. E.g.
$ sudo -u tcadmin vi $TOMCAT_HOME/bin/startup.sh
At the top of the script add:
export JAVA_HOME=/usr/local/jdk

NOTE: $TOMCAT_HOME refers to wherever you installed tomcat. E.g. /usr/local/tomcat.

Now you need to adjust the permissions so the "tomcat" user can write to certain files like log files and files under the work directory. E.g.

$ sudo chgrp -R tomcat $TOMCAT_HOME/conf/*
$ sudo chmod 640 $TOMCAT_HOME/conf/*
$ sudo chown tomcat.tomcat $TOMCAT_HOME/conf/Catalina
$ sudo chmod 755 $TOMCAT_HOME/conf/Catalina
$ sudo chown tomcat.tomcat $TOMCAT_HOME/conf/Catalina/localhost
$ sudo chmod 755 $TOMCAT_HOME/conf/Catalina/localhost
$ sudo chown tomcat.tomcat $TOMCAT_HOME/conf/Catalina/localhost/*
$ sudo chown tomcat.tomcat $TOMCAT_HOME/logs
$ sudo chmod 700 $TOMCAT_HOME/logs
$ sudo chown tomcat.tomcat $TOMCAT_HOME/webapps
$ sudo chown -R tomcat.tomcat $TOMCAT_HOME/work
$ sudo mkdir $TOMCAT_HOME/conf/users
$ sudo chmod 700 $TOMCAT_HOME/conf/users
$ sudo chown tomcat.tomcat $TOMCAT_HOME/conf/users
$ sudo mv $TOMCAT_HOME/conf/tomcat-users.xml $TOMCAT_HOME/conf/users
$ sudo chown tomcat $TOMCAT_HOME/conf/users/tomcat-users.xml
$ sudo chmod 644 $TOMCAT_HOME/conf/users/tomcat-users.xml
Finally, you need to change tomcat's configuration to refer to the new location of tomcat-users.xml, which we moved using the above commands. E.g.
$ sudo -u tcadmin vi /usr/local/tomcat/conf/server.xml

Change:
pathname="conf/tomcat-users.xml"

To:
pathname="conf/users/tomcat-users.xml"
That's it. You can now start tomcat. To do this use the following command:
$ sudo -u tomcat $TOMCAT_HOME/bin/startup.sh

You should now be able to connect via HTTP to tomcat on port 8080 and view the sample web applications.

Feedback

We aim to continually improve this documentation set to make it as easy as possible for new users and seasoned users alike to setup the ESOE securely in unix environments. We welcome any comments or additions you may have on the ESOE users mailing list at any time.


SPEP Grails Plugin

This is a placeholder page for the new SPEP Grails plugin. More documentation will appear here as it is written.

Prerelease

The SPEP Grails Plugin is in a prerelease state. As such, the deployment and configuration are not polished and the code has not been thoroughly tested. Use this at your own risk.

Acquiring the source code

You can check out the source for this plugin with:

svn checkout https://esoeproject.org/repos/esoe/trunk/spepintegrators/grails grails-spep

For the present time, the SPEP filter and dependency jars need to be manually inserted in grails-spep/lib before building the plugin via:

grails prod package-plugin

Installation

As with all standard grails plugins, this can be installed with the grails install-plugin command, i.e.:

grails install-plugin /path/to/grails-spep-0.2.zip

Upon installation, the plugin will create web-app/META-INF/context.xml if it does not already exist. The important part of this xml file is the crossContext="true" attribute, which enables the SPEP filter to access the SPEP war context.

Development version

A development version of the plugin can be built with:

grails dev package-plugin

This development version injects a configurable set of attributes into the user object, rather than retrieving them from the web environment. This allows testing of the application without setting up an SPEP. To configure the attributes, put the following piece of config in your application config, and edit the attributes to suit:

spep {
    devAttributes {
        uid = ["test"]
        name = ["Test user"]
    }
}

Note that all SPEP attributes are treated as multi-valued, so each attribute should be a list of values, even if only one value is set.

If no attributes are specified, the user object is populated as if the user had authenticated successfully with no attributes. This behaviour will likely change in a future version.

Attributes in application code

To access the devAttributes shown above, the following example code can be used:

TestController.groovy

class TestController {
    def spepUser

    def index = { return [authenticated:spepUser.authenticated, uid:spepUser.uid[0], name:spepUser.name[0]] }
}

index.gsp

<html><head><title>Welcome!</title><meta name="layout" content="main"/></head><body>

    <h2>Welcome, ${name}</h2>
    <p>Your uid is: ${uid}</p>
    <g:if test="${authenticated}">
        <p>You are authenticated</p>
    </g:if>

</body></html>