Symfony 2 - how to disable querying user at every page load? - security

I'm using my own User class as and entity provider for security system in symfony 2.0.
I noticed that on each reload of the page symfony is fetching user from db:
SELECT t0.id AS id1, t0.username AS username2, t0.salt AS salt3,
t0.password AS password4, t0.email AS email5, t0.is_active AS
is_active6, t0.credentials AS credentials7 FROM w9_users t0 WHERE
t0.id = ? Parameters: ['23'] Time: 4.43 ms
Is there any easy way to disable this behaviour? Maybe serialize user data in session variables or cache them some way?

You can change this behavior in the refreshUser method of your UserProvider.
You should be careful when doing this with doctrine: There is an issue at FosUserBundle github, explaining the pitfalls:
Storing it in the session would lead to several issues, which is why it is not done by default:
if an admin change the permissions of a user, the changes will have an effect only the next time you retrieve the user from the database. So caching the user must be done carefully to avoid security issues
if you simply reuse the user which was serialized in the session, it will not be managed by Doctrine anymore. This means that as soon as you want to modify the user or to use the user in a relation, you will have to merge it back into the UnitOfWork (which will return a different object than the one used by the firewall). Merging will trigger a DB query too. And requiring such logic will break some of the built-in controller which are expecting to be able to use the user object for updates.

Related

Current session id in sails js

I want to delete all sessions from all devices by one click in sails.js. How to get the current session id?
For example:
console.log(req.session.sessid) // sess:jV-M6_ZNCp-8x_jYPbSfbUilXd_T85i_
sails.js version 1.1.0-3
All sessions are unaware of which user they belong to unless you've mapped the session in a persistent storage system like Redis/Memcached cache or MySQL, MongoDB database.
One of the many solutions I could think of is as below:
Create a model in your sails app which can be called SessionMapper
Add three columns: userID, sessionID, and isActive (boolean).
Now whenever a user signs in, create an entry in this model/table.
Create a middleware through which all API requests (except /login and public APIs) will flow
This middleware will check if the current session is still active -- acting like an extra layer of authentication.
If the session is active, grant access / next()
if the session is invalid or isActive === false, log out the user internally and redirect to login page with some message.
To sign-out an users all active sessions, set isActive = false for userID = <user-id> in SessionMapper model.
Note: This method will increase a lot of READ operations on the datasource which is connected to SessionMapper. Move it to a better and efficient solution like Redis/Memcached if it hurts the primary operations.
I hope this pseudo code help you achieve your task. #tspentzas, the next time when you seek for a solution-- kindly add whatever you've tried so far in your question for the community to help you in a better way.
If I understand correctly from your question, req.session.destroy() is your answer.
https://sailsjs.com/documentation/reference/blueprint-api/destroy

OWIN with Identity 2 - avoid regularly hitting the database for common objects

I have just taken the plunge and started to learn the OWIN style of authorizing users into MVC applications. One issue I'm having is storing objects since the move away from session objects and into claims.
Traditionally what I would do is authenticate the user, and then store the User object in the session. This is useful when you are regularly using the data from that object all over the application.
Now that I have moved to OWIN with Identity, I instead store the UserId as a claim. I understand that the use of complex objects is best avoided with claims.
So I find that I'm regularly having to hit the database to read User information based on the UserId.
Here is how I am reading the UserId claim:
List<Claim> claims = HttpContext.Current.GetOwinContext().Authentication.User.Claims.ToList();
var ret = claims.FirstOrDefault(x => x.Type == StaffClaims.OrganisationId);
Is there a way that I can avoid taking this ID and reading the corresponding record from the DB each time? I want to achieve something like having the User object stored in memory somewhere.
Alternatively, does Entity Framework 6 allow caching so that I don't hit the database when repeating the same query (unless I know it has changed and should be re-read)?
First, storing the user object in the session is a hugely bad idea. Don't do that ever.
Second, you don't need to store the user id in a claim; you can get it anytime with User.Identity.GetUserId().
Third, Entity Framework does utilize caching, but not in a way I'd consider it as something you could rely on. If you want to cache something, then do it explicitly with System.Runtime.Caching. You can also utilize the OutputCache attribute on actions to cache the rendered view, which has the side effect of not requiring database calls to render it again.
Finally, this is not a big deal in the first place. Just fetch the user when you need it. Before you worry about this one simple query, there's probably 10,000 other areas of your application and could and should be optimized first.

