SSO - Share single User table between several websites or somehow keep multiple User tables in sync? - asp.net

I'm working on a single sign-on solution for two ASP.NET MVC3 websites. The sites are on separate subdomains. I'm using Forms Authentication and so far I everything is working well. When I sign into a.example.com I'm automatically signed in to b.example.com too. Nice.
Each application has its own database.
My question is this - if I want to keep certain user information in sync between the two sites (say the last activity date or some user preference) then should I have a User table in both databases and somehow keep them in sync or should only a.example.com's database have a User table and b.example.com somehow reads and writes to it?
Thanks for your advice.
Edit: Thanks to adam I'm leaning towards storing all user data in a separate database. I will pass the authenticated user's username and ID to each application in the authentication cookie. Can anybody offer any advice around maintaining referential integrity between the two databases?

Most SSO solutions I've seen have a central accounts portal where users can maintain settings, change email address etc.
Think Google:
google.com/reader
google.com/analytics
google.com/accounts
This represents a single user store, providing authentication to several sites. This has various benefits, such as a single place to store session hashes and other security details (for preventing things like man-in-the-middle attacks).
In a true SSO, an authentication request redirects to the central auth system (ie google.com/accounts), authenticates and then redirects to the service that requested authentication.
From your description, it sounds like you have separate authentication for each site/service, but the user db is shared.

Related

Retrieving all users and roles in a .NET Web Application through ADFS

We have a hosted .NET web application (Windows Server 2012 R2 environment) and we need to provide Single sign-on (SSO) to users from a corporate LAN environment. We have used ADFS to enable SSO and it is working as expected thus when a user hits our web application login page URL he is authenticated against ADFS and is automatically logged in to the application.
We have an additional requirement where we need to obtain a list of all users, their groups, email addresses some additional information periodically from their Active Directory so that this information can be bulk loaded into our web application however since ADFS is implemented we do not have direct access to the Active Directory.
Is it possible to connect to ADFS and obtain a list of all users, their email addresses etc. programmatically?
If the above is not possible then what is the recommended approach for this kind of a setup?
Thank you.
No, this is not possible. There is no such API because with SAML and WS-Federation, users can come from anywhere. This does not have to be AD, technically it's possible create a "Log in with Facebook" implementation.
What would you need the information for? The user's claims contain all information which you might need (user name, e-mail address, group memberships).
If you really need that information about all users in your application, perhaps ADFS is not the solution you are looking for.
As Alex mentioned above - the way it works, ADFS does not provide any way of importing data from the AD or other trust stores. It just gives you the information that are carried over with the token.
In case you need more information, you should extend the number of claims being issued by ADFS. You can then collect the information - when the user comes for the first time, use the data from the token and fill the profile. If it is returning user - update the information if necessary.
The other solution (but I wouldn't say it's recommended - rather a workaround) would be to implement custom solution for importing information from AD to your application. I'd say it's fair as long as you use your local AD for reading this data. In the moment you decide to extend the access to third party (e.g. partner company), which might be using different identity provider, which doesn't have to be backed by Active Directory any more - you find yourself in tough spot.

Multiple site domains and virtual directory single login

I am creating a project which has a login portal with multiple applications and websites. I want to allow the user to login and then click any application and have access to it. Some considerations are: each application is defined in a user profile, ie which users can see what. also each application privileges are different for each user. so user a may be an administrator of application a but just a normal users in application b.
What i know.
I can have one auth cookie created in the main portal which with setting the machine key and same authcookie name, each application can use it. I have done a test with this and it seems to work.
My problem
As each site/ virtual directory has different privileges per user and per application when the user access a site i need to get his privileges from the databases but I cant then overwrite the auth cookie userdata with the new details because he may have multiple tabs etc open at a time on different sites. So how can i have an extra cookie store per user and per application for holding application specific details. I know I could go to the database each time but that's allot of overhead for each post back.
Maybe another option is to use the main authcooke for checking the user is logged in then have a new auth cookie per aplication and user, but how can i have 2 authcookies, that may get confusing and the second needs to timeout when the main one does et c i think
Any help suggestions would be gratefully appreciated
THanks
------------------- EDIT -----------------------------
we have one user table for all all sites not 1 per each site. then we map the user to an application and then the user application and role. so when you get to an application it has to check if the user has access and what there role is. all other user details are already in the auth cookie when loggedinto the main site. We do it this way because we have to manage users in one application not each application. Hope this helps understand my requirements.
What you are describing is a 'classic' SSO (single sign-on) example. There are lots of ways people have tried this and they are well documented on Google.
One way to do this is to have your SSO server (e.g. the first place you land and log in) to issue a security 'token' (e.g. a Guid) and then either store this in a cookie or append to URLs. Each subsequent call to an application can look-up the token in a database, verify it's validity and carry on (or boot the user out if invalid).
Using a database also allows you to set a timeout for all applications for which the token is valid.
This can then be extended to allow the database to store which apps each user can access etc. I've described this in very broad terms but it may be a good starting point.
Hope this helps
BTW: querying the database on each request isn't too much of an overhead. I have applications that do just that and are still performant when loaded with 300+ users.

