Is there any way to extend the authentication operation which connects a client application to an EJB, using standard JAAS/container-based security? I'm looking for a way to use more than just a username to authenticate the user (in this case a domain name is also needed). Ideally I'd like to be able to use the SessionContext.getCallerPrincipal() to get access to both the username and the domain name in the EJB.
I'm using Glassfish, if that influences the answer at all. Do I need to create a custom login module/custom realm and what should it do?
Adding authentication mechanisms to an EJB Container is usually a vendor specific task. I don't believe there is a standard way to do it. For Glassfish though, I believe this article will help you set up a SAM (Serve Auth Module) that can handle the authentication in any way you need. http://blogs.oracle.com/enterprisetechtips/entry/adding_authentication_mechanisms_to_the
Keep in mind this is Glassfish specific.
Related
What I'm trying to do is to create an application with Angular frontend and Spring Boot backend with OAuth2 authentication.
The issue is that I don't know how to get on the frontend the ROLES user has so that I'll be able, for instance, to show something role-based on the page. Yes, there are scopes that OAuth provides in the response but the problem is that these scopes are for the CLIENT but not for the specific USER itself. And that CLIENT is my frontend side (correct me if I'm wrong) which basically means that every user operating my application(client) going to have the same scopes(roles). Moreover, I can specify roles on the backend with the help of Spring and UserDetailsService and then use those roles with #PreAuthorize, etc. But not on the frontend side.
Just as an example, if I simply used single JWT then with a token itself I'd return both the username and roles to frontend. And then I could store that data and use it on the frontend side according to my needs.
So what I'm asking is if it's actually possible and if this is correct to do so?
And how can I possibly implement such behavior?
OAuth doesn't solve this problem and it is best solved via claims in your API. OAuth should deal with authentication only. My below post may help you to think about the best separation: https://authguidance.com/2017/10/03/api-tokens-claims/
In a nutshell you will have to look up user rights such as roles after the OAuth processing completes.
There is a great video from Spring developer on YouTube about OAuth2/OpenID Connect. It shows how to implement the resource server using the newest Spring Security 5 solution.
Probably the easiest and the best way to achieve this is to use an OpenID Connect server which will provide all user management stuff. On the market there are many solutions. Auth0 and Okta are Identity Clouds which provides their services for small amount of money. On the other hand you have Keycloak, which is a server which you can install in Docker or even on bare metal - it's free and open-source.
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.
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.
I have my company resource for authentication, since this is part of its security policy.
Basicly, it works this way: requesting a desired url, we receive a login/password prompt for authentication. Since we've been validated, the server returns a bean filled with some session attributes which we can inspect and programatically render components and/or grant access for a requested page.
I'm looking for some way to work with this scenario along with Glassfish Security (JEE7 roles and groups), so I can delegate the access control indirectly and use EJB for access control instead of the progamatically way.
Does anyone knows how can I do it? I also appreciate any book, site and/or link addressing to this scenario.
Thanks in advance.
I'm working on an existing j2ee app and am required to remove some vendor specific method calls from the code.
The daos behind a session facade make calls into the ejb container to get the user's id and password - in order to connect to the database. The user id and password part of the initialContext used to connect to the server.
I am able to get the userid using sessionContext.getCallerPrincipal()
Is there anyway to get to the SECURITY_CREDENTIALS used on the server connection or, is there a way to pass information from the server connection into the ejbs (they are all stateless session beans).
This is a large app with both a rich-client and web front end, and in a perfect world I'd be happy to go back and re-architect the entire solution to use J2EE security etc - but unfortunately, that is not realistic.
I can't give you a generic solution, but this is what has worked for us. We have the app server connect to LDAP as a specific user that has the ability to request credentials for other users. Then we have some generic security code that we can use to request a users credentials from inside the session beans, based on the users identity from their initial login (just as you are doing it via getCallerPrincipal()).
We also place the users identity in a thread local variable, so that classes down the call chain from the EJB do not have to be "container aware". They simply access the identity from the thread local and use the security classes to look up user profile information. This also makes it easy to change the implementation for testing, or even something other than LDAP lookups.
Other conveniences we created were a JDBCServiceLocator that retrieves connections with user/password for the current user. So the developer does not have to explicitly code the security lookups at all.
Normally the Java EE security model will not allow the retrieval of the user password, for security reasons. But it depends on the implementation. Some vendors provide methods to retrieve this kind of information, but if you rely on such implementations, be aware that the portability of the application will be compromised.
One common approach is to write a servlet filter to intercept the login request and save a copy of the credentials, to be used later. If your application doesn't use the Java EE security infrastructure, this could be easily implemented. That's because some vendors prevent you from filtering an authentication servlet.
Robin,
Sounds like what I was planning. I figured I'd make a call right after a successful server connection to load the credentials into a threadLocal variable on my connection class. I was hoping there was an easier way - but I guess not.