Web application with secure access for users and groups of users - java

So I'm working on a project with a multi-tenant database (MySQL, Java JDBC). Each tenant can be considered a "group", and each "group" has multiple "users". My main confusion is how best to secure this, so members of a group can only access data from that group, even though they're all logging in with separate credentials.
If I was just having a group-based login, it'd be simple: one schema per group, one database user with access to each schema. This could make it so that access would be completely restricted, since without that group's password no one can access that schema.
It's with the users, what I'll be calling the "application users", that things get complicated. Each application user would be associated with a group, and when that application user logs in, they would need access to the group they are associated with. In essence, they log in as an application user, and are granted the credentials for a database user.
Right now, the idea just seems to unwieldy and insecure. If there is a way for the JDBC application layer to grant access to any database level user account, then that security becomes pointless, since it would become easy to bypass.
I guess I'm looking for guidance about how to best secure this kind of environment. Thank you.

Heres a better idea than allotting different database users for different tenants, just use a table to store all Data of Group. One Table for all application users and a third relational table to link group or tenant IDs with their respective group members' userIDs.
Whenever a Group resource or data is requested by any application user, check in the relational table if the user has authority to access the group data or not. Good Luck

Related

How to maintain integrity of a LDAP system together with a relational database?

Currently i'm developing an application which authenticates the users against an external LDAP system. The applications specific data is saved in a relational database though.
My question is if there is a design pattern or something like a best practice to maintain referential integrity in my database concerning the user entries?
One of my ideas was to grab an unique identifier of the user from the LDAP system (once the first login of this user occurs) and store this together with a generated primary key in a table in my database. If I do it like this I would be able to reference the primary key in my other tables. Is this a good approach? Are there any better alternatives?
I'm using an Active Directory, a java backend and a postgres database.
What you described is essentially the approach I've taken for applications that store user login info (or really any LDAP related info) in a separate database.
Basically when they login decode their objectGuid attribute value to get their UUID and use that UUID string to do the rest of their lookups in the database. This helps a lot on user account renames, as you can just lookup the UUID and if it matches then re-sync the user's data (if any else is saved in the DB).

What's the benefit of using j_security_check over self-coded login module?

j_security_check makes it easy to load users from a ldap server. It saves me a USER table. It's like user-management task is separated from the system.
But the problem is, in a production system with sophisticated requirements, a lot of data is associated with user id. What I expect from the user-management is not simply login/verify the password. For example I have an USER_MEMBERSHIP table, to record what kind of membership a specific user has purchased. If the user logs by j_security_check, how can I list users belonging to a specific membership? Eventually I wound up creating another USER table in my database, and fill in user info the first time they get logged in. If I have to do this, why should I use j_security_check anyway? Why not just verify the password in my database, and cut off the complicity of form_login/ldap ?
I'm getting so confused here. Is it fair to say j_security_check is for simple systems only? Is it recommended login machinism for sophisiticated Java EE applications?
Thanks in advance.
J_security_check is part of Container Managed Authentication, which assumes the entire burden of ensuring users are logged in, associating them with roles, and enforcing role-based access to various parts of the application as defined by security entries in web.xml. If you don't use CMA, you are condemned to reimplement all this stuff yourself. It's possible; it's error-prone; it's repeating work that has already been done. And tested.

Same authentication in 3 different web applications, that have their own database

I have three REST web applications (Java) with their own database (MongoDB).
All the applications require authentication, so I created a collection called User in each database.
Now I want the same user to be able to log in each application.
Shall I have a fourth shared database only for user?
Shall I have a sort of synchronization process of the collection User among the three databases?
What's the solution?
I think the solution is to develop some microservice (OAuth2 for example) to do the authentication and implement all login and permission check routines by its means.
If that's an overkill for your task, it is better to make a separate DB for user accounts and synchronize application databases against it.

Java web application authentication - account design