Best way to log users programmatically into a 3rd party website (when OAuth is unavailable)?

I'm working on an asp.net website that needs to store user passwords for another website so that I can retrieve data periodically without requiring the user to keep logging in. I can't imagine how one-way hashes would work in this case since the user isn't going to be re-keying the password every time. I'm assuming I need to encrypt the passwords to store in a SQL Server database and decrypt them when needed. But that's where things get tough for me. The basic infrastructure is a C#/Asp.Net MVC3 website running on load-balanced Azure compute instances and storing data in SQL Azure. I'm not a crypto guy, and I don't want to make a rookie mistake. There seems to be a lot of information out there, but nothing seems clear to me. Even though the data I'm connecting to isn't sensitive, I want to treat my users' information with the same care I want my personal data treated. Any advice on how to proceed would be appreciated.
EDIT:
I certainly understand that storing passwords is not a best practice, but in some cases it is simply unavoidable. I have come across this project, but have not tried it yet: http://securentity.codeplex.com/. It uses a digital certificate on the web server.
Users of the 3rd party site are able to set their data as "public", in which case I wouldn't need to store their password. So I may give users the option of doing that instead.
You should have a look at OAuth and Single Sign-On.
In simple terms: Only an authentication token is sent between the different systems.
You (the site) should never have knowledge about the users passwords. At most you should know the hash of the passwords to your site.
Read the two topics above and you will know how to properly secure your and the "neighbour" site.
Edit
In Short:
The other site (site B) implements OAuth server processes. Your site (site A) implements OAuth client authentication. When requesting user information from site B you redirect the user to site B authentication to allow site A to read information from site B regarding the user. Site B creates a token that site A can use to access the information. This token can be time limited (or not).

Creating a Forms Authentication cookie for a search engine crawler

Big picture: I have been asked to create a search engine for our company's intranet. Such a search engine will crawl pages supplied to it by XML files for each independent application on the intranet. Problem is, the entire intranet is using Forms Authentication, and so the crawler will have to have access to each application without actually having user credentials (e.g. username and password).
Each application within the intranet has its access controlled by a permission manager, which is essentially a wrapper on the default Role Manager ASP.NET comes with. Each application can define its own roles and assign people who have those roles.
Please note that there are potentially hundreds of applications.
The crawler has access to the permission manager's database, so it knows what all the roles are. Therefore my idea was to have the crawler create a cookie that identifies it as having all roles for each application.
The problem I'm running into is this: how do I create a forms authentication cookie which already has the roles assigned in it without creating a corresponding user (IPrincipal).
It is entirely possible that I've failed to completely understand how Forms Authentication works, and if so, please tell me what I can do differently.
This is probably not what you want to hear, but...
I would just have the crawler authenticate like anyone else.
Given that this is a crawler you control, why fight Forms Authentication? Seems logical to create a user with all required roles in each application (hopefully you have a central administration point for the hundreds of apps, else I would not want to be an administrator there ;-)
If you do anything that allows "just the crawler" special access (bypass user-based authentication based on... what? The crawler's user agent? A specific origin IP?), you create a security hole that a hacker can leverage to gain access to all of the intranet applications that have otherwise been diligently secured with user IDs, passwords and roles (in fact, the security hole is particularly wide because you propose granting access to EVERY role in the system).
It sounds like what you want is an appropriately encrypted System.Web.Security.FormsAuthenticationTicket (which then gets attached to HTTP requests as a cookie).
The encryption logic is located in System.Web.Security.FormsAuthentication.Encrypt(), which I think uses the MachineKey as the encryption key. Also have a look at the GetAuthCookie() logic (using Reflector).
You might have to write your own version of the encryption method, but what you want to do should be possible, provided you have a copy of the remote site's encryption keys. You don't need the user's passwords -- only the user name is encoded into the Ticket.
It seems to me that the problem is not yet well defined, (at least to me!).
Why do you need to crawl the pages and index them if there are fine grained permissions on them?! How do you show search results without violating the permissions? Why not index the back end by passing the pages altogether (I mean index the database records not the pages)....

Keep User logged in across multiple applications on multiple servers

I am building a suite of applications using ASP.NET.
Each application can be hosted on separate servers.
All the applications share an integrated database.
All applications require user authentication before use.
I want to build the ability to transfer users from one application to another without having to relogin.
Is there a way to recognize that a user is logged in one application and allow quick navigation to another application on a different server?
Currently I am storing the password hashes in the database; but I wouldn't be opposed to other suggestions if they solve the problem.
Here is what I have done in the past.
Each application must share a forms authentication ticket. To do this the forms authentication cookie name must have the same name, the machineKeys must be the same, and the protection mode must be the same.
This works across domains, but does not work across IPs. What I do to get around this is to serialize the ticket info and store it in the database with the session id as the key. If a user is not authenticated the server will look for the session id in the database and rebuild the FA ticket if found.

Resources