DotNetOpenAuth on web farm - session

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.

Related

Access postgres DB from two applications

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.

JSON Web Token (JWT) benefits over a database session token

With a database session token system I could have a user login with a username/password, the server could generate a token (a uuid for example) and store it in the database and return that token to the client. Every request from thereon would include the token and the server would look up whether the token is valid and what user it belongs to.
Using JWT there would be no need to save anything to the database with respect to session/tokens thanks to the combination of the secret key kept on the server and the signed token the client keeps and sends with every request.
This is good but besides saving a database check each request (which would be fast anyway since it's just checking a hash table) it's not clear to me what the advantages are of using JWT. Can you anyone familiar with this explain? Let's ignore cookies, it's specifically a database custom token as described above and JWT that I am trying to compare and understand the benefits.
The main difference is the session storage size and lookup work required from the server:
On the server side, JWT stores a single key in memory (or in config file) - called secret key. That key has two purposes, it enables creating new encrypted tokens and it also functions like a master key that "opens all locks", in practice it verifies all tokens.
As a result the server responds much faster to auth requests, because it doesn't matter if you have two or two million users logged in - the same number of records (one, that server key) will be used to authenticate all client requests.
Traditional authentication that stores user sessions in a database, creates a record in the db for every single user, which results in multiple keys.
So if you have two million users logged in, the server will create two million records and with each client request the server needs to locate the relevant session record in the database*.
JWT leaves it up to the client side to store and handle the entire session/user object. It actually makes much more sense because every client handles their own data only, so it doesn't cause heavy lifting for the client side either.
As for what you wrote in your last paragraph, it's not just db calls that we save here. JWT is actually much more scalable because of its independent and lightweight nature, it doesn't fail as auth requests pile up and it allows the server to handle auth accross devices and services without managing sessions on the server side.
Security wise though, db sessions arguably have the upper hand: they can be more secure because of that latency, and are also less vulnerable to session hijacking after user logout.
*The db stored sessions method can be optimized with effective caching and by storing only the session id (as opposed to the entire user object) in a fast key/value server such as Redis. That said, I would still choose JWT method over db for most cases.
A Json based token(JWT) overcomes the following problems:
Mobile issues: Native mobile apps seems to have problems working with cookies so if we need to query a remote API, maybe session auth is not the best solution.
CSRF issues: If you are following cookies way then you need to have CSRF to avoid cross site requests.
But JWT doesn’t use sessions, has no problems with mobile, it doesn’t need CSRF and it works very well with CORS too. If you dont have a valid token you can't do anything.
One more as this token gets stored at client local storage/session storage so you can pass these tokens to other clients as well but you have to share the same credential which you used to generate this JWT.
You are underestimating impact of the database call. Database connections are expensive and round trip takes time. If you are doing thousands of requests per second. Your database would be bogged down with just authentication related queries. In that case not only will it be slow, the query can altogether fail. Even if you use something lighter and faster like redis, it won't be more robust or faster than not making a call at all.
The JWT alternative eliminates all this. The auth can be done without a network call to and response would be sent in milliseconds.

Why are sessions in the Snap Framework client side only?

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.

Using Forms Authentication Cookie to Cache Roles - (Windows Authentication)

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?

What's the best way to store Logon User information for Web Application?

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

Resources