Is it possible to enable ServiceStack auth across a webfarm without a shared session state storage? - asp.net

With ASP.NET Forms Authentication, its possible to setup all the servers in a webfarm to share the same machine key for encryption of authentication tickets, meaning if you can get by without requiring session state in your application scale out to a web farm is easy.
i.e., http://www.iambacon.co.uk/blog/getting-asp-net-authentication-to-work-on-a-web-farm
Is there a method to do accomplish this disconnected setup using ServiceStack Authentication, or does implementation require a shared session state to be persisted somewhere accessible by all web servers? I'm assuming shared state is required, but if there's a way around it, would interested to learn more... (we load-balance globally, so shared state is a bit more of a challenge)

ServiceStack Sessions are essentially the User Session DTO's serialized in the registered Caching providers. All Caching providers except for MemoryCacheClient persists to a distributed data store so they're naturally load balanced by just using the same configuration.
The Auth Providers that implement IAuthWithRequest can authenticate on-the-fly and access protected services without prior authentication, namely:
BasicAuthProvider
DigestAuthProvider
AspNetWindowsAuthProvider
But overall this would be worse performance since it has to authenticate on each request instead of a single cache hit to access the users session.

Related

When to use Azure Cache Service for Session in ASP.NET (MVC)

I read that when using Session objects in an ASP.NET web app hosted in Azure, if the request is handled by a different (virtual) machine, the app cannot see Session variables of another virtual machine (obviously), so it is recommended to use Azure Caching Service.
Just to understand:
can these 'virtual machine switches' happen in 'normal' web sites too?
I mean: if I don't configure redundancy (i.e. multiple instances) do I have the risk to 'not see' session variables just the same?
Thanks in advance.
AB
If you are using Azure Web Sites with a single instance, then you can technically use in-process session storage since all requests are handled by the same instance. Even when using multiple instances in Azure Web Sites, the default behaviour is to use ARR with "sticky" load-balancing, so that all requests for a particular client are routed to the same instance.
However, there are still times when all in-process session data may be lost. If an instance fails, then the site will be quickly transferred to another instance, and any in-memory (or on-disk) data will be lost. For that reason it is better to use some form of separate, persistent storage such as caching, table storage or a SQL database for your session data if it is in any way essential. I believe all the ASP.NET session providers maintain an in-process cache of the underlying store for performance reasons anyway.
If you are using a Cloud Service to run your site, then all requests are load-balanced between all available instances, so separate session storage is essential.

Session Authentication equivalent to FormsAuthentication?

I'm using a login form to authenticate users.
FormsAuthentication is right out as it stores sensitive user/role membership in either client-side in a cookie or within the URL. Within the URL is a huge security risk, so I won't even get into that. With the
FormsAuthentication cookie, this creates problems with a) security where the client is in the position of dictating it's own roles; and b) way too much data stored in cookies. Since I'm gaining nothing through security and loosing out big time on the size of user data storage, I'd rather just work with Sessions.
I'd like to reuse something like FormsAuthentication for all its basic login form-handling features. But i would rather have it store user data server-side in perhaps Session rather than client-side all stuffed into a single cookie. I'd rather just authenticate against a Session token of some sort.
I have no database and local disk storage of user data is forbidden. I rely on a 3rd party authentication service provider, and a requirement is that I must reduce chatter with this service. Thus, sessions for temporary storage of user info. Sucks, but that's not necessarily the problem I'm asking about. Also, a requirement is that I must set/use HttpContext.user and likely Thread.CurrentPrincipal for use later on in such things as AuthorizeAttribute, for displaying user info in views, etc.
So FormsAuthentication stores all user data client-side in a cookie. Whereas Session stores all data server-side and just relies on a simple client-side token cookie. However, Session is not available anywhere during the asp.net startup and authentication steps. Is there an equivalent forms "membership" provider that stores all data in Session server-side instead of client-side?
If there is no Session equivalent...
Where do I set HttpContext.user and Thread.CurrentPrincipal to make both values available throughout the rest of both MVC apps without interfering or messing up other MVC components?
Hinging on #1, is Session available at that entry point? If not, how do I make it available so I can create the Principle/Identity object using the data stored in Session?
This can't possibly be a unique requirement. Are there libraries already available which handle this?
Session stores information in a client-side cookie too! (or in the URL if cookieless).
If you want to authenticate a client, he'll have to provide some kind of credentials - usually an encrypted token in a cookie once he has logged on. If not a cookie, then what do you propose?
You should use FormsAuthentication. The sensitive information stored in a client-side cookie is encrypted using a key that should only be known to the web server. "the encryption methods being public knowledge" doesn't mean that you can decrypt the data without access to the appropriate cryptographic key.
You mention "roles" and a "third-party authentication provider". If your third party is also providing roles (i.e. an "authorization provider" as well as an "authentication provider"), then it would be reasonable to cache roles obtained from the provider on the server. Session is not available when a request is being authorized, so the best solution is to use the Cache (System.Web.Caching.Cache).
Personally I would encapsulate this in a custom RoleProvider. The custom RoleProvider would implement GetRolesForUser by getting roles from the third party on the first call, then caching them in Cache.
Not sure if I like what I'm about to suggest, but you could do the following:
Leverage the Application State or System.Cache as a global storage for user credentials.
Use an InMemory database (like RavenDb) which can also have encryption (in memory, I believe).
Using the Application state as a place to storage relatively common / frequent stuff I think is not a great place because of
Scaling / locking issues? <-- just a gut feeling.
Permenant data? so you have users in the website's memory .. then the website crashes or recycles, etc... what happens now to that data?
RavenDb is awesomeballs - go.use.it.now.
I understand that you are not storing anything locally, so whenever a user hits your system, you need to refresh your inmemory cache, etc. Fine. A pain in the f'ing butt , but fine none-the-less. (EDIT: unless the data has been cached in memory .. that is)
Anywys, two suggestions.
ProTip:
Oh! move away from role based shiz and start using Claims based identity stuff. Yes, it still works with IPrincipal and HttpContext.User, etc. So all previous code is NOT busted. But now it's baked into .NET 4.5
Awesome Video on this for you, me, everyone!
Finally - bonus suggestion
A nice package that auth's with either Facebook/Google/Twitter. You said you're keeping the user cred's on another site (good move!). If you're using other providers, then stick with DNOA or SS.
GL!

