Identity Server Saml2AuthExtensions Idp initiated SSO - c#

We currently have our identity server setup with Sustainsys/Saml2 extensions to allows 3 party clients to login to our product via sso, where the request is initiated by the client hitting our login page to start the request.
We now have a customer you want to put a link into there own software to start the process, creating a ldp initiated request.
My question is how do i go about implementing this using identity server and the Saml2AuthExtensions. I've had a look and i cant see anything extra that might allow this through. Does it just work out of the box, or do i need to setup something else?
Cheers

The SAML2 standard supports "Idp initiated sign on", which can be enabled in the Sustainsys.Saml2 library with the AllowUnsolicitedAuthnResponse flag on the Idp. It is however a bad idea, because the idp initiated flow is by design vulnerable to session pinning attacks. I have seen people make IdentityServer work with idp initiated sign on, but it's awkward, because IdentityServer is not built to support it.
It's much better to use the OIDC way. Have the customer put a link directly to the client application (I assume that the end goal is a client to IdentityServer, using OIDC). Then create an endpoint on the client that initiates an OIDC sign on to IdSrv, with an amr value indicating to IdSrv that Saml2 should be used for authentication. That can give a solution where the user clicks a link, goes to the client, is redirect to IdSrv, is redirected to the Saml2 Idp where they are automatically signed in (using e.g. Windows Auth or an existing session). Then they are automatically redirected back to IdSrv which redirects back to the target application.
From the users' perspective they have a link that will automatically log them in to the application.

Related

Is it possible to sign out a User in IdentityServer4 as a different user?

