Bug 54503 - SAML2 based single sign on
Summary: SAML2 based single sign on
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.0.x-trunk
Hardware: Macintosh All
: P2 enhancement with 5 votes (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-29 15:30 UTC by Toby Hobson
Modified: 2016-02-16 21:46 UTC (History)
1 user (show)



Attachments
Unified diff including new and changed files (326.48 KB, patch)
2013-01-29 15:30 UTC, Toby Hobson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Toby Hobson 2013-01-29 15:30:00 UTC
Created attachment 29906 [details]
Unified diff including new and changed files

SAML2 is a standard for cross-domain single sign on and federation. We have developed a Tomcat authenticator which acts as a SAML2 service provider i.e. it allows Tomcat applications to delegate authentication to a single sign on server (identity provider). We already offer this authenticator to our customers but we would now like to contribute it to the wider Tomcat community.

Whilst Tomcat already offers single sign on between webapps, SAML2 allows SSO between different platforms (.NET, PHP etc) and different hosts so we feel it's a useful contribution.

The authenticator we have developed supports the most common SAML2 profiles and binding i.e. the Web browser SSO profile using the redirect/post binding. We have tested it with our own SSO server and also with a PHP implementation (Simple SAML PHP). It should also work with other SAML2 implementations although this has not been tested.

I've attached quite a large patch which includes couple of changes to the core code and several additions:

- A new authenticator (SamlAuthenticator)
- An example webapp which demonstrates some of the features
- Various tests (which make use of the example webapp)
- Updates to the build.xml script
- Updates to the documentation, explaining how to use the new authenticator. We still need to add some more detail here
- Minor changes to Realm and RealmBase (see below)

The SamlAuthenticator always retrieves the username from the IDP (SSO server) and it can retrieve the Principal's roles one of two ways: 1) The IDP can pass the roles across to Tomcat along with the username. 2) Tomcat can lookup the roles from a configured Realm. To achieve this we had to make a change to Realm to allow allow "authentication" using a username alone.

The authenticator has 4 dependencies:

- saml2-core (our general saml2 library, in maven central with an Apache 2 license)
- log4j (required by saml2-core)
- commons-codec (required by saml2-core)
- commons-io (required by saml2-core)

This patch should be applied at p0 i.e. "patch -p0 < saml2.diff".

I'm sure there will be plenty of questions which I'm happy to answer

Toby
Comment 1 Christopher Schultz 2013-01-29 18:47:50 UTC
I'm floored: a great idea, backed-up with a complete set of diffs including test cases and examples. I'm looking forward to diving-into the code further when I get some time.

I did have two initial reactions when doing a (very) brief overview of the patch:

1. Is the term "Cloudseal" a requirement? I see that, for instance, the type of authentication is registered as CLOUDSEAL instead of, say, SAML2. I think we'd prefer to use the generic name (SAML2) rather than a particular service (Cloudseal).

2. I noticed that you changed CombinedRealm.getPrincipal(). Can you explain why that needed to change? I don't see any of your code that calls Realm.getPrincipal.

Again, thanks for the great contribution.
Comment 2 Toby Hobson 2013-01-29 21:08:21 UTC
Hi Christopher

"Cloudseal" is certainly not a requirement, SAML2 would indeed be a better name. I think the term is a hangover from our current implementation of the authenticator which we offer with our product (we describe it as a "Cloudseal Authenticaor). The only thing I would point out is that the code uses a class called CloudsealPrincipal. This would have to remain because CloudsealPrincipal is defined in our saml2-core library. We may refactor this class at some stage but there's nothing SAML specific about it (and we also use it for our OAUTH2 implementation)

There's a transitive dependency on CombinedRealm.getPrincipal(String) - As mentioned in the bugzilla comments the SamlAuthenticator can lookup roles against a configured realm. We modified Realm to add authenticate(String). RealmBase.authenticate(String) calls getPrincipal(String) and CombinedRealm extends RealmBase. The modification allows a developer to use CombinedRealm with the SamlAuthenticator if he wants.
Comment 3 Mark Thomas 2013-06-20 14:43:21 UTC
That is a big patch.

I have one immediate concern with the proposed patch with is the unknown licensing of the new JAR file.

Looking more broadly, I think it would be worth (re-)considering adding JASPIC to Tomcat. Most of the code should be available in TomEE. That would then provide a standard mechanism to plug-in additional authentication mechanisms such as SAML2. At the moment, I'd be happier with SAML2 as an optional extra rather than as a core component.
Comment 4 Toby Hobson 2013-06-20 17:19:03 UTC
(In reply to Mark Thomas from comment #3)
> That is a big patch.
> 
> I have one immediate concern with the proposed patch with is the unknown
> licensing of the new JAR file.
> 
> Looking more broadly, I think it would be worth (re-)considering adding
> JASPIC to Tomcat. Most of the code should be available in TomEE. That would
> then provide a standard mechanism to plug-in additional authentication
> mechanisms such as SAML2. At the moment, I'd be happier with SAML2 as an
> optional extra rather than as a core component.

Which jar? saml2-core is licensed under Apache 2
Comment 5 Mark Thomas 2016-02-16 21:46:51 UTC
This isn't going to be added to the core Tomcat distribution but as of Tomcat 9 (9.0.0.M4 onwards) Tomcat supports JASPIC which provides a pluggable mechanism for authentication.

Given the relatively low level of interest, a 3rd-party JASPIC module looks like the way to go for SAML. If you do go this route then do let the Tomcat team know if you find any issues in the JASPIC implementation and we'll get them fixed.