Allow access to specific user only (Postgres) - postgresql

I have a database with an owner for it. My problem is that, though i have assigned a password for the owner, any other db user can access this database locally, even without password.
How can i configure the database so that only a specific user has access to it (only with right password)?

Related

Best practices for creating a admin role group in PostgreSQL

I'm currently trying to find the best process for managing admin privileges throughout my PostgreSQL databases. What I am trying to do is assign permissions that are sufficient enough for in an admin role group where I can GRANT a user (another admin) to inherit the permissions of the role group; however, I'm not sure if this can be done or how to do this. The admin role group's privileges should be the following:
Able to add users
Able to view users and permissions in a database
Able to reset a user's password, dropping a user, or resetting a user's name
Able to show grants of a particular user
Able to add specific permissions for a user to a schema and table. (So have permissions to the database and tables)
For auditing purposes, should I even go with this approach of creating a role group or add a user (admin) with no role group? I remember reading that the role group would show as who did any changes rather than the specific user. Would appreciate clarification on this.
Thanks for reading my post.

What happens when a User Mapping's Password Changes?

I would like to use a service with our Database, but it doesn't support Amazon RDS IAM Database authentication. My plan is to have a mock-database that only has tables it needs from the original postgres DB, and to have a script that refreshes the service's user's password on the real DB every time it expires (15 minutes).
What happens when I call ALTER USER MAPPING on the Foreign User? Does it reconnect to the server with a new username and password?
Yes, when you change the userid or password using ALTER USER MAPPING, it will reconnect the user. It may wait until the user actually requests something to authenticate, but the user will not know the difference.

Should I avoid creating a MongoDB user in the 'admin' database if I do not intend to grant it cluster level roles

The MongoDB documentation indicates that a user can be created with any database as its authentication database. Is there any reason I would choose to create my user in the 'admin' database, unless I intended to grant it cluster level privileges?
Should I avoid creating users in the 'admin' database unless the above criteria applies?
Where the user is stored does not influence what privileges are granted to the user.
If you prefer to have all users defined in the same place, it makes sense to keep them in the admin database.
If your users have access to one database each and you prefer to have users defined in the database that they have access to, it could make sense to define them in the database they have access to.
In either case which databases the users have access to, and what operations they are allowed to perform, can be defined per user.
If you store users in admin database, but the client is connecting to another database, the authSource must be explicitly specified when connecting.

Role creation on postgres

I'm developing a small database for a library but I'm completely ignorant when it comes to roles and privileges.
I've spent quite some time googling but I still don't truly get the mechanisms.
My aim is to create 3 basic roles:
User with no login (not really an user, just someone who wants to see the books the library has in store, but he can't do any action besides just watching)
User with login (He can preorder books and do other actions)
Admin (He can add new books, authors, genres and can give the admin privileges to other users)
At first I thought I could create these 3 roles specifying the various privileges each one has and then, on the related website, every time someone would connect he would have been considered an "User with no login" until the login which would've determinated whether he is an Admin or not; reading the PostgreSQL documentation I understood it's nothing like this, or perhaps I got it wrong.
I really have no clue what to do, any help would be appreciated.
What you want to do is reasonable. Your webapp should log in with its connection pool as a user (say mywebapp) that is marked NOINHERIT and has no rights except to SET ROLE to three other roles. Each of those roles describes one of the categories of users you mention above. You'll also need to GRANT the rights to access any tables used to look up and authenticate users to the mywebapp user.
When servicing a request, if it's acting on behalf of an anonymous user it does SET ROLE anonymous_web_user; or whatever.
If it's acting as a named user, it does SET ROLE authenticated_user;. You'd GRANT the right to read the table you use for authenticating users to the mywebapp role so it can authenticate them in whatever way your app does so.
If it's acting as an admin, it does SET ROLE admin;. Or, if there aren't many admins and they need different rights, you can make them PostgreSQL users, and SET ROLE the_admin_user_name;. Again, your app would pre-authenticate them, and SET ROLE if it was satisfied with the user's authentication.
When a connection is returned to the pool it is vital that the pool run the query DISCARD ALL; to clear the connection's role setting.
So, for example, you might:
CREATE ROLE mywebapp WITH LOGIN NOINHERIT;
CREATE ROLE anonymous_web_user;
CREATE ROLE authenticated_user;
CREATE ROLE admin_user;
-- 'mywebapp' can become anyone, but by default doesn't
-- get the rights of any of them since it's marked NOINHERIT
GRANT admin_user TO mywebapp;
GRANT anonymous_web_user TO mywebapp;
GRANT authenticated_user TO mywebapp;
-- All admins are authenticated users, since authenticated_user
-- is INHERITable
GRANT authenticated_user TO admin_user;
-- All authenticated users have the rights of anon users too
GRANT anonymous_web_user TO authenticated_user;
-- The app must be able to look up users
GRANT SELECT ON some_users_table TO mywebapp;
-- but only admins can change them
GRANT ALL ON some_users_table TO admin_user;
...
See Role membership.

How to store these dbusername,dbpassword after login in play framework?

I have a separate dbusername and dbpassword for each login user in a Play framework Scala application. Login credentials are first checked by against a stored Postgres database username and password. After a successful login it gets the user's dbusername and dbpassword, and connects to the database. How should I store the dbusername and dbpassword after login in the Play framework? Can I use global variables?
To clarify what you are doing here:
You are using Postgres user credentials as your Play application
user credentials.
Database connections are authenticated with the user credentials, so you must be using database access control (i.e. GRANTs) for permissioning.
The first one is fine. The second is not, as it is not compatible with connection pooling. You would have to either: have a private connection pool per user (too many connections to your Postgres server), or open a new connection for every database access (slow). If your application will have more than a few users, I strongly recommend using the default database configuration in Play (single username/password in application.conf), which will use the built-in Play connection pool (i.e. the boneCP plugin). With this configuration, you would have a Postgres username/password for your Play application. You will have to implement permissioning in a different way.
To actually answer your question, here's the way to store information for a logged-in user:
On successful login, store a session id in the Play session (not the user name, the session cookie is not encrypted).
Store the user information in the cache, using the session id as part of the key. The cache is really a big global variable, so you were right about needing that!
For each request, check if the session id is in the session. If not, the user is not logged in, so redirect to the login page. If the session id is valid but not in the cache, the session has expired, so redirect to login.
Update: if you have a small set of database credentials (corresponding to user roles), you can just use normal Play database configuration as follows:
1.In application.conf, create a set of db config settings, one for each role. For example:
db.guest.driver=org.postgres.???
db.guest.url=???
db.guest.user=theguest
db.guest.password=secret
2.At login, look up the user role, and store it in the cached session, as above. Then get the database connection using the connection name, like this:
val role = getRoleFromSession(request) // e.g. role = "guest"
play.api.db.DB.withConnection(role) { implicit c => ... }
You should put the username/passwd into a configuration file, and use com.typesafe.config.ConfigFactory to load that info at runtime.