The flow I am trying to figure out is this:
UserA is logs into ClientA
ClientA redirects to Idenitity Server to authenticate user
after authentication ClientA manages User info in its own system
UserA is found to be a "bad actor"
AdminUser goes into IdentityServer AdminTool (a different client application for managing the IdentityServer, including users).
AdminUser performs an action to "revoke" UserA
A call is made to the IdentityServer back-end from the admin tool where UserA has an "Enabled" property that is set to false.
At this point in the flow I want to kick the user out of ClientA from the back-end of the IdentityServer.
More context:
IdentityServer is using cookies in the client browser to keep the "session" (not sure if that is the right word cause there isn't actually any state being managed).
Also using cookies for remember-me.
Is there a way to remove the cookie for the IdentityServer from the back-end? Or notify the client that UserA should no longer have a valid authentication so that it can perform HttpContext.SignOutAsync()?
I was reviewing this link: https://docs.identityserver.io/en/latest/topics/signout.html for guidance but I am stuck on how to do this from the back-end as the AdminUser. Calling HttpContext.SignOutAsync() would sign out the AdminUser that made the request, not UserA that is causing havok in ClientA.
In a typical setup with identity server you have:
A JWT token with a short lifetime
A session cookie
The JWT token needs to be renewed frequently. The session cookie is used when there's no valid JWT. In this case the user will be redirected to the login page and if there's a session cookie the user will be automatically authenticated and redirected back to client app.
So you have some options for your logout:
Ensure the user cannot renew his JWT (= logout after a few minutes)
Ensure the user cannot login again
Really clear everything in the browser (and ensure he cannot login/renew again)
Back to your question
Is there a way to remove the cookie for the IdentityServer from the back-end?
The answer here is WebSockets which allows a two-way communication.
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API
A common library for C# is Signal/R
https://dotnet.microsoft.com/apps/aspnet/signalr
You would create a Hob on the server side that allows you to send messages to the "bad user".
https://learn.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-6.0
And listen for those messages in your client app:
https://learn.microsoft.com/en-us/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0
Please note: Whatever you do on the client side, the important part is typically to block the server requests. It's not secure to delete the cookie on the client. You have to delete the session on the server side instead.
Additional notes:
The flows in your setup may be different from what I described above.
I know, this is just a partial answer, but it's too much content for a comment ;-)

How to validate external IDP session after x minutes?

I'm working on a SaaS offering, and we are using IdentityServer 3 for authentication.
To support Single Sign On with external identity providers, we are using SAML2p with Sustainsys Saml2 Owin middleware, so that IdentityServer is the SP.
However, after signing in with the external IDP, we would like to validate the external identity periodically, or at least after some given time.
Say you have signed in using Active Directory Federation Services (ADFS), you are authenticated, and are working in the software. Then someone decide you are no longer a valid user in the organization (fired), and disable your user in their AD.
How long could you then still continue working in the software without being validated with the IDP/ADFS? The IdentityServer session is 60 min, but of course sliding. Will it slide forever? Is there a way to configure this?
There are methods in Idsrv where we could do some checkups, like in the IAuthenticationSessionValidator. Someone suggested to call userinfo endpoint, but not all IDPs are OpenID Connect compliant or have such endpoints.
I would like something generic, we don't control the external provider. And we plan to support WS-Fed and OpenID Connect also.
I found this question, but it didn't really have the answer I'm looking for:
SSO : Should SP validate session with IDP in every request
It would be great if there is a way to configure an interval or rule to redirect to the external IDP to validate the session? Redirecting on every request seems too much. (I don't even know how to do that)

Can a website authenticate against multiple ADFS servers?

We have an ASP.NET/MVC website that's using FormsAuthentication. As is usual, when the user tries to access a page, and doesn't have a valid FormsAuthentication cookie, IIS redirects him to the login view. When the user does a HttpPost to the login controller, our controller action makes a call to our WebApi webservice, which validates username, password, and customerid against a Sql Server database. If the authentication passes, the controller action sets a FormsAuthentication cookie, and redirects to the page the user had asked for.
Now sales is making noises about "Single Sign-On", though I'm not clear exactly what they mean by that. From what I've read, in the Microsoft World this usually means accessing MS's Active Directory Federation Services.
At this point I have almost no idea how this would work, but before I dig into this too deeply, would it be possible to put the authentication code within the WebApi webservice, where we could choose to validate against the Sql Server database, or against whichever ADFS server was appropriate for the specified customer?
Our problem is that we have I don't know how many thousands of users, working for some hundreds of customers. Many customers will not have ADFS running, and those who do will each have their own ADFS server.
Most of what I see with respect to Single Sign-On seems to involve doing browser redirection to the ADFS server, then redirection back, and looks to be avoiding login at all, if you're already logged in. I don't think we can do that, in our case. We can't know which ADFS server to redirect to, until we hit the database.
So, the question - is it possible to do ADFS authentication entirely from C# code in our WebAPI web service?
(One possible complication - the website itself has zero access to any database. The sole configuration setting in its web.config is the base URL of the webservice. Whatever authentication happens has to happen in the webservice, not in the website.)
First of all, "Single Sign-On" (SSO) is not limited to ADFS. It simply means that you type your credentials only once, and then all systems you access automatically "recognize" you; all subsequent authorizations request are transparent. For instance, if you have several web sites using Windows Authentication in your company Intranet (same AD domain), you have SSO: you authenticate once when you log in to your computer, and then your web browser authenticates automatically to these web sites using NTLM or Kerberos. No ADFS in this case.
What ADFS (and "Federation" more generally) allows, is SSO accross security boundaries. In Windows world, a security zone is typically created by an Active Directory forest; everything within this forest is accessible using SSO provided by Windows authentication. But as soon as you leave this zone (SaaS application, web site in another company network), you need another authentication protocol to perform SSO, and these protocols are implemented in ADFS.
Then about your particular problem:
What you could do is instead of using FormsAuth, you use AdfsAuth. When a unknown user accesses a page, he would be redirected to ADFS for authentication (using browser redirects as you correctly mention). To know which ADFS server should authenticate your user, you need a way to differentiate them indeed: a list of IP range per customer? a different URL per customer? If you don't have something like this, then the only way is to show them a list of choices such as: "I work for CompanyA", "I work for CompanyB", "I work for CompanyC", "I don't work for any of these companies and want to authenticate using FormsAuth."
In this case, what your WebApi web service has to do is: if I know which ADFS server to use, redirect the user there. Otherwise authenticate the user as usual using the database.
When you use AdfsAuth for a customer, your database is useless. You can delete all credentials related to this customer.
do ADFS authentication entirely from C# code in our WebAPI
Well it's possible to "re-implement" ADFS in your service, but you won't get SSO if you do that. When you use federation, your redirect the user to the ADFS server of his company. This ADFS server is in the same domain as his computer, so the user gets SSO here. Once again, your users can't get SSO if you authenticate them yourself, because your users are not in the same security zone as your site.
When authenticating to multiple identity providers, it is typical redirect to your own STS. So, in this case, you would have www.yourapp.com redirecting to sts.yourapp.com, which redirects to sts.somecustomer.com.
The specific tools to enable such a dataflow is the home realm parameter (whr), and the AD FS Powershell API (to allow IDP maintenance).
Your RP-STS acts as the trust-point for the app, and manages selection of the appropriate IDP. One RP-STS, many IP-STS's. Each of your Customer's IP-STS gets set up as a Claims Provider Trust in AD FS.
As always, Vittorio has already covered the subject better than I could.

Ping federate asp.net configuration saml sso

I have asp.net MVC application I want to make SSO windows authentication.
I use Ping Federate as the IdP and SP. When I enter the site it redirect to the SSO page after I enter my credentials it post the SAML to the SP and the SP redirect to the site.
The Problem
My app not recognize that the user is authenticated and redirect back to the SSO page that already authenticate the user to it again post the SAML to the SP and there is infinite loop.
What am I missing? Do I need to change something in my web.config file?
this is what I have in the web.config
<authentication mode="Windows">
</authentication>
<identity impersonate="true" />
Depending on which adapter types you are using for your SP side, I would recommend using the appropriate kit for it. Being the OpenToken kit, Agentless kit, etc.
I had the same problem before, so what you must do is finish the flow in your application and write a cookie on the response. This would depend on which adapter you are using, but the end is the same.
If you are using OpenToken Adapters you must be receiving an open token by either query string or form post. You must open that token with the OpenToken agent kit. Once you do that, you will find your "attributes" or "claims" inside, then you must write a cookie in the response, and use that cookie to have startup a session.
If you are using Agentless Adapters you will be receiving a REF id by either query string or form post. You must grab that REF id and call the Pickup Endpoint in PingFederate. That call will return the claims, then you must write a cookie once again and startup a session.
In the past, I coded an HTTPModule that would do this for me, and I repurposed the WS-Federation functionality to write my cookies. At the end, the site would be authenticating with Ping, but reading WIF cookies like a WS-Federation enabled app to keep the session going.
However, we ended up moving to OpenIdConnect/OAuth2, which is a newer standard and does not require SP adapters.
I have released a client for OWIN that would take care of everything for you as long as you have the OAuth2/OpenIdConnect module enabled in PingFederate.
Here is the link if you ever move.
https://www.nuget.org/packages/Owin.Security.Providers.PingFederate
You can give a try to asp.net saml sso connector. It supports multiple idps like ADFS, Azure AD, Bitium, Centrify, G Suite, JBoss Keycloak, Okta, OneLogin, Salesforce, AWS Cognito or even with your own custom identity provider. It really help me in my .net application for sso.

Single-sign-on: Which direction should I go?

I have a SaaS web application that caters to multiple education institutions. All clients are hosted in the same application/database. The application is currently written in C# for ASP.Net 4 Web Forms.
Currently my application uses a local/native database for user authentication/authorization.
Our clients are asking us to support single-sign-on where the client is the authentication provider and my application the consumer.
The problem is that the clients are asking for SSO via different protocols/mechanisms like Shibboleth and OpenID Connect. This means I need-to/should create a solution that works with all of these or that is at least extensible.
I came across Thinktecture's IdentityServer, which I think can abstract the various SSO mechanisms used by my clients and return to my app a claims based identity token that my app understands.
I'm struggling a lot with this concept though. Does this mean that my app redirects all authentication requests to the IdentityServer, lets IdentityServer handle the back and forth of say OpenID Connect, and then receives a token back from IdentityServer with the information I need about the user? How does the identity server know the realm of the user (i.e. so it knows which client auth provider to send the user to)? Does the IdentityServer need to validate the existence of the user in my app's local/native database? Can the IdentityServer handle both SSO and local logins?
Is a separate identity server the way to go? It seems like it would be, allowing my app to integrate with one point (the identity server). But, there's not a lot of documentation out there on Thinktecture's IdentityServer other than how to configure it. ADFS may provide a similar solution, but most examples out there speak to ADFS and Azure.
Lastly, I'm assuming that I'll still maintain local/native authorization data about each user as the 3rd party authentication provider can't possibly know the specific authorization needs of my application.
Any thoughts or suggestions out there?
Does this mean that my app redirects all authentication requests to the IdentityServer, lets IdentityServer handle the back and forth of say OpenID Connect, and then receives a token back from IdentityServer with the information I need about the user?
Basically YES. But it depends on how you set it up. Your page could call Authentication provider of the client if you have only one client or one authentication provider. Or you could set up your local IdentityServer (more extensible IMHO) and configure authentication provider of your client as another IdP (identity provider).
How does the identity server know the realm of the user (i.e. so it knows which client auth provider to send the user to)?
If you go with the second option then your app will redirect to IdentityServer and based on home realm it will be automatically redirected to IdP. If no home realm is specified by your application then IdentityServer will show all configured IdPs and user chooses what IdP to authenticate at.
Does the IdentityServer need to validate the existence of the user in my app's local/native database?
It depends on you. If you wish to verify the existence of the user in your local database then you may do so by extending IdentityServer.
Can the IdentityServer handle both SSO and local logins?
Yes, it can.
Is a separate identity server the way to go? It seems like it would be, allowing my app to integrate with one point (the identity server).
You can always use IdentityServer and integrate it in your local application. Or you can use Shiboleth as your local authentication provider. Both are implementing standards like WS-Federation, WS-Trust or OpenId and both are open source so you can extend/modify it to your liking.
But, there's not a lot of documentation out there on Thinktecture's IdentityServer other than how to configure it.
I can't really say how much documentation is there. But if you wish, NDC Oslo 2014 will feature 2 days of Pre-Conference Workshops where Dominick Baier and Brock Allen (authors of IdentityServer) will teach you everything you want to know.

Categories

Resources