Java EE Security Concept - java

I need to create an application with authentication and authorization using Java EE 6 (Glassfish Server). I read a lot about Java EE 6 security and just wanted to ask if my concept is correct:
Every user in the company has an account according to "X123456". I want to use this for LDAP Authentication:
Application ---> LDAP
So, I can use the company's infrastructure to authorize the user.
However I want to be in control of the roles in my application. So, I want to define my own roles using JACC. Therefore I will create a database with a user-to-role mapping,
Example: "X123456 -> ADMIN".
The benefits would be:
I don't need to store any password
I can create a kind of admin panel in my application where I can set the existing roles to users dynamically
Do you think this would be technically possible and good practice?
Alternative: Would it be possible to define the roles (Admin, User) in Active Directory and query it via LDAP? So I could outsource my user-to-role mapping into active directory.
Update:
For authentication I currently use a LDAP-Realm (user, password).
For authorization I want to use a database (rolename, user). However I don't know how to tell my application to use the database for authorization. If I would use a JDBC-Realm, I could specify the Group/Role table and column. Is there a way to tell my application to just use the JDBC-Realm for authorization?

Related

Spring boot security roles per entity

My application has currently two types of users: Admin or Normal user.
The application has several projects: 100 or more. Per project the user has a different role like project owner, client, etc...
I'm now figuring out the best way to put those subroles in place.
Because in my services I want to use PreAuthorise("hasRole('OWNER')") so that only the right people can execute an update or whatever.
What I was trying now was giving every project a list of users that are working on it with a roles (project owner, client, etc...) when I login via Spring Security I retrieve the user and fetch all the projects where he is part of and then I add roles as follows ROLE_PROJECTNAME_OWNER or ROLE_PROJECTNAME_CLIENT.
The thing is that I can't use the HASROLE because there are a lot of projects so I can't annotate in advance which projects there are to allow a method call in my service layer. I also can't just add OWNER because then I don't know in which project. So I'm a little bit stuck here how to do this properly.
Define your own service to manage access with user/project/role and call this service directly on your #PreAUthorize.
Have a look to : https://dreamix.eu/blog/java/implementing-custom-authorization-function-for-springs-pre-and-post-annotations
Why don't you separate your users and the groups they form part of, from the roles and services they can access.
There are various ways you can do this, but one approach is to have the central authentication framework provide you the groups of the user once he performs authentication.
Now within each service, there will be a mapping between groups and roles. The roles are application specific, the authentication service or the other applications do not care about them. You might store this mapping in the individual application's database, or in a simple configuration file (maybe simply in application.yaml of the specific application).
Your groups currently are Admin and Normal but you could have others. A user could also be a member of multiple groups. So in application 1 you could say that Admin users can do role 1, role 2, role 3, while Normal users can only do role 1. Again it is many to many. This is something your UserDetails instance would carry once it recognizes the authenticated user and his groups, which are then mapped to roles as part of your Spring Security configuration. You will then be able to do PreAuthorise("hasRole('OWNER')") etc. on your services.
This way, if you add more users, you just put them in the right groups to give them access to the individual services. If you want to create new profiles, instead of just Admin and Normal, or special groups, you just do it once and update the configuration of the individual application to recognise that group if it is relevant to it (remember the user can be a member of multiple groups, so you don't even need each application to know about each group).
I don't know what mechanism you are using for single sign on authentication. But in spirit of microservices and minimal sharing between applications, you could actually put the groups as scopes in your token (if you are using JWT for example). This way the application receiving the token not only knows that the user was authenticated but knows the groups of the user without even making a query to any other system.
This architecture you will have is shown in the picture.
Each use case (service method annotated with #PreAuthorise) will have a role.
Each user will be associated with a number of groups the authentication system will provide. (For example groups in Active Directory). Upon receiving the authentication information of the user, the groups will be mapped to the roles specific to the application and populated in the UserDetails Spring Security object. Each annotated method will then get the application specific roles (not the global groups).
This gives you the flexibility to add as many groups as you like that can have the same application role.

Java EE JDBC Realm

when using a JDBC realm for authorization I usally have this tables:
User table
Role table
Group table
When I now login with username, password the security module makes a lookup in the table: give me all roles for user: username.
Can I somehow hook into the process and add another attribute? E.g.
give me all roles for user: username where UserTable.X = Y ?
Note: I must use pure Java EE
There are some possibilities to achieve the desired behavior.
The easiest solution would not be to customize the login process, but to use a manual lookup using perhaps a #WebFilter or some similar approach.
If you need or want to customize the login process itself have a look at JASPIC (relatively new). In the version 1.1 it is quite usable, but its support depends on the application server you are using. The idea is to write an own login process and pass a custom Principal back to Java EE. Here is a nice collection of links: Zeef
An older approach to customize the login process is to create an application server specific security realm. In other words you are writing or extending the JDBC Realm that is currently used by your application server. You can then also pass a custom security principal back to Java EE.

Get all users and roles in Java webapp

Questions:
Is there a concept of user & role that is general to Servlet Containers?
If so, is there a container agnostic way to access those users and roles?
If not, is there a way to access Tomcat Realm users & roles?
Background:
I would like to either get all users and their roles from the Java webapp context (Servlet Container) or, better yet, query the users and their roles directly.
I see that there are projects like Apache Directory which let you do this for LDAP if you know the connection string. However, I want to be agnostic to the technology serving up the users and roles.
Specifically, I'm on Tomcat and in the simplest scenario want to access the users & roles in a) tomcat-users.xml b) any other configured Realm in the context. However, I am really looking for a solution which isn't specific to Tomcat and it's Realms.
In tomcat(or any other conytainer) (using std. Servlet API), directly accessing of user roles is not possible (without using tomcat/third party specific mechanisms). the getUserPrincipal & isUSerInRole are the two methods, access to the role list is not directly possible.
Since the API does not provision for such an access, I guess you will have to rely on other mechanisms which is container or technology specific.
As you pointed out, if the realm configured is a JNDI realm and the realm store is implemented over an LDAP, it is possible to write a servlet filter and get the roles from the LDAP and set them on session or on a thread local.

Java EE authorization using Roles defined in database, in Glassfish

I want to have authorization in my Java EE application.
Online it describes how you should define the roles in sun-web.xml. However I would like to have all my roles, and groups defined in a database table.
That means, when I access a method for my application, the request needs to be intercepted to see if the user is allowed in the role.
Do I need to
create some kind of interceptor class that checks auth as user makes call to my web service method
create a custom Login Module that fishes out the group and role data from the database when a user first logs on
Any pointers would be really helpful.
First of all: I would strongly suggest using standard authorization mechanisms.
But for your use-case these standard mechanisms won't work, see this post: dynamic roles on a Java EE server
Roles have to be declared in the web.xml or sun-web.xml.
Frameworks
The next thing I would look into are frameworks, that could help you with that. The link will provide you with two suggested frameworks.
Building your own
If you don't need it for productive purposes, I would suggest the following:
use Filters to check for authorization and authentication: Filters a fairly easy to use ,very powerful and often used for security purposes: See http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html for more information about filter.
For the login, you could probably just stick with the standard form-based login.

Best practices implementing Security in multiple Web application

We are using Spring Security and it is working fine in the single web application. Now, I need to create another Web application with Spring security. In the first application the user can sell his/her stuff (e.g. EBay). The second app which I am creating now, it is for general users where he can save his general preferences, searches, save some items he looked at etc. He may/may not be the existing user. So the difference between the two users are:
User 1 (existing user): Can post his stuff for sale.
User 2: He/she should be able to login. Save his general activities etc. & if he/she wants to sell his/her item, he/she needs to go thru the additional steps for verification.
All this cannot be done in just one application due to some reasons. My question is on how to handle the security? Should I create separate security filters for each applications or is there a way to use common security implementation who can manager both of these application. Please provide your feedback, I would really appreciate it.
if you wrap both components in two different webapps, each will have his own spring security web filter infrastructure.
So in principle there will be a security session for each web application, to be backed by whatever authentication system you use.
If you use JDBC then the user would have to login twice.
If you want your customers to only login once, you can for example use a token based system.
When you cross link from webapp 1 to webapp 2, you could hook the links up to a redirect servlet.
The servlet then generates a token, persists it in a database and forwards the user with the token in the url to the other webapp.
In spring security you can then implement your own PRE_AUTH_FILTER which reads out the token, verifies if it is persisted in the Database.
For security reasons you should make these tokens only one use.

Categories

Resources