Multiple Identity Providers

Hello!

I’m new to Hydra, and trying to see if it can fit my use case. I have multiple websites(50+) that each have a different pool of user accounts. I would like for each of these sites to be able to use any of the other sites to log in to the original site.

So for example, say i have site red and site blue. If a user has an account on red, I would like him to be able to use that account to sign in on blue. And vice versa. So in effect, each site would be an identity provider, and be able to use its accounts to sign in to the other sites.

Ideally, I would like to be able to do this using 1 instance of hydra where each site was a separate client in hydra. Searching your forums and the net, I was able to find this post(below) which seems to be similar.

From this, the docs, and the sample login/consent app, i was able to setup a simple test case where i have the 2 sites(red and blue) setup so that starting on red, i can use the auth code flow to redirect to blue to login, consent, and get my code then tokens. however, i end up on blue with all of my tokens made for blue, where as my intent is to end up on red with tokens made to be used on red, but with account info for the account on blue.

I was hoping you might be able to give me some assistance as to how to proceed from here. Or if not, let me know if i’m trying to do something Hydra is not designed for.

Thank you for your time, and hope to hear from you soon!

Hi there, so there’s some questions here that need to be answered for context:.

  1. Will red and blue stay with their existing identity pool?
  2. Will you migrate red and blue to a new identity store?

Depending on that I can give you an answer. Both use cases are possible IMO.

Sure thing.

1.) Yes, any sites that use the functionality will remain in their current identity pools. ie red signs into to blue, red is still able to use its same credentials to sign in with red as well.
2.) No, red signing in to blue is just letting blue know that this is a user on red, and can use red’s information. No additional user will be created.

Ok, the easiest way to solve it is like this:

  1. You run one hydra instance with one consent and login app
  2. The login app uses e.g. the email address to identify the user pool (e.g. red or blue)
  3. Both red and blue are modified and now capable to accept, and validate access tokens or openid connect id tokens from hydra.
  4. Done

So the missing link is that you need to implement a login app (the consent part is not that important here, just standard I’d say) which is capable of choosing the right identity pool.

Shouldn’t be a lot of work IMO!

I don’t think i’ll be able to use email address to distinguish whether the request is coming from red and blue. It’s possible(and even likely) that a user account on both red and blue have an account using the same email. We have a fair amount of overlap of users. So i guess the question becomes how do i distinguish where to send the flow to login, which was where i started.

(Again going on the assumption red is logging in with blue and wanting to end on red), Initially, on the login app, i was using the login challenge to get the client id, and from there direct to the proper login, which works fine. But at that point, i end up on blue, because i log in on blue and the auth code flow stops on blue because i use blue’s client id in the initial url to start the auth code flow.

I could register redirect uris on each site for every other site, but that ends up being a lot of upkeep and even if i do that, when i go to exchange the auth code for tokens, it would be using red’s id/secret instead of blue’s, and the flow would error out.


Edit:

Ah, i think i see at least part of the answer now. So, i’ve been running the auth code flow with blue, when i should be running it with red. That makes sense, and even obvious in hindsight. But my issue is knowing how to redirect to blue in the middle of the flow. If i initiate the flow with red, i can’t use the login challenge to get blue’s client id, and i can’t distinguish by email. Is there any other way I’m able to discern where i should be sending the user to login if i can’t use either the email or login challenge?

I don’t think i’ll be able to use email address to distinguish whether the request is coming from red and blue. It’s possible(and even likely) that a user account on both red and blue have an account using the same email. We have a fair amount of overlap of users. So i guess the question becomes how do i distinguish where to send the flow to login, which was where i started.

Distinguishing by emails is just an example. Up to you how that works, can be anything really, even trying to log the user in at several sites and take the ones that accept is as the source - if your security model allows that.

Ah, i think i see at least part of the answer now. So, i’ve been running the auth code flow with blue, when i should be running it with red. That makes sense, and even obvious in hindsight. But my issue is knowing how to redirect to blue in the middle of the flow. If i initiate the flow with red, i can’t use the login challenge to get blue’s client id, and i can’t distinguish by email. Is there any other way I’m able to discern where i should be sending the user to login if i can’t use either the email or login challenge?

Not sure if I get this. The OAuth2 flow always starts at a client and ends at that same client. If you initiate log in from blue, it ends at blue. What happens in the middle (pulling user info from multiple sources) is separate from that.

The OAuth2 flow always starts at a client and ends at that same client

This was my main issue. Since i was using the login challenge to redirect to the correct login page, I was incorrectly assuming that the flow needed to be initialized by by blue, where as I really wanted to be starting it with red.

I can’t use anything to determine where i need to redirect the login, so I think I am going to use the login app itself to let the user choose who they want to log in with instead of making that choice before hand and trying to pass it through to Hydra.

Thank you very much for your help and quick replies!

Hi,

I did not want to start a new thread because my question is similar to this one. I did my first implementation of the login app, everything works well - although I did struggle a bit with the documentation. Now I am trying to imagine the scenario where I would have, for the same app, an internal user database and support for, let’s say, Google accounts. I think I imagine the flow but I wanted to make sure I am on the right track.

I think the solution is first to figure out which authentication method to use and then use OIDC with Google. Let’s say, for simplicity, that anything @gmail.com would be assumed a Google account.

I have to tell Hydra that I accept the login by calling its API with the challenge provided. Which means that I have to get the challenge and my login service has to be called as callback URL by Google.

  1. My login app is, essentially, a client from Google point of view
  2. I receive the login request in my login provider with the challenge from Hydra. I prompt the user for the username. Form is posted back to my login service. I look at the domain of the email address and decide which identity pool it belongs to.
  3. If it is not @gmail.com - then I do what I did before. Skip to the end.
  4. If it is @gmail.com - I have to redirect to Google’s OIDC endpoint.
  5. User interacts with Google somehow, eventually, I get the callback with IDENTITY_TOKEN. Token is signed, I can confirm that the user has been successfully authenticated with Google.
  6. I can do some magic, like doing lookup for my internal user ID etc. Finally I call “accept” API on Hydra and redirect the user to the returned URL.

My only concern with this flow is how to preserve the challenge value between the step 4 and 5. Is there a 100% reliable method for this? I can imagine I could probably use the challenge value as (part of) the session token I pass to Google’s OIDC endpoint…but then it comes to the question about how compatible are the challenge and the token, allowed characters, length etc.

What is the right way to implement this use case with Hydra?

The best (and safest) way to do that is to store the challenge in a cookie/session. That way you’re sure that the person that returned to the end point is also the person that initiated the flow. You need a cookie/session anyways to store the “state” for the Google OIDC flow :slight_smile:

OK, but for everything else - does this flow I described above look correct? I think the description of how to do it would be a great addition to the documentation. So the “login provider” becomes, essentially, a router between different identity providers and OIDC is the protocol to be used there.

Yes, totally