ASP.Net Application Context Data Sharing - asp.net

I have several websites that use a HTTPModule (wrapped in a dll) to authenticate users and store an authentication object in the application cache for ~10 hours. I then set a cookie containing the cache key on the users machine.
I'm now looking for a way to allow admins to clear a specific cache object for all websites for any given user (effectively logging them out) causing them to automatically log back in (via windows authentication) next time they visit any of the sites.
I was planning to have a single administration website with the facility to reset logins - but I can't change the application cache for other websites for obvious security reasons.
Is there any way of passing a signal to those sites that use the authentication module so that they can clear their own application cache?
Note: I have read up on memcached but I would like to avoid a solution that isn't 'Standard ASP.NET' if possible.

Here are two ideas:
If they are on the same server, you could have a file containing the active logins in the file system, that all projects can access.
Add a generic handler to each project, that resets the login of a given user. Call this from another project when he gets logged out there. You could add a passphrase for security reasons.
EDIT: I just thought of a better solution:
Create a central "authentication" project that keeps track of the login status. Call it from the websites (e.g. through generic handlers, webservice, ...) to log out a user or check his status.

I've opted to piggyback code onto the existing HTTPModule.
I check for a custom user-agent string, if it exists I clear the relevant cache entries based on a query string and return a custom HTTP header upon success.
The only extra overhead is checking the user-agent for each request which I can live with.
With this setup I can now use a WebRequest object (injecting my custom user-agent string) from my central site to send messages to all sites using the module.

Related

How are user logins from a desktop application usually handled?

What is the common(best practice) way of allowing a user to sign in from a Windows desktop application. Some examples of what I mean are Dropbox or Google Picasa. You sign in with your credentials and then the software is permanently signed in.
I assume the communication takes place over HTTPS. Does the client store the credentials to be sent with requests or is there some sort of token generated? Can anyone point me to some resources on how this should be handled?
Logging into a website normally creates a session at the server. The server then has to identify subsequent requests by the session. Typically, there is one of the following two solutions applied:
Session cookie, storing a session identifier
URL rewriting, where the session identifier is appended to every link in the html source
Which approach is taken is site dependent, so if you are writing a general 'for all sites' client, you might have to implement both.
In the former case, your application will have to handle the session cookies, in the second case, your application has either nothing to do - if it caches the html response - or will have to emulate the url rewriting itself.
In both cases be aware that the session will expire at server side after a certain period without any activity, so you might be required to generate such.

Sharing ASP.NET_SessionId and .ASPXAUTH cookie security risk

We're developing a SAAS solution for a big company in which doctors can view patients and make mutations, order products, provide licenses.
This project is for 4 separate companies under one umbrella company. For each company we developed a portal. All portals use the same code but have a strict separated database because the database contains all the patient information.
We're using Sitecore as CMS.
The client decided to use virtual folders instead of subdomains for the production environment. Our staging evironment url is for example: acc-portal1.umbrella.com. For the production environment they would like a URL such as: acc.umbrella.com/portal1. One SSL certificate is being used for all portals and requests.
We're using Membership Provider (forms authentication) for the authentication of users. Users can not log in with the same account in for example portal1 and portal3 because of the usage of separated databases.
Because we're using formsauthentication the ".ASPXAUTH" cookie is being used. Of course the "ASP.NET_SessionId" cookie is used also.
Because the client wants to use virtual folders instead of subdomains, the cookies are shared over all portals. It is possible to set the "path" on the node in web.config but this path is dynamically read by Sitecore and resolved in a pipeline. I did not find a way to override this path after it is being loaded in the web.config. Also I did not find a way to alter the ASP.NET_SessionId cookie path.
My question is: is it a (security) risk to share these cookies over multiple portals (remember, they should be separated completely)? Are there any other problems this setup could cause?
Hope somebody can help!
Yes, there is a huge security risk. What you do is called a multitenant application. You have to take special steps to ensure that cookies and other sensitive data cannot be shared.
My advice would be to store the tenant name (portal1) in the custom data section of the forms authentication cookie. You set the custom data when you issue the forms cookie.
Then, have a custom module or just a handler of the Application_AuthorizeRequest event, where the identity is already established based on the cookie.
In your handler, you decrypt the forms authentication ticket from the cookie, retrieve the user data and compare to the actual url. If there is a match - nothing happens. If there is no match, it means that user is authenticated in one portal but tries to access another. You can gently clear the response and render a message "well, this portal is not meant for you" or just log the user out.

