Simon's Musings

September 19, 2008

Integrating Jabber web interfaces with Cosign (and other SSO technologies)

Filed under: Uncategorized — sxw @ 7:25 pm
Tags: , , , , ,

Back in May 2007, I wrote a blog post discussing hypothetical mechanisms for integrating the JWChat web-based Jabber client with a web SSO solution such as WWW-Negotiate or cosign. In my not-so-copious spare time, I’ve been working on implementing this, and now have a working solution to share. Skip to the end of this post if you’re just interested in the code.

Web-based jabber clients such as JWchat differ from many other web applications in that the application actually lives on the client side. Javascript running in the user’s browser communicates with the Jabber server, via a proxy. The proxy takes XMPP (the Jabber protocol) data encapsulated in an HTTP tunnel, and relays it directly to the Jabber server. For this project, I’ve concentrated on the Punjab python-based proxy server, and the http-binding (BOSH) encapsulation technique.

In order to perform SSO, the client must authenticate the encapsulated HTTP connection in the usual way. The proxy must then hijack the client’s authentication step with the Jabber server, and replace it with one that uses credentials delegated to it as part of the HTTP connection establishment. Our credentials are all Kerberos based, which simplifies this step hugely. Here’s a rough description of how it all works when using the WWW-Negotiate HTTP authentication mechansim

  • The client makes an HTTP connection to the proxy, which is authenticated using the client’s Kerberos credentials. The proxy performs this negotiate, and stores the delegated credentials
  • The client and the jabber server start up the XMPP connection via the proxy
  • Providing the authentication step succeeded, the proxy intercepts the server’s list of acceptable authentication mechanisms. If the server indiciates that GSSAPI is acceptable, the proxy adds the SASL EXTERNAL mechanism to the list. (EXTERNAL is a trivial mechanism which just indiciates that the server is prepared to accept an out-of-band authentication method)
  • The client initiates an authentication using the EXTERNAL method
  • The proxy intercepts the first EXTERNAL authentication stanza, and replaces it with a GSSAPI stanza, created using the stored credentials that were delegated in the first step.
  • The proxy and the server continue to exchange stanzas, without involving the client, until the connection establishment either succeeds or fails.
  • The proxy returns the success or failure stanza to the client – which views this as the result of its attempt at EXTERNAL authentication.
  • Normal operation resumes

However, as I’ve discussed previously, the level of client side configuration required by WWW-Negotiate, especially when credential delegation is required, makes it difficult to deploy in a heterogeneous environment. That’s why we use Cosign as our WebSSO solution, rather than using Kerberos directly, and pretty much requires this solution to work with Cosign.

Cosign complicates things because it’s based on redirects, and (ultimately) on user interaction following those redirects. It also has a pretty complicated web-server side module which can’t be easily implemented within the python-based Punjab (rewriting the cosign client as a python Twisted module might be an interesting side project, but not for today). Cosign’s redirects means that you can’t easily use it to authenticate XMLHttpRequest connections, especially when those connections are POSTd. Instead, what we must do is use Cosign to authenticate the fetch of the HTML landing page. Once this page is fetched, and authenticated, Apache has taken care of populating the cosign cookie on the client, and placed a ticket file containing the delegated credentials on the server.

This all actually simplifies things for the proxy. Instead of having to accept a WWW-Authenticate GSSAPI handshake from the client, it just has to check for the presence of a cosign cookie. Having found the cookie, it can then locate the ticket file on the server, and tell the proxy to use that file to obtain credentials with which to authenticate to the server.

Code

Enough talk, now for the patches …

JWChat, or more correctly, the JSJaC connection library that it uses requires a couple of small patches. The first fixes a bug with session restarts, which would otherwise break Punjab’s XML parser. The second adds support for using the EXTERNAL SASL authentication mechanism

The major changes are to Punjab. This patch adds support for doing both cosign and WWW-Authenticate authentication (if you aren’t interested in cosign, the patch should still function correctly – it will just skip the cosign parts when cosign cookies aren’t present with the incoming connection). In order to do GSSAPI authentication from punjab, you will also need my python-gss module.

Configuration wise, in order to use cosign, punjab must be accessed as a proxy through a cosign authenticated location on your web server. The JWChat html pages must also be served through a cosign authenticated location, which requires delegated tickets.

January 29, 2008

Integrating cosign with web sites

Filed under: Uncategorized — sxw @ 12:48 pm
Tags: , , ,

I’ve made a couple of changes over the last few days with a view to making it easier to integrate cosign authentication with web applications, and web sites in general. These are trivially available to sites which are built with the LCFG apacheconf and cosign components, and will be available in the next stable release.

Standard Logout Mechanism

Firstly, a standard logout CGI script is generated by the cosign component, as /var/www/cosign-logout/logout.cgi. Sites built with apacheconf can include the cosign-logout configuration fragment in their host defintion to map this to the /logout URI on their site.

Cosign requires a site-local logout mechanism due to the way in which it uses cookies to record user authentication. When a user is authenticated to cosign and accessing your site they have two cookies, one for your site, and one for the central cosign server. If your logout button only redirects to the central cosign logout page, then that site cookie will continue to exist – so users will be able to still access your site for a brief period of time after they have logged out. Needless to say, this tends to confuse people.

The local logout CGI will remove the local cookie, and then redirect them to the central login service. It should be linked (or redirected to) after your web application has performed whatever internal tidyup it requires on logout (for example, it may have its own cookies to remove).

Authorization

For some services, it is desirable to check a user’s entitlements before allowing them access. Until the new account management technology is available, it is only possible to give local users entitlements, so the mechanism below cannot be used on services which allow access by iFriends.

Entitlements are accessible as LDAP groups, so can be checked using LDAP authorization. To enable this for your web server, you need to include dice/options/apacheconf-ldapauthz.h in the server’s profile. Then you should include the ldap-authz configuration fragment in the configuration of each site you wish to protect. The implementation details of this is different between the DICE Apache 1.3 build, and the Fedora Apache 2.2 system, which unfortunately changes the final configuration steps.

Apache 1.3

Individual sections of the site may then be protected by doing

<Location /my/secret/data>

CosignProtected On

AuthType Cosign

Require group my/entitlement/name

</Location>

(my/entitlement/name is the entitlement that you want to restrict access to)

Apache 2.2

<Location /my/secret/data>

CosignProtected On

AuthType Cosign

Require ldap-group cn=my/entitlement/name,ou=Capabilities,dc=inf,dc=ed,dc=ac,dc=uk

</Location>

(again, my/entitlement/name is the name of the entitlement you wish to restrict accces to. Note that you must specify the full DN of the entitlement, rather than just the name)

Theme: Rubric.