Conceptual View of Single Sign On - c#

I'd like to create a single sign on for multiple websites (sitea.com, siteb.com, sitec.com). All sites are with the same company. Any database is also with the same company/location. Some are asp.net web apps and some are forums. I'd like to try and abstract away the SSO so it is not tangled up with any one site. I've outlined my approach below:
user signs into sitea.com, which authenticates user. A sessionid is created by sitea.com.
a cookie is placed on the user's machine with username and sessionid. The sessionid is inserted into the database centralAuthDB, which all sites have access to.
user clicks a link in sitea.com that does SSO to siteb.com (forum).
siteb.com retrieves username and sessionid from the cookie. siteb.com then checks these credentials against centralAuthDB.
A match is made with centralAuthDB and the SSO is authenticated. However, the forum (siteb.com) also has its own database of users. The username is checked in this database as well and now the user is seamlessly logged into the forum.
Is the above secure and practical?
Should credentials be send to centralAuthDB via webservice?
Will the cookie need some generic name? Then the values for username and sessionid are placed in this cookie?

With any SSO, you're going to need a service that takes a credential and generates a secure authentication token. The token must be encrypted so that it cannot be forged; only the authenticating service would be able to decrypt it to check for validity. Then, that token can be passed around to whatever you wish--in a query string, most likely. Cookies are ruled out because they are inaccessible across host names.
As mentioned in the comments on your question, it's wise to investigate pre-existing solutions to this problem. Way smarter guys than you or I have spent thousands of man-hours hashing out all the problems with such systems.
My own personal choice would be OAuth as it's the implementation I'm most familiar with. You might also want to check out how Facebook does authentication for ideas on what, exactly, the token could contain.

Related

Allow supporter to sign in as another user

We currently have an Identity server 4 application. Using entity framework core and asp .net identity.
We have a group of supporters who need to be able to access our users accounts in order to help them with issues over the phone. Our users are not able to figure out how to use team viewer. As most of them are mobile and will only have a cellphone at the time.
I know all the security ramifications of allowing other people to sign into your account however there is really no way around this. Our customers have accepted that our supporters can connect to their account when they request it. We trust that our supporters only do this when its requested.
Current solution and its issues
The current hack creates an api endpoint which only our supporters can use as it has been locked down so that only those with supporter permission can use it. They send the users email and we hack create them an access token which is then used by the application (Web version) to act like its the user who is having issues.
This solution was created by my predecessor basically by taking the supporters access token and replacing all of the claims with this supporters id to the users id and returning it to the application. I hate this solution on a number of levels and its very unstable every time i look at this method it breaks. currently its not working because audience clams are incorrect for some reason.
What i want to do
I would really like to do this in a less hack way. So is there a way to sign in a user to the application without it actually being them thats doing the signing in and return an access token?
I have tried doing
await _signInManager.SignInAsync(user, false, null);
But i cant seam to figure out how to get that to return an access token.
What i would really like to do is have the ability for supporters to login to any ones account but do it securely somehow.
The problem with the user account is that it's not bound to one application. So by allowing others to login using the account, you give them also access to other applications. As a workaround you could use 'public' accounts, like engineer_01, engineer_02, etc.
But, this may not be necessary at all. What you really want IMO is to impersonate the user, instead of 'hacking' the account.
One way to do this, is to extend IdentityServer with a custom grant type using extension grants.
How this could work:
A signed-in user, who is allowed to impersonate users for the particular client/resource, requests an access token at the new impersonation endpoint.
The user sends the sub from the user to impersonate to the endpoint, where the user and (combination of ) sub are verified.
When access is granted a new (short-lived) access token is returned which can be used to impersonate the user, without having to know the credentials of the user.
The access token should contain information of the endpoint so it can be determined whether the user is impersonated.
We implemented an impersonation feature that is integrated into the browser-based sign in flow. If a user with permission chooses to sign in as another user then we add additional claims to their IDS4 authentication cookie which then supports issuing extra claims in the resulting token that reflect that it's an impersonation session and who the original actor is.
Navigate to client application
Sign in using whatever credentials
Check if any impersonation permissions exist (how these are defined is entirely up to you)
Prompt for impersonation account selection (or just continue as self)
Sign in as the selected account (with record of original actor)
Redirect to authorize endpoint
Issue tokens and redirect back to client application

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.

Implementing Single sign on in asp.net and C#