Creating a cookie using ASP.net

I have a sharepoint webpart where I have links to go to different web sites to which login is required. Therefore, I think i need to log the users on before redirect them into deep pages in that site, therefore I think i need to set up a cookie to that web site when the web part is loaded (by using the user credentials of the user's active directory information).
How can I achieve this requirement with out opening up a new browser window? (Though I have used a client side script, it pops up a new browser window)
Any help is highly appreciable...
Thanks
If you are referring to "different web sites" as sites having completely different URL's, then it's probably not possible without SSO system.
The reason is that it's impossible to read/write cookies from other domain in web environment, i.e. pre-login the users like you are saying.
If all the sites are inside same domain, like mycompany.com for example, and different sites are in abc.mycompany.com or mycompany.com/subsite, then yes, you can set the cookie. See top section here http://www.15seconds.com/issue/971108.htm
A simple way to implement SSO is by implementing method described later on in same article.
in the "Requesting Cookie from Another Domain". This is not a very secure method though, but can be done if you restrict it properly to specific slave domains. And obviously all the slave sites have to be modified, as with any SSO implementation.

ASP.NET Application to authenticate to Active Directory or SQL via Windows Authentication or Forms Authentication

I am in the process of writing an application that will need multiple forms of authentication.
The application will need to support authentication to Active Directory, but be able to fail back to a SQL Membership Provider if the user is not in Active Directory. We can handle the failing to the SQL Provider in code based on the username provided because the username will be a different format than the Active Directory username.
Is this even possible? What I mean is, can I use membership and use both ActiveDirectoryMembershipProvider and SqlMembershipProvider together or will I have to roll my own?
Another additional added complexity is that I would like to automatically authenticate my internal users based of Windows Authentication back to AD, but use Forms Authentication for users not on our internal network, or users that are using the SQL Provider.
These will most likely be separate servers, one internal, and the other external so I have a lot of planning to do to figure out the data replication, and how I will authenticate the AD users if they hit the outside server etc.
I am wondering what thoughts are out there as I start down this road. Is what I am wanting to do even possible without me rolling my own, or is there a way to mesh these together?
Thanks for the reply.
The reason I asked originally was because I was able to get this specific senerio working about 7 years ago using IIS to authenticate and then passing back the credentials to a Lotus Domino Server Web App. If the user was not authenticated via the Windows Authentication/ISS then Domino would handle the authentication. This was what I was looking to do here, but really couldn't think of a way to make it work in IIS.
As for the rest of your reply, I think you are on to the way that I will need to take. I have thought this through and tossed it around in my head a lot. The application will be somewhat different on the two servers anyway since there is going to be limited access to the data on the external server anyway. The fact that so much is going to be different already I may just treat these as two applications, thus negating the need to use two types of authentication in the same application anyway.
I am playing around with the idea already of writing my own authentication/login window for the external server, and if the user trys to log in with their AD credentials on the external server I will be able to detect that and redirect them to the internal server. If they are not on the local network or VPN'd in they will simply not get access. This part still has some thought process to go though so I am not sure.
As an additional thought - is there a way to pull just enough of AD into a SQL database to allow me to authenticate users to the SQL database from the external server using their AD credentials, without creating any security issues? I hope I am clearly typing what I am thinking....
Thanks again!
Tim
This is the way I've handled a similar situation based on this info:
Configured the application to use Forms authentication.
Set the LoginUrl to a page called WinLogin.aspx.
In WinLogin.aspx, use Request.ServerVariables["LOGON_USER"] to get the username then call FormsAuthentication.RedirectFromLoginPage( authorizedUserName, false ) to log them in. I guess you can manually check Active Directory as this point as well.
Create an html page that redirects to a page called Login.aspx
Login.aspx is your standard username/password login.
In IIS, Enable Integrated Authentication and Anonymous on the entire site, but deny anonymous access to WinLogin.aspx.
In IIS, set your 401 errors to the page created in step 3.
What basically happens is that when an unauthenicated user hits the site, they're redirected to WinLogin.aspx. Since anonymous is turned off, integrated security makes a check. If that passes, your custom code in WinLogin can run. If the integrated security check fails, a 401 error occurs. Your custom 401 page redirects to Login.aspx where the user can log in using their username and password with the SQL provider.
As far as I know, Web Applications are configured to use either Windows Authentication or Forms Authentication, but not both. Therefore, I do not believe it is possible to automatically authenticate internal users while requiring others to enter a username / password.
You could authenticate to Active Directory or a SQL user store via Forms authentication by using a custom provider. However, the AD users would still need to enter their username and password. Although I've never combined these two methods, I have used Forms authentication to authenticate against both sources at one time or another.
With that said, I think you may want to consider reducing the "flexibility" of your system. If you have an external facing server and an internal facing server, you could simply change the provider configuration on each copy of the application to go against a different source. Then, you could configure the internal one to use Windows (automatic) authentication and the external one to use Forms authentication.
IMHO, I believe that internal users should not be using the external server to access the application. If they are, they should have a user account stored in SQL, completely separated from their AD account. Basically, when someone accesses the application externally, they are acting as an external user, irregardless of their physical location.
Well, it is possible to use ActiveDirectoryMembershipProvider and SqlMembershipProvider, but this requires you design your log on page with your own code instead of the Login controls.
About the mix authentication (Windows and Forms), as far as I know only IIS 7 makes it easy and clean. See this post for details,
http://mvolo.com/blogs/serverside/archive/2008/02/11/IIS-7.0-Two_2D00_Level-Authentication-with-Forms-Authentication-and-Windows-Authentication.aspx

redirect to another URL issue in ASP.Net

I have two web applications and sometimes I need user to jump from one application to another. Since they are two web applications and may reside on different domains/machines, I can not share session between them.
The technical challenge for me is how to pass session information (I only need to pass userID string information in the session) from one source application to another destination application -- so that the user feels Single Sign On and personal information is displayed for him/her in both application (as the userID is passed to the destination application, no re-login is needed).
My current solution is generate all URL strings in both application and append them with user ID after user logins successfully, like http://www.anotherapplication.com/somepage?userID=someuserID, the userID value is retrieved from session. But I think my solution is stupid and I want to find some way to automatically append the query string ?userID=someuserID when the user jumps to another URL in another application -- so that I just need to generate the common unified URL http://www.anotherapplication.com/somepage in both application.
Is there a solution to automatically append the userID query string?
thanks in advance,
George
Rather than doing it via the Querystring, it might be more maintainable in the long run if you use create a FormsAuthenticationTicket with the required values.
I especially recommend reading Michael Morozov's excellent article on the subject of SSO (Single sign ons).
I do not think it is a good idea to have the user id in query string.
A better idea would be to implement a single-sign on solution. In your scenario, you could do the following:
Whenever one of your applications receive an unauthenticated request, redirect the user back to the other application to a special single-sign-on url.
This page checks whether the user is logged in, and if so, redirects back with an authentication token in querystring.
This token is checked by the un-authenticated application; and if it passes, you can login the user.
Of course, this seems like "a lot" of redirecting, but it should be reliable, and it only happens once, and then your user will be authenticated on both applications.
Obviously you would need to implement a security scheme so that you can check that the authentication token you get passed is really valid and originating from your other application. You could do this with a challenge-response algorithm; which could be:
Both applications should know a common key.
First application sends some random data (the "challenge") to the second application.
The second application includes a hash-value of the random data + it's answer + the secret key in its response.
Now the first application can check that the second application knew the secret key by calculating the same hash-value.
Have a look at:
http://en.wikipedia.org/wiki/Challenge-response_authentication
EDIT:
With regards to session state, see http://msdn.microsoft.com/en-us/library/ms178581.aspx for an overview. It is possible to share session state between the applications, but I would not recommend it in general. If your application resides on different domains (URLs) you would have to use cookieless session state; which is not safe. If you decide to go this way, you would either have to use State server or SQL Server for session persistence, depending on your setup.
You can persist the session using something else than InProc (which is short for in process). If you persist the session using a SQL Server backend you'll be able to retrive the session cross domain/machine if they are setup to use the same SQL Server backend for session storage. This is configurable in ASP.NET and support out-of-the-box. I suggest you look it up.

Resources