How to maintain User-session with ASP.NET MVC

Hey folks, I would like to know is there any way i can maintain stuffs like log-in,log-out,user-session..etc without using membership in ASP.NET MVC?
Faraaz.
There are three provider models concerned with the areas that you are referring to.
The MembershipProvider is concerned with authentication, validating users and storing data related to the user such as last login date, username, etc.
The RoleProvider is concerned with authorising users for particular areas of your application.
The SessionStateProvider is concerned with storing session for your application.
You can write your own custom provider for any of them if the default providers are not suitable. You could roll your own authentication, authorisation, or session management without the providers, however there would be quite a bit of work involved more so than implementing your own custom provider.
You can use the Session object to store session scoped data.
But for authentication/authorization you will need to come up with your own scheme.
You need to use the Session dictionary and a session state server. See http://msdn.microsoft.com/en-us/library/ms178581.aspx for more info.
Word of warning: In my experience the InProc session state mode only preserves the values you put into Session for the lifetime of the current HTTP request. They don't persist across requests as you might expect, even when you're using a single HTTP server and you'd think in-memory storage would persist. This may only occur while debugging using the built-in http server in VS2010, but even so it can cause you a lot of trouble trying to understand why state information isn't being saved.

How to authenticate a Windows Mobile client calling web services in a Web App

I have a fairly complex business application written in ASP.NET that is deployed on a hosted server. The site uses Forms Authentication, and there are about a dozen different roles defined. Employees and customers are both users of the application.
Now I have the requirement to develop a Windows Mobile client for the application that allows a very specialized set of tasks to be performed from a device, as opposed to a browser on a laptop. The client wants to increase productivity with this measure. Only employees will use this application.
I feel that it would make sense to re-use the security infrastructure that is already in place. The client does not need offline capability.
My thought is to deploy a set of web services to a folder of the existing site that only the new role "web service" has access to, and to use Forms Authentication (from a Windows Mobile 5/.Net 3.5 client).
I did see this question and I am aware of the limitations that Forms Authentication poses. Since security is not my primary motivator (I use SSL and can restrict access by IP address), but rather using existing user accounts and roles, my decision tree is somewhat different as well.
Can I do this, is it a good idea, and are there any code examples/references that you can point me to?
I ended up with a combination of things. First, forms authentication does not really work in this scenario, because of the redirects that you get when a users is not logged in or the credentials are incorrect.
Because I want to use the user accounts from the web app, I worked around this by just calling Membership.ValidateUser prior to processing each service call on the server.
A user is prompted for an id and password when logging on to the client. I store both values encrypted in the proxy class and pass them transparently with each call using a host header, so that the application does not have to bother with this once the user is logged in, i.e. the credentials were validated once by calling the Login() service method (which only calls Membership.ValidateUser).
I use the CryptoApi on both the server and the client side.
I understand that host headers are somewhat outdated for security applications, but since I use strong encryption AND SSL, it is perfectly adequate.

What should I do If I want to maintain session between HTTP and HTTPS - Asp.Net

What should I do If I want to maintain session between HTTP and HTTPS.. In my site's public area some pages are HTTP and some are HTTPS but I want to keep common session for both..
Once your user's have authenticated they will continue to have the same session cookie until it expires whether they are accessing pages with HTTP or HTTPS. Make sure that you are using encryption on your session cookie to make it more difficult to crack if you are passing it over an insecure protocol. You might want to look at the wikipedia article on session hijacking for more information.
There are a number of session state modes in ASP.NET you can use (which can be configured in web.config) apart from the default "In Proc":
StateServer mode, which stores session state in a separate process called the ASP.NET state service. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
SQLServer mode stores session state in a SQL Server database. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
Custom mode, which enables you to specify a custom storage provider.
See ASP.NET Session-State Modes on MSDN. I haven't tested this for HTTPS, but hopefully StateServer or SQLServer should facilitate this.
One session is maintained per application per user. So if you have one application which has some pages served over https and some over http, you do not have to worry about a new session being created when moving from https to http and vice-versa.

Resources