views:

95

answers:

3

Hello,

Looking at the OpenID protocol, it appears that the relying party needs to send a request to the identity provider. In our situation, this is not exactly ideal since the identity provider is behind a firewall-- our server will not be able to make the request. However, the user accessing our website (client-side, e.g. javascript or redirects) would be able to. So my question is this: does OpenID support an identity provider behind the firewall? If not, is there a secure way of accomplishing this?

EDIT:

The client has a web server behind their firewall. They have employees that visit our website and thus are able to visit our site and their webserver which resides behind their firewall-- our server, however, would not be able to. The Identity Provider resides on their webserver, behind their firewall-- our application (Relying Party) needs to be able to use this internal employee Identity Provider for their employee authentication.

Thanks! Josh

A: 

Your question isn't clear to me.

If a client is able to access the provider that is behind firewall, the server should also be -- it connects to the same port, using the same method as a client.

If the provider isn't accessible from the outside, then it's useless, like any other inaccessible server.

If it's your relying party can't make outgoing connections to the server, then nothing can be done -- there must be at least one direct request from the RP to the OP.

In summary: yes, the relying party must be able to connect to the provider.

Mewp
The client has a server behind their firewall. They have employees that visit our site and thus are able to visit our site and their server which resides behind their firewall-- our server, however, would not be able to.
Josh Barker
Oh, I see. However, it is necessary for the server to connect to the provider, otherwise the client could just forge server's responses.
Mewp
Okay, that is what I thought.... hmmm... so this is completely not doable? What about sending the request using the client system (employee's browser, e.g. javascript, form post, etc)? We have complete control over the code behind their firewall and the code on our end.
Josh Barker
Looks like there is a client-side javascript partial RP example? http://code.google.com/p/openid-selector/ ... looking into this.
Josh Barker
You still have to verify with the OP, otherwise you can't be sure that the information provided by the client really comes from the provider. As far as I know, even if someone managed to do that in javascript, it's worthless as an authentication mechanism.
Mewp
I got the partial RP working-- when I place it in combination with server-side verification of the signature, it should be a working solution.
Josh Barker
A: 

Found out that there is a way you can create a client-side RP using this as sample code: code.google.com/p/openid-selector . I modified the code to fit our situation and it seems to work. The caveat here is that you do not use auto-discovery and instead are required to hard-code the endpoint (which is perfectly acceptable in my situation).

Josh

Josh Barker
Bad bad. The code.google.com/p/openid-selector is *only* a Javascript part of a relying party. It is NOT a complete solution. I suspect your server is *wide* open to attack because it doesn't verify the signature, so anyone can log in as anyone by just fiddling with the URL that comes back to your web site.
Andrew Arnott
Right, thanks for the heads up, this portion of the RP is all I need. I will be doing verification of the signature on the server-side.
Josh Barker
+2  A: 

OpenID relying parties must be able to verify that the assertion the user obtained is genuinely from the OpenID Provider. Otherwise your RP is wide open to simple attacks.

Traditionally signature verification requires that the RP server contact the OP server directly. Since this is impossible in your case, your only alternative is to hard-code a shared association secret between RP and OP. You make up an association handle and a cryptographically strong secret for that association, and tell the RP and OP about it and that it never expires. Then every auth request your RP sends must ask the OP to use that particular association handle.
Of course an association that never expires carries security risks of its own. You can mitigate that (partially) by being sure it's an HMAC-SHA256 association rather than just HMAC-SHA1.

Finally, user identifier discovery typically requires a direct HTTP connection from RP to OP, but this can be easily avoided by using identifier delegation (set up identifiers on a non-firewalled server that point to the OP behind a firewall). Alternatively your solution of hard-coding discovery results including the OP Endpoint is just fine too for a specialized solution. You've got to be careful to block all the security risks that this opens up though (like making sure the identifier really is from the set of URLs that you're hard-coding, otherwise people can spoof identities from other OP endpoints.

Since you're using DotNetOpenAuth what you can do is create your own IDirectWebRequestHandler class and set that on your OpenIdRelyingParty.Channel.WebRequestHandler property. This handler will have the opportunity to intercept outgoing HTTP requests to [server-behind-firewall] and "redirect" the request by simply synthesizing an HTTP response of your own that is the XRDS that the server behind the firewall would produce if you could only reach it. There should only be two XRDS documents per OP (one is the OP Identifier and the other would be all the claimed_id's that the OP asserts). That should get your discovery both before and after authentication working correctly.

Andrew Arnott
I'm working on this project while learning OpenID, so this is great information. Had a question though-- our solution, being specialized, would it be possible to make the association between the RP and the OP, by way of first visiting the OP (the OP makes the association?). We will have a single RP and many OP's (opposite of the norm). That way, the OP can make a server-side association with our RP (OP makes request to RP).
Josh Barker
I'm afraid that doesn't work. Merely visiting the OP doesn't create an association between RP and OP. If all the OPs are behind firewalls you'll need to hard-code (unique!) associations between each RP-OP pair. And again, be *very* careful that you verify the signature and the identifier carefully or else you'll open yourself for identity spoofing. I'm actually pretty scared for you being new to OpenID *and* doing something this advanced. OpenID wasn't optimized for this scenario and you *might* want to consider other protocols in this case.
Andrew Arnott
I'm new to it in the sense that this is only my 3rd implementation-- and never done this type of integration before (sounds like abuse of OpenID?). What protocol would you recommend? Essentially what we are doing is have a SaaS website and our vendors want to login using their custom credentials (which are behind their firewall, e.g. LDAP). We don't want to introduce hassle of opening their firewall, but it sounds like that would be a good viable option.
Josh Barker
Josh Barker
Ah, I thought you were building this from scratch. If you're using DotNetOpenAuth then I'm much less scared for you because DNOA won't let you go too far wrong unless you go out of your way to do it.A Windows Service that automatically rotates shared association secrets is awesome! You can tie that into DotNetOpenAuth just by way of your custom IAssociationStore, which it sounds like you've already figured out.
Andrew Arnott
I've added a paragraph to my answer describing how to get identifier discovery working even though the server is behind a firewall.
Andrew Arnott
Oh, and as far as the right protocol for the job, OpenID might still be the closest fit from the protocols available today. But DotNetOpenAuth's feature set for OAuth 2.0 (currently in unstable CTP) would make something like this much easier, since the "resource server" doesn't *ever* need to talk to the "authorization server", so the firewall would be a total non-issue.
Andrew Arnott
Wow, thanks a lot for the additional information-- *very* helpful! So it is possible to do use identifier_select (http://specs.openid.net/auth/2.0/identifier_select) with the identifier delegation?
Josh Barker
Yes, you can create your own OP Identifier for someone else's OP. But you can't create your own identifier to substitute for the one that the OP asserts on the way back out.
Andrew Arnott