Currently I have a code modules which contains code necessary to authenticate user credentials and it includes AD users validation also. now I have a requirement to auto logging in without prompting the user to enter username and password if the user browses the application from company's network domain.
Can it be done via Single Sign on?if so how to implement it?
I believe the easiest way would be to use Integrated Windows Auth and ensure your computers are connected to the domain, and then the computers are set to have your host in the "Intranet" zone in IE, therefore your credentials would be passed. If this isn't an option perhaps take a look at ADFS or OAuth where you can implement SSO across many sites using Cookies, Tokens, Claims, headers, etc.
Thanks!
http://technet.microsoft.com/en-us/library/cc754628(v=ws.10).aspx
yes, you can implement sso via cookie, if you have cross domain request in iframe in IE browser, please remember to add P3P in http response header when set cookie

Providing SSO support for 3rd party systems in our application without another sign in page

We have an application which we need to allow users from our customer's systems to be able to sign in without seeing another log in screen.
What is the best way to provide an SSO type experience for our customers? I have tried to research Azure ACS and Windows Identity Framework but they all seem to be based on this idea of a common log in popup/screen which all sites use. Unless there is another aspect to this federated identity system I don't think that will work for us. Basically our customers are education institution which have students who sign in and use their own web applications/portals. These customers purchase access to our application and want their students to be able to click a link from their portal and automatically sign into our system.
From looking around it seems important to know that these systems are running on completely separate domains. For some legacy systems we have asked our customer to provide simple api endpoints for a very custom sso implementation. What I'm looking for is any information about a more standard approach for SSO.
SAML 2.0 is the standard for single-signon. Your clients would need to have some authentication mechanism on their sites that can be translated into a SAML call to your application.
When they sign the student on, they should make a quick call to your application, passing you the username of whoever is logged in. In return, you generate a token, store it in a DB along with the username, and send them the token. They append that token to any link to your app in GET form, and it "uses up" the token (removes it from the DB) but signs them in to that account.
Upon generating the token, you can also remove one "credit" from that applications allowed requests, or whatever else you want to do there.
Our specific needs required us to roll our own SSO type system using some simple secret token handshakes.

Facebook authentication and Asp.Net Membership

I'm trying to integrate facebook authentication with an asp.net site.
So if a user decides to register at the site they can do so by using their facebook credentials.
I'm currently at the point where I have the facebook access token and the user details and not sure how I should go from here.
The site uses asp.net membership authorization.
This is what I believe should happen in case a new user decides to register: (But not sure if this the the way to go)
0) User visits the site and decides to register using their facebook credentials.
1) The user providers their credentials and I receive an access token and their user information.
2) I store this information in my database and create an asp.net membership user with the data I received. (At this point I'd have to generate a password).
3) Log the user into the site so he can navigate freely.
I would appreciate some advice if I'm on the correct path and how I should go about generating the password. (I'm thinking in maybe combining the email and facebook userId, retrieve a hash and store.)
Thanks
UPDATE 1
I found this SO question where they suggest to use:
http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.setauthcookie(v=VS.90).aspx
I think you approach is sound; what you effectively do is to replace the username/password authentication with the received facebook id, and let that id pass as a valid identifier in you application.
You say that you will need to generate a password in you application which I am note entirely sure about. It is true that you will need to create your user with a password as far as the membership provider in ASP.NET is concerned, but you could choose to fill in a random string if you only want the users to login using facebook connections.
Deciding which facebook attribute to bind to is also worth a bit of concideration. The natural choice is of course the facebook identifier since that is unqiue to the user, but if you choose to allow other authentication mechanisms later on - google open id for one - you might also benefit from storing the email from facebook etc.
Probably it will also be a good idea to auto generate a user name in you application that is not defined by facebook. If you choose the facebook identifier as login name you have a hard dependency on facebook making the introduction of new identity providers hard. If you choose a random identifier and an associative table establishing the connection between the facebook id and your id, you will also gain some flexibility later on. Choosing the somewhat more limiting email address might be a better choice if you want to have meaningful output from ASP.NET Login-controls like LoginStatus etc.
I haven't read the response below/above so this may have been covered but be warned that I ran into a serious problem with cookies not being set from within an iframe in IE. It was a bloody nightmare. I'm not sure if this has been fixed, if its fixable, but just be conscious of my experience and test thoroughly in all browsers.
Also checkout the .net open auth project. I haven't used it personally but it supposedly supports OAuth as well as OpenId & ICards, which could be helpful later on for additional integration points.

Categories

Resources