How to ease CouchDB read/write restrictions on _users database

In my couchapp two databases are being used
1 Is for application data
2 Is "_users" database.
In my application In one form I'm trying to implement autocomplete where data source is a "view" created in "_users" database.
Now when I login with normal user id other than admin. While trying to access the view inside "_users" database I'm getting the error 403 which is :
{"error":"forbidden","reason":"Only admins can access design document actions for system databases."}
Is it possible for me to allow and limit the access for non admin users to that view only ? So I can get the list of users from _users database into my application.
I've never been able to do many tasks that require much custom with CouchDB by itself. I've always needed a script somewhere else that gives me the info that I need.
What works for me is this setup:
A gatekeeper Sinatra app that has admin access to my CouchDB
Using CouchDB's config to proxy to my Sinatra app. httpd_global_handlers _my_service {couch_httpd_proxy, handle_proxy_req, <<"http://127.0.0.1:9999">>}
The reason for the proxy is because any request that comes through to your gatekeeper will have the AuthSession token set. Inside your gatekeeper, you can GET localhost:5984/_session passing the AuthSession cookie along, it will tell you who is making the request, allowing you to look them up and see if they have access, or just give everyone access to whatever you like. Another reason for the proxy is to avoid any CORS nonsense since you're making the request to yourserver:5984/_my_service.
Update
A purely client-side/javascript solution means that it will be fundamentally insecure at some point, since well, everything is on the client-side. But perhaps your application, doesn't need to be that secure. That's up to you.
One workaround could be to make your application authenticate as a predefined admin, and then create more admin users that way. You could authenticate once when your application boots or on an as needed basis.
The "problem" is that CouchDB sees the _users database as fundamentally special, and doesn't give you the opportunity to change the credential requirements like other databases. Normally you would be able to use the _security document to give role based or user based access. But that's not possible with _users.
An alternative implementation might be to keep track of your own users and forgo the _users database altogether. In that case you could set your own cookies and have your own login and logout methods that don't depend on CouchDB's authentication scheme. You could query your own _view/users because it would be in your main database. Things wouldn't be locked down tight but they would work fine as long as no one was interested in hacking your system. :)

Login system using physical postgres users not "logical" users

I'm currently building an application that has to conform with SOX auditing requirements. One of these, is that all inserts, updates and deletes (but delete you can ignore), need to leave a trail that is difficult, if not impossible for a standard user (or non-DBA) to change.
This means, I need to enforce the auditing at the database level via triggers on insert, update and delete.
My problem is; this is a webapp... The typical design pattern is to store users as "logical", for example; in a "users" table. What I need, is for the application to actually run as the logged in user after the initial login.
My thinking (which is likely not the best) is to do the following:
Load the login page via a standard username (webapp)
Check a table called "stored_users" for their logical username/password.
If they enter the correct user/pass; retrieve the db username, generate a session password (stored in KVSession on redis), update the user on the postgres DB and login with it.
After a defined time of inactivity, destroy the password session, reset the db password for the user and log them out.
Does this sound like a safe way to ensure the following?
My users are always using postgres users; so I can enforce the triggers via CURRENT_USER etc..
Security by always regenerating the postgres user password with a random, temporary password
I'd really like to hear what others have to say on this matter; as I really can't find this on Google (or I'm not searching the right terms). It seems the prevailing mindset for user logins is to store them as logical records and have a global connection user.
To achieve your goal
all inserts, updates and deletes, need to leave a trail that is
difficult, if not impossible for a standard user to change.
you can create:
1) Two schemas: one for common tables, one for security stuff like login/pass(hash) table, user session log, change log table, etc.
2) Two users: one common user, that can only use dml on common schema (no ddl), one superuser.
3) Login function that will check provided user/pass against login/pass table and log successful/failed attempts into user session log (you need SECURITY DEFINER function)
4) Set of audit triggers on common schema tables that will check the user privileges and log any changes, made by the user (SECURITY DEFINER functions here too).

