This space contains the old OpenAthens SP documentation and is no longer maintained.
OpenAthens SP software is already out of support and reached end of life in May 2020.

Check out OpenAthens Keystone instead. It's supercool and makes dealing with SAML much easier.

Search

Skip to end of metadata
Go to start of metadata

The OpenAthens SP Server software does not offer any authorisation functionality.

The provided AtacamaAuthFilter just requires a valid-user and this condition will be met as long as the 'authentication receive' flow exports a 'subject' parameter. This section will outline how additional authorisation checks may be enforced.

Attributes

How attributes are written

The AtacamaBaseFilter will intercept any responses sent from an Identity Provider. If the response is valid this filter will write any attributes to the users' session along with the special attribute subject which will contain the subject value exported from the authentication receiver flow.  The actual value of subject will depend on the underlying configuration and the responding Identity Provider.  Then when a user tries to access a protected page the AtacamaAuthFilter will be called, if the session contains a subject (it's not empty or null) the user will be granted access. If the session does not contain the subject attribute the authentication request process will be invoked.

How attributes are stored

As attributes can be multi-valued, the attribute name is stored in the session as a String and the associated values are stored as a List<String>. E.g:

String attName = .....;
List<String> attValue = .....;
HttpSession session = request.getSession();
session.setAttribute(attName,attValues);

Defining the authorisation policy

In a case where the consideration is whether the end-user is from a site that has purchased a licence we need a way of identifying the users' site for comparison.

The attribute to use for this is scopedAffiliation. E.g:

HttpSession = request.getSession();
List<String> organisation = (List<String>)session.getAttribute("OA_URN_OID_1_3_6_1_4_1_5923_1_1_1_9");

scopedAffiliation is made up of two parts, e.g. role@scope. In this use-case the scope needs to be extracted (the role section could be used for greater granularity such as telling 'staff' from 'student' or 'alum'. There are a small number of possible values).

Implementing an authorisation filter

Example code

package com.sp.example.web.authorisation;
 
/* Need to include the import files */
 
..................
 
public class Authorise implements Filter {
        
        ..................
 
 
    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession();
        @SuppressWarnings("unchecked")
        List<String> usersOrganisation = (List<String>) session
                .getAttribute("OA_URN_OID_1_3_6_1_4_1_5923_1_1_1_9");
 // Extract scope from scopedAffilation
        String scope = usersOrganisation.get(0).split("@")[1];
 // Ensure that we have a value.
        if (usersOrganisation != null && !usersOrganisation.isEmpty()) {
            // This value will be single valued.
            String _usersOrganisation = scope;
 
            if (this.isAuthorised(_usersOrganisation)) {
                // User is authorised so call next filter in chain.
                chain.doFilter(request, response);
                return;
            }
        }
                // If we are where the user is not authorised.
                // We send a 403, but you will probably want to
                // redirect to an error page.
        res.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
 
    /* The authorisation logic */
    private boolean isAuthorised(String org) {
        // This list is hard coded but you would 
        // derive yours from your customer database.
        Set<String> whiteList = new HashSet<String>(1);
        whiteList.add("examplescope.com");
        return whiteList.contains(org);
    }
}

Users from the organisation with the scope examplescope.com would get through.

The web.xml

Edit the web.xml to include our new Authorisation Filter, then add a filter-mapping after the filter-mapping which invokes the AtacamaAuthFilter. Please see the below example fro further clarification:

......
<filter>
  <filter-name>OABaseFilter</filter-name>
  <filter-class>uk.org.eduserv.openathens.atacama.modules.server.servlet.AtacamaBaseFilter</filter-class>
</filter>
 
<filter>
  <filter-name>OAAuthN</filter-name>
  <filter-class>uk.org.eduserv.openathens.atacama.modules.server.servlet.AtacamaAuthFilter</filter-class>
</filter>
 
<!-- New Filter -->
<filter>
  <filter-name>Authorisation</filter-name>
  <filter-class>com.sp.example.web.authorisation.Authorise</filter-class>
</filter>
 
 
<filter-mapping>
  <filter-name>OABaseFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
 
<filter-mapping>
  <filter-name>OAAuthN</filter-name>
  <url-pattern>/protected/*</url-pattern>
</filter-mapping>
 
<!-- New filter mapping -->
<filter-mapping>
  <filter-name>Authorisation</filter-name>
  <url-pattern>/protected/*</url-pattern>
</filter-mapping>
.........

Flow

  1. User attempts access
  2. User is not yet authenticated so the AtacamaAuthFilter redirects the user to their Identity Provider's login page
  3. The user logs in and is returned
  4. The AtacamaBaseFilter intercepts the Identity Provider's response and, assuming there are no problems, the subject and user attributes are written to the user session
  5. The AtacamaAuthFilter is called again but this time as the subject variable is in the session, control is passed to our authorisation filter
  6. If the user is from an organisation with an authorised scope the underlying content will be display to the user, else an 'unauthorised' response will be returned.


  • No labels