IdentityServer / IdentityServer3

OpenID Connect Provider and OAuth 2.0 Authorization Server Framework for ASP.NET 4.x/Katana
https://identityserver.github.io/Documentation/
Apache License 2.0
2.01k stars 764 forks source link

IdP Initiated SSO with Identity Server as the initiator #2572

Closed scottlance closed 8 years ago

scottlance commented 8 years ago

This is more along the lines of an ask for advice or best practices using IdSrv. As far as I have been able to tell Identity Server can be used to authenticate SSO requests, what I haven't been able to find is the ability for Identity Server to act as the initiator of a SSO request.

For example: We use Identity Server as our IdP for a dashboard portal for our business. WIthin this portal we have a number of app that we would like to SSO into, The idea here would be that we would issue Identity Server a request and Identity Server would make the call to the remote IdP which would authenticate that request and allow the user to log into their system. SAML calls this IdP-Initiated SSO.

My initial thoughts around this are that we can build a custom plugin that could create and issue authentication request (either OIDC requests or SAML requests) for each application we want to SSO into.

Thoughts?

TIA

brockallen commented 8 years ago

OIDC doesn't support IdP initiated signin. You need to have a well-known endpoint in your client app that triggers the signin.

scottlance commented 8 years ago

By "You need to have a well-known endpoint in your client app that triggers the signing" I am assuming you mean that in that instance Identity Server is basically out the picture, the client app would need to handle all request creation (be it OIDC or SAML)?

What are your thoughts around a plugin for Identity Server that would host this endpoint?

brockallen commented 8 years ago

That won't work, because the client needs to generate the state/nonce to validate the response from the OIDC STS. This is why you need to send a request to the client to have it initiate the SSO request to IdSvr.

scottlance commented 8 years ago

So given the following example you don't think it would work:

image

I must be missing something. Isn't this how other IdPs (e.g. Okta, Ping Federate etc) work? If you could help me understand what I'm missing I would appreciate it.

brockallen commented 8 years ago

I'm not following... In short for an OIDC token service (like IdSvr) and a OIDC client (say an MVC app), you can't have the user start at IdSvr and login and then be sent with some SSO magic to the client. You can login to IdSvr first, then go to some endpoint in the MVC client and that in turn redirects back to IdSvr for login, but since the user is already logged in they're immediately redirected back to the MVC client with the successful SSO result.

In WS-Fed (and maybe in SAML) you could just POST an authentication token to an unsuspecting client/RP and you'd get logged in, but in OIDC the client won't accept tokens unless it requested them. That's what I meant by OIDC as a protocol doesn't support IdP-initiated signin.

scottlance commented 8 years ago

Ok I think we may be talking about two different things. Let me go into exact detail about what we are trying to accomplish.

We use Identity Server as our STS. We have a portal application that allows our users to access several different applications, some of these are internal and some are external. The flow for the portal is this:

  1. The user tries to hit the landing page for the portal application.
  2. The application does not have a id_token for the user so it redirects them to the STS (IdSrv)
  3. The user logs into the STS
  4. The STS generates the id_token and redirects back to the landing page

Now that the user is logged into the portal application with the STS id_token we present to them an 'app drawer' that has a bunch of different applications that they can use. The internal applications that we have written are using the STS for auth, so as long our STS id_token persists the user can use those applications. All the app drawer is, is a link to these applications and when the user gets to the application, its the applications responsibility to make sure they are authorized (e.g. [Authorize] in the case of our MVC apps).

This is standard OIDC, my question now relates to external applications (SP) that require us to SSO. Some of these applicaitons are unfortunately SAML and others are OIDC. I want to come up with a common way to sign into these external applications (SP) without having to rewrite a new OIDC request or SAMLRequest for each link.

My initial concept was to write a MVC app/Web API/HTTP Handler for each SSO case that would create the OIDC or SAML request and then go through the appropriate flow for the SP and then redirect the user to the application after the authorization was taken care of. I think this is what you were trying to tell me to do.

You confirmed that IdSrv does not do IdP Initiated SSO, and what I'm trying to get at is, could I by writing a plugin based on the structure of say the IdSrv WS-Federation plugin, accomplish the external SSO to the SP without the need of another piece of infrastructure in our system (e.g MVC app/Web API/HTTP Handler).

My thought around that is that the plugin would expose an endpoint that the link in the app drawer would link to and would also pass all the information required to log into the SP (e.g. SP Name, Username ect). The plugin would then get the information from the request, figure out which SP it would auth with and then create the artifacts necessary to log into the SP be it OIDC or SAML. Once the auth with the SP has finished the plugin would then redirect the user to the SP and they should be logged in.

I hope that makes what I'm asking clearer.

Thanks again for your patience.

brockallen commented 8 years ago

It might work for the SAML SPs -- not sure. But it won't work for the OIDC clients. You're going to get the "nonce does not exist" error if you somehow try to submit an id_token to the OIDC clients that aren't expecting it.

brockallen commented 8 years ago

More info from the OIDC spec on IdP-initiated signin. In short, the RP/client needs a dedicated endpoint for this:

https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin

scottlance commented 8 years ago

Thanks for the info. Right now our immediate needs are SAML based anyway. I'll do a prototype and throw it up on Github if you are interested.

BrandonBrowning commented 8 years ago

@scottlance How did that prototype work out for you? Got any pointers for others in your situation?

brockallen commented 8 years ago

Any update?

scottlance commented 8 years ago

I've got a "basic" authentication plugin working. The provider does their auth in a pretty unorthodox way. I'm going to be writing a SAML2P plugin shortly. I can post a very rudimentary plugin based off the WS-Fed plugin. I'll send a link when I get it up

----- Reply message ----- From: "Brock Allen" notifications@github.com To: "IdentityServer/IdentityServer3" IdentityServer3@noreply.github.com Cc: "Scott Lance" scottdlance@gmail.com Subject: [IdentityServer3] IdP Initiated SSO with Identity Server as the initiator (#2572) Date: Mon, Feb 22, 2016 10:45 AM

Any update?

— Reply to this email directly or view it on GitHub.

scottlance commented 8 years ago

My sample code is posted at: https://github.com/scottlance/IdentityServer3Plugin

I've based all of this code off the WS-Federation plugin. Since I have the correct information to negotiate with the service provider, I've proved this works in our environment, but for the most part this is template code for how I created the plugin.

I'm going to work on a SAML plugin next.

scottlance commented 8 years ago

I probably wont be working on the SAML plugin soon due to higher priorities. I will keep everyone updated, but for now I'll close the issue.