I am wondering if there are any risks or pitfalls involved in me using the WindowsAuthentication_OnAuthenticate event to create a FormsAutnetication ticket to store user roles. I grab these roles from a couple different queries (I don't have permission to change the db schema so...). I don't want to use ASP.NET's role manager and My concern is that if I don't use a cookie (at least one that expires every 30mins or so) then performance might be an issue since WindowsAuthentication_OnAuthenticateis would get called for every request and I'd be make making these db calls constantly (not to mention having to decrypt the cooke and build a custom principal for my Context on the Application_AuthenticateRequest event).
Yes and no. If it's compromised yes, if not no.. From a security standpoint it's not a good idea and this has been compromised although quickly patched (see the POET vulnerability)
It's for you to decide if the risk is worth it which it generally isn't.
Why not consider a server side cache to store this data on instead and only of the cache is empty then check for the roles?
Related
I am performing load balancing for my application. I have made two application servers, say A and B. That access the same database (Postgres) using Hibernate.
The problem arises when the system moves from A to B. Most of the things are working fine, but at some points (While reading data from db) the system automatically logs the user out.
Is this because of synchronization with db?
Is there some kind of lock on the database when one application is accessing the database?
What do i need to do in-order to get it working?
It'll be a great help.
While the Postgres server can terminate connections for various reasons (i.e. if an admin does so), generally that would be a client-side thing, which in your case is likely Hiberate as a Spring DAO. If your app-level login is being closed, it's likely to be an issue with how your app is logging back in on the other server.
Most likely, you have entirely separate DAO instances on each server, and so when the switch from app-server A to B occurs mid DB read, it has to start over from the beginning on the new server, including authentication, et al.
I'm assuming each is deployed in its own WAR and has the DAO injected at runtime, at which point the connection to Postgres is made. (You could add logging in your dependency-injection code to determine more.)
In addition to the separate database connections, it appears it doesn't handle failover to the other server without requiring re-logging in. That shouldn't be related directly to Postgres, at least not the connection. It would depend on how you're persisting the login. i.e. if it's cached locally, that would also have two separate instances in each app, and the authentication would need to reoccur. If the credentials are stored in Postgres, the connection would first need to be obtained before re-authenticating.
Edit in response to comment from OP:
Since they are two separate app instances, a load balancer alone would not work, since that would most likely depend on the request being (mostly) stateless. If you authenticated via a token which was either in the URL or the header, a load balancer would work, since the the auth token would be redirected also, and while reauthentication would need to happen in the backend, authentication should be granted if the token is valid, and the app should essentially stay logged in. It doesn't sound like you're using auth tokens, though.
In short, which two separate instances, the authentication really always needs to happen on every request, but how that's managed can vary. You could look into an OAuth solution, for example, but that may be overkill for your needs.
In any case, you should avoid taking state straight from the client, since that can be tampered with. If the server were to failover cleanly (say, for load purposes), you could control that security handover in the app logic by propagating the security context to the other instance, although that could get a bit unwieldy.
However, during an unclean failover (say, if the JVM heap limit is reached), that wouldn't be possible -- you would need an external authentication system that the other app could query using the supplied credentials, determine the request is authenticated, and allow the request to proceed.
By browsing through the code of the Auth and Session snaplets I observed that session information is only stored on the client (as an encrypted key/value store in a cookie). A common approach to sessions is to only store a session token with the client and then have the rest of the session information (expiry date, key/value pairs) in a data store on the server. What is the rationale for Snap's approach?
For me, the disadvantages of a client side only session are:
The key/value store might get large and use lots of bandwidth. This is not an issue if the session is only used to authenticate a user.
One relies on the client to expire/delete the cookie. Without having at least part of the session on the server one is effectively handing out a token that's valid to eternity when setting the cookie.
A follow-up question is what the natural way of implementing server side sessions in Snap would be. Ideally, I'd only want to write/modify auth and/or session backends.
Simplicity and minimizing dependencies. We've always taken a strong stance that the core snap framework should be DB-agnostic. If you look closely at the organization, you'll see that we carefully designed the session system with a core API that is completely backend-agnostic. Then we included a cookie backend. This provides users with workable functionality out of the gate without forcing a particular persistence system on them. It also serves as an example of how to write your own backend based on any other mechanism you choose.
We also used the same pattern with the auth system. It's a core API that lets you use whatever backend you want. If you want to write your own backend for either of these, then look at the existing implementations and use them as a guide. The cookie backend is the only one I know of for sessions, but auth has several: the simple file-based one that is included, and the ones included in snaplet-postgresql-simple, snaplet-mysql-simple, and snaplet-persistent.
It seems some web architects aim to have a stateless web application. Does that mean basically not storing user sessions? Or is there more to it?
If it is just the user session storing, what is the benefit of not doing that?
Reduces memory usage. Imagine if google stored session information about every one of their users
Easier to support server farms. If you need session data and you have more than 1 server, you need a way to sync that session data across servers. Normally this is done using a database.
Reduce session expiration problems. Sometimes expiring sessions cause issues that are hard to find and test for. Sessionless applications don't suffer from these.
Url linkability. Some sites store the ID of what the user is looking at in the sessions. This makes it impossible for users to simply copy and paste the URL or send it to friends.
NOTE: session data is really cached data. This is what it should be used for. If you have an expensive query which is going to be reused, then save it into session. Just remember that you cannot assume it will be there when you try and get it later. Always check if it exists before retrieving.
From a developer's perspective, statelessness can help make an application more maintainable and easier to work with. If I know a website I'm working on is stateless, I need not worry about things being correctly initialized in the session before loading a particular page.
From a user's perspective, statelessness allows resources to be linkable. If a page is stateless, then when I link a friend to that page, I know that they'll see what I'm seeing.
From the scaling and performance perspective, see tsters answer.
I am implementing DotNetOpenAuth for both an OpenId provider and a relying party. In both cases, the servers are behind a load balancer, so for any HTTP request, we can't assume that we'll hit the same server.
It appears that DotNetOpenAuth depends on the Session to store a pending request key. Because the server may change between requests, we can't depend on the standard InProc Session. Unfortunately, we've been unable to successfully implemented SQL as the store for Session.
My question is: is it safe to store a PendingAuthenticationRequest as a client cookie? Any worse than using Session?
The ProviderEndpoint.PendingAuthenticationRequest property is there for your convenience only, primarily for simpler scenarios. If it doesn't work for you, by all means store it another way and totally ignore this property. No harm done there.
Ultimately a session is tracked by an HTTP cookie, so you can certainly store the auth request state entirely in a cookie if you prefer so that it works in a web farm environment. Another approach is to not require the client (or the server) to track state at all by either making everything (including authentication) handled directly at the OP Endpoint URL, or redirecting the user from the OP Endpoint URL with a query string that includes all the state informaiton you need to track. Be careful of the latter approach though since you'll be exposing your state data to the user to see and possibly tamper with.
In short, you may or may not choose to store user sessions in a SQL store. That should be fine. The issue I think you ran into (that we discussed by email) was that you needed to implement your own IProviderApplicationStore, which will store nonces and associations in a database that is shared across all your web servers. This is imperative to do, and is orthogonal to the user session state since this is stored at the application level.
I was once in a project of web application developed on ASP.NET. For each logon user, there is an object (let's call it UserSessionObject here) created and stored in RAM. For each HTTP request of given user, matching UserSessoinObject instance is used to visit user state information and connection to database. So, this UserSessionObject is pretty important.
This design brings several problems found later:
1) Since this UserSessionObject is cached in ASP.NET memory space, we have to config load balancer to be sticky connection. That is, HTTP request in single session would always be sent to one web server behind. This limit scalability and maintainability.
2) This UserSessionObject is accessed in every HTTP request. To keep the consistency, there is a exclusive lock for the UserSessionObject. Only one HTTP request can be processed at any given time because it must to obtain the lock first. The performance and response time is affected.
Now, I'm wondering whether there is better design to handle such logon user case.
It seems Sharing-Nothing-Architecture helps. That means long user info is retrieved from database each time. I'm afraid that would hurt performance.
Is there any design pattern for long user web app?
Thanks.
Store session state in the database and put memcached in front of it.
One method discussed on StackOverflow and elsewhere is the signed cookie. A cookie that has information you would otherwise not be able to trust, along with a hash created in such a way that only your server could have created it, so you know the information is valid. This is a scalable way to save non-high-security information, such as username. You don't have to access any shared resource to confirm that the user is logged in as long as the signed cookie meets all criteria (you should have a date stamp involved, to keep cookie theft from being a long term issue, and you should also keep track that the user has not authenticated, so they should have no access to more secure information without going through the usual login process).
StackOverflow: Tips on signed cookies instead of sessions