Skip navigation.
Home

How to securely redirect users between web applications at different corporations without a packaged SSO solution

Browser RedirectIt was hard to come up with a title for this article... Essentially the problem that I have been repeatedly been asked to solve is: Company A wants to use Company B's web application within it's own web application. How can we make sure that only people from Company A will be able to access Company B's application?

The Problem

The company that you're working for has a web application (A) that needs to use some other company's web application (B). You as the developer (of A) responsible for the integration between A and B, ask for the API and a login for application B. After reading up on the API, you login to B and start clicking around. From a security perspective, you realize that application B is setup to work with user ids and passwords as the main authentication mechanism and roles as the main authorization mechanism.

So one question becomes, how are you going to get application A to use the proper user ids and roles for application B?

Some Possibilities

I have employed each of these techniques at some point; one is usually right for the situation. The delineating factors are usually the number of users in application A, cost and the overall talent level of the developers of applications A and B.

  1. Dual login. You could simply not do anything and have users login "twice" (once in A and again in B). The user ids would more than likely be different unless you do some kind of login migration.
  2. Login data migration plus dual login. You could copy all of your user ids and roles into the destination system. Usually this implies some kind of batch process to either refresh the entire set (or just the deltas) at some time interval. The users would still need to login "twice" but at least the user ids and passwords would be the same.
  3. Jerry rigged single-sign-on (SSO). Essentially this is login data migration plus dual login but application A also auto submits the login to B before redirecting to application B. The main idea here is to make the user not ever see application B's
  4. Package SSO solution. There are some products out there specifically designed for SSO. Think CA's Siteminder, CAS, or any Kerberos kind of solution.

The key thing with any of the above solutions is that the authentication/authorization model works similarly in both applications...

What if application B's security model doesn't work like A?

The most current problem that I ran into (and the reason I'm writing this article) was that application B was never intended to be used the way we needed it to work.

Here's an example. Let's say that application B is a generic survey tool. The way it works is that survey authors login to the application and create surveys. Those surveys are then published and sent out to survey takers (via email) who do not ever log in to the application.

Now let's say that the users of application A are the ones that need to take the survey. The flow turns into: a user logs in to A and then clicks on a survey link (which is a uniquely generated url), then fills out the survey. Since application B (the survey) never authenticated the user, anyone who has the link to the survey could take it. This is really security through obscurity at the point (it is really hard to guess or generate the URL).

This security model is probably sufficient for the survey application (application B) when it is used in isolation. But what if more than one user from application A needs access to the exact same survey (authentication difference)? Also add the requirement that users from application A should only be able to access the survey sometimes, not all of the time (authorization difference).

Essentially the problem here is that application A has higher security requirements than application B.

Possibilites Revisted

Okay so now we know that we need to upgrade the security of application B (or downgrade A). There's no way you can downgrade A so how could we use any of the previous possibilities to upgrade application B's security? All of the previous solutions require application B to upgrade the fundamental security model in place. IMHO, 3rd party vendors are not usually willing to fundamentally change their core product for one customer. Sometimes they do, but the negative side effect is that it is going to take a long time. The vendor would want to perform full regression tests to ensure that all of their other customers will still be functioning. Also vendors usually have their best developers working on new functionality, so you'll normally get stuck with junior level developers working on security enhancements (a recipe for disaster).

Most products (halfway decent ones at least) have extension points built into them where extra functionality can be employed. On my last project the alternative for us was to partner with the vendor to create a custom security module only for us. This module would be attached to the vendor's current application at an already defined extension point. So the testing effort would be contained to the extension and not have any impact on the vendor's core application.

The Way Forward

Ok the next thing that we did was define how we were going to really do this. Here is what we considered:

  1. Change the security model of application A and the extension module of B to use an inexpensive third party mechanism (e.g. CAS is free).
  2. Have the extension module of B use a home grown security mechanism.

The business chose #2 because of reduced complexity. If we had gone with #1, it could have been faster to implement but that would only be true if all of the actors in the equation could use the third party module out of the box (or the third party module had excellent support).

Authentication and Authorization Specification

  1. Users must not have been able to guess the URL for Application B and gain access. Security through obscurity was not sufficient.
  2. Generated credentials to Application B had to expire. This prevented bookmarking (replay) of credentials to Application B.
  3. Users should not have been able to escalate their role in Application B. The URL to Application B had to be tamper proof.

Redirect URL

In order to fulfill the requirements we would need to link to Application B with a URL that at a minimum has:

  • a token: the time in millis from a fixed point in time (e.g. unix epoch). This will be evaluated by Application B, if it has been too long, the request is invalid.
  • the user's id: a string, to be used on the callback
  • the user's role: a string, to be used on the callback and for authorization in Application B.
  • a CRC: a SHA-1 hash of (the token, user id, role and a non-publicly visible element) as a HEX string. To be verified by Application B, if it doesn't match this value the request is invalid.

The URL would look something like this: https://Bhost/Bapplication?TOKEN=12345678&USER_ID=matt&ROLE=admin&CRC=2b94372d1f0a2d7771359fbe4bc198c13c9c979c

CRC Formula

Since we are using JEE on one side and .NET on the other, we need to use a format that can be created by both systems. If the CRC doesn't match, the request is invalid. For the Java side, it is super easy to make a .NET compatible string by using:


org.apache.commons.codec.digest.DigestUtils
     .shaHex(userId + token + role + non-public-visible);

For the .NET folks we used this article (which had some tips on padding) to make a Java compatible string: http://authors.aspalliance.com/thycotic/articles/view.aspx?id=2

Here's an example test case that should pass (the .NET article has some more):

userid: jjohnson

token: ABCDEFGH

userrole: ROLE_2

non-public: 633712906001197959

Those inputs should yield: 2b94372d1f0a2d7771359fbe4bc198c13c9c979c

Client Side (Browser) Redirect Solution

The beauty of this solution is that the deployment of both applications doesn't really matter. All that matters is that the browser can access each application. This solution doesn't really require your infrastructure (IT) people to get involved.

Browser Redirect

Server Side Proxy Solution

There is another way to do this very same solution via a server side proxy instead of a client side redirect. Here the advantage is that the user has no access to the URL that goes to application B (so no possibility of bookmarking) and the experience is seamless. You can embed this call as an iframe (or object) in the browser and even Safari will work with it. This has the exact same security as the redirect solution, with an added layer of obfuscation in that the users never even see the redirect url.

The caveat is that you need to be able to seamlessly stream content to the browser (across domains). This solution will only work if Application B is hosted on a sub-domain of Application A (or you setup some kind of reverse proxy type deal). You won't be able to set Application B's session cookie if this is not the case. Also, the internal workings of Application B must be able to use the sub-domain as the host. A lot of applications will redirect you after the first click to the true domain of the Application instead of the one you arrived with.

Server Side Proxy

Conclusion

It is a fair bit of work to implement secure transfers between two different corporation's web applications. Hopefully this article will take out a good bit of the design phase brainstorming and help you focus on the specifics of the implementation. I've found that the hardest part of the solution is getting everyone on the same page-- explaining how the two applications are going to work together and the responsibilities each application are key to this. Once everyone understands the sequence diagram, the implementation is pretty straightforward.