Should Domain Entities always be loaded in their entirety?

I have a custom ASP.NET Membership Provider that I am trying to add password history functionality to. User's passwords expire after X days. Then they have to change their password to one that has not been used in their past X changes.
I already had the User entity, which has a password attribute for their current password. This maps to the User table in the db. Since I needed a list of previous passwords I created a UserPassword table to store this information with a FK reference to the UserId.
Since passwords are value objects, and have no meaning outside of the user, they belong inside the User aggregate, with the User as the root. But here in lies my dilemma. When I retrieve a User from the repository do I always have to get all of their previously used passwords? 99% of the time I don't care about their old passwords, so retrieving them each time I need a User entity seems like a dumb thing to do for db performance. I can't use lazy loading because the User entity is disconnected from the context.
I was thinking of creating a PasswordHistory entity but for the reason stated above, passwords aren't really entities.
How would you DDD experts out there handle this situation?
Thanks.
Edit 1: After considering this some more, I realized this is essentially a question about Lazy Loading. More specifically, how do you handle lazy-loading in a disconnected entity?
Edit 2: I am using LINQ to SQL. The entities are completely detached from the context using this from CodePlex.
It is hard to fully answer this question because you do not specify a platform, so I cannot be exactly sure what you even mean by "disconnected". With Hibernate "disconnected" means you have an object in a valid session but the database connection is not currently open. That is trivial, you simply reconnect and lazy load. The more complicated situation is where you have an object which is "detached" i.e no longer associated with an active session at all and in that case you cannot simply reconnect, you have to either get a new object or attach the one you have to an active session.
Either way, even in the more complicated scenarios, there is still not a whole lot to lazy loading strategies because the requirements are so inflexible: You have to be "connected" to load anything, lazy or otherwise. Period. I will assume "disconnected" means the same thing as detached. Your strategy comes down to two basic scenarios: is this a situation where you probably need to just reconnect/attach on the fly to lazy load, or is it a scenario where you want to make a decision to sometimes conditionally load additional objects before you disconnect in the first place?
Sometimes you may in fact need to code for both possibilities.
In your case you also have to be connected not only to lazy load the old passwords but to update the User object in the first place. Also since this is ASP.NET you might be using session per request, in which case your option is now basically down to only one - conditionally lazy load before your disconnect and that is about it.
The most common scenario would be a person logs in and the system determines they are required to change their password, and asks them to do so before proceeding. In that case you might as well just take care of it immediately after login and keep the User connected. But you are probably using session per request, so what you could do is in the first request process the time limit and if it is expired, you are still connected here so go ahead and return a fully loaded User (assuming you are using the historic passwords in some kind of client side script validation). Then on the submit trip you could reattach or just get a new User instance and update that.
Then there is always the possibility you also have to provide them with the option to change their password at any time. They are already logged in. Does not matter much here, you have a User but the request ended long ago and it does not have passwords loaded. Here, I would probably just write a service method where when they invoke a change password function the service gets a second copy of the User object with the full history for update purposes only, then updates the password, and then discards that object without ever even using it for session or authentication purposes. Or if you are using Session per request you have to do the equivalent - get a fully initialized object for client side validation purposes, then when the data is submitted you can either reattach either one you already have or just get yet a third instance to actually do the update.
If the password is needed after beginning an authenticated session, you could still do the same things and either replace the local User or update the local User's in memory password version as well.
If you have too much stuff going on with multiple levels of authentication most likely you are going to have to require them to logoff and do a full log back in after a password change anyway, so the state of the User does not matter much once they request a password change.
In any case if you are using session per request and your objects become fully detached after every request, in the first scenario you can still lazy load while you are on the server on the original request to return data for client side validation. In the second scenario you have to make another trip (there really is no such thing as lazy loading here). In both case though you have to weigh your two update options because you are always disconnected before an update. You can either just get a second instance from the database on the submit trip to update, or you can reattach the one you already have. It depends on what is optimal/easiest - does saving a db round trip for an uncommon event really matter? Does reattaching using your ORM of choice possibly hit the database again anyway? I would probably not bother to reattach and instead just get a new instance for the actual update as I needed it.

Resources