We have a web application which consists of two parts (among others): a 'shell' written in Java running in Jetty using Windows authentication through Waffle, which shows a 'component' written in ASP.NET running in IIS using Windows authentication. Both parts are served from the same host, but (of course) from different ports.
As it stands, a user first must sign in to the shell, and then when the component is loaded the user must sign in again. We want to get rid of that second sign-in step.
From what I've seen and read, e.g. about claims-based authentication and OAuth, the standard pattern for that is the following:
- After signing in to the shell, the shell constructs a 'token' with the user's Windows account name, which it sends back to the browser.
- The component does not use Windows authentication, but instead the browser sends it the token.
- The component verifies that it trusts the token, and uses the identity from that token.
(In our case the simplest technique is to put the token in a cookie, since both shell and component run on the same server, and HTTP cookies are not port-specific, so the browser will automatically send the shell's token to the component.)
Now I see several ways to construct and verify the token, like:
- (a) The token contains the Windows account name, encrypted with a symmetric key that is hardcoded into both shell and component, or generated and agreed at installation time or start-up time.
- (b) The token contains the Windows account name, signed using a private key, and verified using the corresponding public key. This key pair is generated at installation time.
- (c) The token contains a GUID, and the component's server side makes a call to the shell's server side to verify its validity and get the Windows account name.
I think I prefer (b), since (a) seems too 'hardcoded', and (c) is more likely to give scaling issues. Also, we already have a private/public key pair in place in the form of an SSL server certificate in the shell which is trusted by the component.
My main concern with (b) is that the token will contain an (X.509?) signature, which means the token could become fairly large. (Would it?) Also I'm not (yet) familiar with techniques to create a signature in Java, and verify it in .NET.
My question: What is the standard/recommended pattern to use here? What alternatives have I overlooked? Is there a standard protocol that we could use here?