I want to pass authentication information to EJB stateless session beans when calling their methods from a Java web application (Wicket). The information consists of a user id and an authentication type (remember cookie or user/password) and is stored in the http session. One obvious solution is to add this as a parameter to all EJB methods, but this is cumbersome and I hope another solution exists.
The JNDI lookup of EJB beans is done via javax.naming.InitialContext#lookup(String) in the web tier.
Is there a portable way to add the authentication information to a calling context so it becomes available to the beans? I need this process to be available for callers both in the EJB layer (for an eventual web service endpoint) and in the web tier.
Some more information
I am using Java EE 6. CDI is not used and I would rather avoid implementing it.
Authentication is handled by the web tier with stateless beans validating remember cookies and user/password combinations. When a visitor first accesses the site, authentication with the remember cookie is tried. When eventually required, the user is asked to login with a username and password. As mentioned above, the authentication status is stored in the http session. I don’t use the Java EE security model based on realms because I couldn’t figure out how this authentication flow could be properly integrated.
The authorization scheme is based on dynamic roles similar to how Facebook determines authorization based on the link between 2 users and some preferences. Some actions also take into account the authentication type. For instance, modifying account settings requires user/password and the cookie is not enough. From what I understood, the Java EE standard groups and roles are not a good fit for this requirement.
Other related questions I found
EJB3 & How JAAS subject/principal is propagated to EJB Tier from servlet container?
Controlling the security Principle passed on a EJB call
Binding a User entity and a GlassFish Principal
Accessing the clients principal inside an ejb method
dynamic roles on a Java EE server
I hope my question is clear enough. If more information is required, I will gladly provide it.
edit
Fixed links. Add note about CDI.
I think you should consider:
Creating an interceptor for the authorization process. It will give you a common place for authorization despite from which layer the call was made from. You might check if the caller is allowed to invoke the method or if his session is still active (i.e. check it in the DB).
In the interceptor you could pass some user-related data using InvocationContext#getContextData().put("user-related-data-name", someObj). In the caller EJB you can get this data using SessionContext#getContextData().
An example of passing contextual data using SessionContext can be found here
The last (and most interesting part) would be how to get the user credentials on the EJB layer. If you're saying about WebServices endpoint than I guess you need to provide some kind of boundary class or specify a methods which will take some sessionId for each call.
If it's about propagating HttpSession data from the Servlet to the EJB... It might be a long shot but I would think of using the CDI. Your Servlet might use a #SessionScoped bean which holds the user credentials and you inject the same #SessionScoped bean inside the interceptor.
I'm not sure if it's possible at all (injecting CDI beans in the interceptors or sharing #SessionScoped between Servlets and EJB's layers).
Related
I'm new to Web API, HTTP and security in general, but I just want to know if this is possible: for a controller to relax security requirements when the HTTP request originated from within the local area network.
My particular application has very low security requirements for clients inside the firewall. For instance, I want internal client apps to be able to make requests of controller actions marked with [AllowAnonymous] so that they don't need to deal with OAuth, etc (which just seems like complete overkill for my internal use scenario).
However, if the same controller actions are available to the public Internet, of course strict security requirements should apply.
Can security be handled differently based on origin? Or is the standard practice to expose both a public-facing and an Internal API?
When you use the [AllowAnonymous] attribute on your controller or action, you tell ASP.NET that it should not check the user's identity at all. That is not what you want for users coming from the internet.
You could remove the [Authorize] attribute from your controller and manually check inside the action if the user is authenticated using:
if (User.Identity.IsAuthenticated || IsLocalUser())
{
// action implementation
}
You can implement this check in a custom authorization attribute.
This still leaves you with the task to determine whether the user is local or coming from the internet. You could check the client IP-address to determine this of course.
Another option would be to enable both Windows authentication and bearer scheme authentication if your local users are part of an Active Directory domain.
Users from your intranet could use Windows authentication to talk to the service, while internet users need to bring a JWT token. This would only work if the client application for users coming from the internet is different than for local users.
DISCLAIMER: I've never tried this last option.
Identifying a request as one from "inside the firewall" isn't always as simple as just investigating the IP address. Although, this may work for you now, it may make it difficult to move environments or modify the environment without affecting application logic.
I would recommend developing a simple middle layer application that simply has the job of calling your main application with enough authorization data to handle security in the same context as your regular app, but this middle layer would in itself not be authorized. You will then just have to make sure that this app is not accessible to users outside of the firewall.
I would like to use javaee security, but I need to authenticate users against an external proprietary authentication mechanism, which is different from LDAP and any other standard mechanisms coming with Wildfly. In particular, I would prefer if the authentication is taken care of by the application, not by the container. I only have come across PolicyConfiguration. But I think that it implies buiding an extension to be plugged into the underlying application server.
What I would like is to let application server obtain credentials in a standard javaee way, then execute a callback into the application in order to authorize them, and then establish current user together with his roles, so that I may use declarative security using annotations.
Is this possible in standard way? Or the only solution is to build an extension module for the application server?
An not so elegant solution would be to perform the login using HttpServlet.login. You still need to configure a realm that would acknowledge the username and password you provide in the method call.
Another, more complex, solution would be to create an JASPIC authentication provider. In short, you are in charge of the whole authentication process. Here is a collection of resources to get you started: Zeef
I want to develop a jsf web application like shopping cart and must have to login before shopping. How can i tracking each user session. What will be the best way in this situation. Track session in presentation layer (HttpSession) or Stateful Session Bean in server side.
thanks in advance
Generally when using EJB Statefull session bean there is thought of to try having somekind of state management needed between same client calls and client is not http/https based. Ideally these should not be used client should manage its own state not service.
User sessions are better kept in war using http session management not in ear/ejbs.
I am trying to use Shiro for securing my JSF app. After having a brief look at Shiro I am confused whether JSF applications really need the sessions management facility provided by Shiro. Since JSF already creates sessions when responding to sets of requests received, will using Shiro create (extra!?) session instances for the authenticated users ??
I am worried that if I am configuring Shiro for a jsf app then does it create the extra session instances(i am worried since jsf already gives me that & I dont want session instances through shiro)
As far as I know, Shiro by default use the sessions created by the web container. You can configure it to use it's own session management, but I don't think it's necessary in a web app.
Shiro's session management is useful in situations where you don't have a session management facility already (like desktop apps).
I was wondering if it was possible to have a Java EE application with multiple JAAS security realms.
I'm currently developing an application in which some users need to be authenticated with data stored in a database, while other users need to be authenticated through an LDAP bind.
So I created 2 security realms in glassfish 3.1, a JDBC realm and an LDAP realm and configured my web.xml to use the LDAP realm (most users are LDAP).
I then use :
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
request.login(username, password);
to authenticate user
is it possible to switch to JDBC realm before calling 'request.login' ?
thanks in advance
Have you seen this?
Cross-Domain Single Sign-On Authentication with JAAS
http://www.devx.com/security/Article/28849/1954
I have seen somewhere that you can configure to use two realms or two methods in one realm, that if the first fails it will try the second. I dont know where I saw it sorry. Perhaps that will point you in the right direction.
You must program your custom JAAS login module that try authenticate in method and if is not work try method B.
In you application is transparently all works in the JAAS login module.