I am working on a web project, backend is Java & Mysql, the client include web(html5) and app(IOS/Android), I have some doubt in design the account of the system.
There are 3 different types of account:
Shop, shop account will have its own website,
Customer, customer access shop/commodity via app(IOS/Android),
Admin, manage everything of the system.
My basic idea of authentication:
There will be account / role / permission table for sure, because both admin & customer will have quite complex user permission issue, customer also have different permission due to their history behavior.
I have kind decided to use Apache Shiro, due to its simplicity & distributed session.
My question is:
(1) Should I create a single account table or 3 individual account tables.
(2) Any advise on design of 3 tables:
account / role / permission ?
If in your first question you're asking how to design a database schema for three very distinct entities (admin user, customer user and shop owner), I suggest you don't combine them into a single table, because they are different concepts and will likely have different features.
You kind of answered your own question, since "ease of programming" rarely trumps business rules/logic.
Your decision to use an existing security framework, or to roll your own, should be independent of the data model for your core business entities.
If you don't want to use a managed solution like Stormpath, and haven't settled on Shiro yet, check out OACC, an open-source permission-based security framework for Java with support for hierarchical security domains, super users, permission inheritance and impersonation.
It might be a good fit for your project because:
you won't need to clutter your database design with authorization-related aspects
OACC was designed for multi-tenancy application architectures (like your project's "shops")
it allows for impersonation, which is a powerful feature if you need to support customer service representatives without giving them "admin" privileges
[Disclaimer: I am a maintainer and co-developer of OACC]
I suggest you to consider delegating all your user-management needs to Stormpath. With Stormpaht, you do not need to worry about such low-level concerns, all your data is securely managed and stored. Stormpath provides:
User management API with different SDKs: node.js, express, java, rest, python, flask.
Off the shelf Hosted Login: login, registration, and password reset.
Off the shelf ID Site to power Single Sign-On across your applications
API keys for your users, secured with HTTP Basic Auth or OAuth2
Social Login: Facebook, Google, LinkedIn, Github
Integration with Shiro and Spring Security
Integration with Active Directory and LDAP
With Stormpath you will only need to create Groups which will represent your roles. Inside your groups and accounts, you can also create finer-grained concepts like permissions using our flexible Custom Data concept.
As mentioned above, we also support Shiro integration, where you can model all your security needs with Shiro while using Stormpath as the authentication and authorization data provider. Please take a look at our Stormpath Shiro plugin and at our Sample Shiro Web App.
Disclaimer, I am an active Stormpath contributor.
To be short: you don't need role / permission tables :)
I would decide first do you really need RBAC security model? Your application looks like a perfect use case for hexagonal architecture with 3 separate isolated front-end parts: Consumer, Shop, Admin. Then I would advise to build separate authentication/authorization mechanism for each of these front-ends. In this case you are flexible to choose the best tool for the purpose (OAuth2, OpenID, LDAP whatever) and follow least common mechanism security principle. Your application doesn't look like the one which needs authorization on method level, thus you don't need RBAC.
I would design each Java object depending on its individual needs. Get clear about what you have to create. Are there overlappings in the account types? Shall a Shop account be able to buy something like (that is. extend) a Customer, or shall an Admin implement both a Shop and a Customer? Shall the address of a Customer, living in the same street as a Shop is located, change if the Shop reports the street got renamed? Does the phone number’s area code depend on the city?
If your Java objects do their job properly, think about the O/R mapping in a second step. Perhaps it will be even very different from what you may think now (just think of carrier codes in telephone numbers that require inline replacement, Packstation boths, Shops with multiple persons of contact, different address layouts in different countries …).
In general, make sure your address fields properly support UTF-8 for diacritics, greek, cyrillic or arabic addresses.
(1) Should I create a single account table or 3 individual account tables.
Yes, I think you should design a single one, as an account is going to have similar data for all 3 types.
(2) Any advise on design of 3 tables: account / role / permission ?
account: PK account_id int, FK role_id int
role: PK role_id int, account_permission enum(admin [0], customer [1])
You do not need a permission table, you may handle your permission levels in your application code, using composite design pattern, where you can have multiple hierarchical levels of admin or customer permissions. Reason for this is it's better to declare your business logic in your model code rather than database design, database is there to persist data with as optimised and normalised state as possible. I suppose you can then use dependency injection to your composite permission hierarchy depending on customer behaviour, which needs to be held in the database under a table, ie named customer_behaviour, with certain columns "ticked" as they behave certain ways.
Hope this helps.

Implementing multi-tenancy for a mature enterprise application

I've been tasked with making an enterprise application multi-tenant. It has a Java/Glassfish BLL using SOAP web services and a PostgreSQL backend. Each tenant has its own database, so (in my case at least) "multi-tenant" means supporting multiple databases per application server.
The current single-tenant appserver initializes a C3P0 connection pool with a connection string that it gets from a config file. My thinking is that now there will need to be one connection pool per client/database serviced by the appserver.
Once a user is logged in, I can map it to the right connection pool by looking up its tenant. My main issue is how to get this far - when a user is first logged in, the backend's User table is queried and the corresponding User object is served up. It seems I will need to know which database to use with only a username to work with.
My only decent idea is that there will need to be a "config" database - a centralized database for managing tenant information such as connection strings. The BLL can query this database for enough information to initialize the necessary connection pools. But since I only have a username to work with, it seems I would need a centralized username lookup as well, in other words a UserName table with a foreign key to the Tenant table.
This is where my design plan starts to smell, giving me doubts. Now I would have user information in two separate databases, which would need to be maintained synchronously (user additions, updates, and deletions). Additionally, usernames would now have to be globally unique, whereas before they only needed to be unique per tenant.
I strongly suspect I'm reinventing the wheel, or that there is at least a better architecture possible. I have never done this kind of thing before, nor has anyone on my team, hence our ignorance. Unfortunately the application makes little use of existing technologies (the ORM was home-rolled for example), so our path may be a hard one.
I'm asking for the following:
Criticism of my existing design plan, and suggestions for improving or reworking the architecture.
Recommendations of existing technologies that provide a solution to this issue. I'm hoping for something that can be easily plugged in late in the game, though this may be unrealistic. I've read about jspirit, but have found little information on it - any feedback on it or other frameworks will be helpful.
UPDATE: The solution has been successfully implemented and deployed, and has passed initial testing. Thanks to #mikera for his helpful and reassuring answer!
Some quick thoughts:
You will definitely need some form of shared user management index (otherwise you can't associate a client login with the right target database instance). However I would suggest making this very lightweight, and only using it for initial login. Your User object can still be pulled from the client-specific database once you have determined which database this is.
You can make the primary key [clientID, username] so that usernames don't need to be unique across clients.
Apart from this thin user index layer, I would keep the majority of the user information where it is in the client-specific databases. Refactoring this right now will probably be too disruptive, you should get the basic multi-tenant capability working first.
You will need to keep the shared index in sync with the individual client databases. But I don't think that should be too difficult. You can also "test" the synchronisation and correct any errors with an batch job, which can be run overnight or by your DBA on demand if anything ever gets out of sync. I'd treat the client databases as the master, and use this to rebuild the shared user index on demand.
Over time you can refactor towards a fully shared user management layer (and even in the end fully shared client databases if you like. But save this for a future iteration.....

Categories