3

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?

Community
  • 1
  • 1

1 Answers1

1

You are on the right track.

Yes, the idea is to have the shell generate a token that cannot be forged (generated by anything/anyone but the shell) that can be verified by the component.

You are right that the token can become quite large. It will not become so large as to be unworkable (i.e. larger than a browser can handle), but it can become a performance issue.

In general, any component that accepts HTTP traffic with any kind of cached authentication is going to have a preferred format for that cached authentication. In your current implementation, after the user signs into the component (the second sign in step) the component will issue some kind of cookie containing identification credentials it will accept for subsequent requests. So the best thing would be for the shell to create exactly those credentials.

Failing that, it's quite reasonable for you to use your option (b) of creating a signed certification form the shell that the component can verify and then replace with its preferred form of authentication credential.

Old Pro
  • 24,624
  • 7
  • 58
  • 106