Authenticate against EJB via RESTeasy webservice - authentication

I am trying to setup a REST-webservice with RESTeasy that access EJBs that are deployed on a JBoss 7.1.1.
I've been successful in:
Setting up Beans to be accessed via REST
Configuring SSL for the connection
Setting up a PreProcessInterceptor that uses HTTP Basic Auth to ask the User for his credentials.
Currently I basically just check the credentials hardcoded in the interceptor.
This works to make sure that the User is authenticated, but our Beans query for the name of the currently logged in Principal for some Beancalls like this:
#Resource
private SessionContext context = null;
[...]
String userName = context.getCallerPrincipal().getName();
Currently userName is now always anonymous. What is the right way to set the caller principal? Do I do this in an Interceptor? Or in the Bean itself? My goal is to basically be able to call a method loginUserWithEJBOnJboss(String user, String pass) that uses the login-methods that are configured within the jboss and sets the principal correctly.
I am at a loss here, google didn't find anything. Maybe I am just searching for the wrong words.

So yeah, as always soon after asking I find the solution myself. I think sometimes I only ask because I know this will happen.
So the solution are these methods:
SecurityContextAssociation.setPrincipal(new SimplePrincipal(username));
SecurityContextAssociation.setCredential(password.toCharArray());
They do pretty much all I wanted :)

Related

How do I get Basic Authentication, GlassFish, REST, and a single page application to all work together with my own login form?

I'm using Glassfish 4 as a server with an AngularJS app as a client. Glassfish is exposing a REST API via JAX-RS (Jersey). I'm using Basic Authentication over an HTTPS connection. I have my own login form and am setting the Authorization header in my REST requests via JavaScript. My issue is that if I use normal web.xml based permissions (<auth-constraint> inside <security-constraint>), the responses come back with 401 with a WWW-Authenticate header (if the credentials are bad). This forces the browser to do the Basic Authentication dialog instead of my own and it appears there is no viable cross browser work around available on the browser side to stop it. So I need to somehow suppress the 401/WWW-Authenticate response.
I stopped using the web.xml based permissions, because it seems it is the Servlet level that is doing the 401 stuff. I was able to get Jersey authentication working with a filter and turning on the "RolesAllowedDynamicFeature" feature (in a matter similar to Glassfish #RolesAllowed with custom SecurityContext). That seems to work great and returns 403 for bad credentials (and thus no browser dialog). However, when I call my EJB's, they do not see the custom security context and the user I have set, so I get permission exceptions. If it matters: the EJB's are in a jar, the Jersey stuff is in a war, and both of them and bundled together in an ear. From what I can gather the only way to have the EJB's properly process credentials is to use the web.xml stuff.
I seemed to have painted myself into a corner and do not see how to make this work. Perhaps I can back out and return to using web.xml based permissions and somehow filter the servlet responses to not return 401/WWW-Authenticate? If so I could not find out how to do that. Or is there some way I can set EJB's security context? Or something else entirely? I wouldn't think using AngularJS with GlassFish and a REST API and Basic Authentication would be very unique, how does anyone do this?
Since posting this question I have found info on implementing a Servlet filter and using that to try to change the 401 response to a different status code. However, the filter never gains control if you have <auth-constraint> in your web.xml and the request is not authorized, so that did not help me. I still could not prevent the 401 responses.
But now I think I finally found the answer. I removed the <auth-constraint> tag from web.xml. I changed the Servlet filter to now extract the AUTHENTICATION_HEADER on its own and decode it (via javax.xml.bind.DatatypeConverter). Next I call HttpServletRequest.login (on the request object) with the decoded username and password. I catch the ServletException if the username/password combination is bad and use HttpServletResponse.sendError to send SC_FORBIDDEN. If I have a good login I call doFilter to continue on with processing of the request, and call HttpServletRequest.logout when it returns.
If I do this in combination with RolesAllowedDynamicFeature and annotations on the Jersey routines everything seems to work including calls to EJB's with their own security annotations.
Side note: before settling on HttpServletRequest.login I had tried to use HttpServletRequest.authenticate followed by checking the returned boolean, but when you gain control in that case the response has already been committed to be 401 and you cannot change it. I even tried passing a HttpServletResponseWrapper to authenticate to stop the commit from happening, but authenticate seems to get the response object through some other means, it seems to ignore the one you pass it (I even tried passed null and it didn't even notice).

Restful Web service Authentication and Authorization with Apache Shiro

I am able to authenticate web based application using apache shiro through databases using JDBC relam. Further more, I am successively able to make the use of Shiro-Filters to grant access for particular web-resource or http urls using Shiro filter configuation in web.xml and configuration into shiro.ini.
Now, I want to implement the same functionality for the webservices too. In Particular, I want user to hit the login-url for getting the token, if the credentials are valid. And after that, all the successive requests for the webservices has to be validated based on that particular token for the user.
I have no any clue to implement this. Any suggestions, procedures, or suggestive links could help me alot !!
I suggest you to use jersey web framwork since it's very simple, in java and annotated!
You specify your uri's, roles, permission in shiro.ini as you know and after that make a web project on jersey.
After that the use in a java code is clear and simple! See how to retrieve
Code in jersey :
/**
* login to app
* #param username
* #param password
* #return
* since v0.6.4
*/
#PUT
#Path("login")
#Produces({"application/json"})
public Response loginv3(
#FormParam("username") String username,
#FormParam("password") String password){
return login(username, password);
}
In this case we will retrieve the books only if are a user connected and that we have "reader" role :
#GET
#Path("/books")
#Produces({"application/json"})
#RequiresUser
#RequiresRoles("reader")
It's realy easy! See the shiro documentation : shiro annotation reference
This mecanic is implemented by shiro, the token is passed to the browser and is stored as a cookie on the client navigator. After that shiro will pass the token on each connection to the service thrue the browser.
Try first to have authentication propaged true your application : authen shiro doc
Please implement the shiro Step by Step project in order to validate the concepts of Authentication and of Autorization ! :)
Give me some feedback please. Enjoy it :)
user authentication with shiro is show in shiro example on GIT. Simply fork this git to have it working.
Shiro is passing a cookie in order to keep the connection alive! :) The transfert of the cookie is managed by shiro, you won't have to think of it.
enjoy :)

spring security jmx authneticator

I have a JMX server configured without Spring and am trying to implement Spring Security for the Authorization part.
(See here, https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization
Use Case 4, without the Authorization part)
I would like now to implement the Authorization part using Spring Security.
In my JMX authenticator, I do:
final List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
roles.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
final Authentication auth = new UsernamePasswordAuthenticationToken(credentialsArr[0], credentialsArr[1],
roles);
SecurityContextHolder.getContext().setAuthentication(auth);
And in the MBeans I try to fetch it and see that it has been passed correctly (in the future I plan to add Spring Annotations to check for roles, for method invocation).
final Authentication springAuth = SecurityContextHolder.getContext().getAuthentication();
The problem is, that in the standard connection flow:
JMXServiceURL url = ...;
Map env = ...;
String[] creds = {"monitorRole", "mrpasswd", "FileRealm"};
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector cc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
I get a JMX connector, then connect to the MBean server and invoke a method - it works.
I get through the authenticator, set the Spring Context and get it in the Mbean.
But when I connect using a Jconsole, for example, I don't get the Spring Context in the Mbean.
I am using the Inheritable Thread strategy.
Is there a way to get the context also in the MBean, when connecting using the JConsole and other connectors?
If I implement JMX using Spring, will it help me to solve the problem?
Is my main flow fool proof (is there a chance I will not get the Context in the MBean)? I am asking this, since this flow is critical to me, to be fool proof.
Thanks a lot!
I will answer my own question, as I've seen interest in it and wanted to share my own conclusions (unrelated to the numbers above):
It looks like connecting with JConsole(or JVisualVM) locally (i.e. to localhost) connects directly to the thread, without going through the JMX Authenticator.
The only workaround I found was by connecting with a full URL (e.g. service:jmx:rmi:///jndi/rmi://10.45.32.112:3251/jmxrmi).
One mechanism that works always is the Java Security context; when JMXAuthenticator returns a Subject, you may assign the Spring Security Context to it and thus surely get it when invoking the method (e.g. in an Advice running before the invocation).
See this reply I got:
http://forum.springsource.org/showthread.php?134327-JMX-Authentication-with-Spring-Security-%283-1-x%29
I can't say for sure if the flow mentioned in the question is fool proof.
But it seems like it is, based on this assumption:
If you create a new connection for each JMX call and use it only for one invocation, you will get the Spring Security Context to propagate correctly.
Hope it helped you people :-)

LdapAuthenticationProvider not checking if user is not active

I can auth my website with either ldap or by looking in db using different spring security authentication providers.
When i use the database auth, i use UserDetailsService, which correctly checks if my user is notActive and throws DisabledException correctly.
but using LdapAuthenticationProvider this does not occur. why?
spring security 2.0.1
Which LdapAuthenticator are you using? If you use BindAuthenticator it will bind as the given user, eventually the directory server should reject if the user account disabled/expired.
I haven't used LdapAuthenticationProvider myself, but if its not done automatically you can retrieve the userdetails, The UserDetails class has bunch of methods to check weather the account is enabled/locked/expired.

How to execute a function immediately after authentication

My question is this: With a web application, after performing a login authentication for a protected resource, how can I run some sort of function (in this case, I want to run a function to initialize some user-dependent session-scope variables) BEFORE the web-app redirects to the protected resource.
I am programming a web application using servlets and JSP's, all within the struts framework. I believe I have followed the correct JAAS or J2EE standards for security.
In other words, I have configured the web-application via the web.xml file to redirect all requests for protected material to a login form that asks the user for login information. It then submits to j_Security_check which performs the authentication and authorization before redirecting the user to the protected materials.
So, I need to run a function sometime just after the web application says "yes, this person is who they say they are" and before the web application shoves them at where they want to go.
Hope you can help me. Thanks in advance.
If you use serverside sessions:
Create a servlet filter
In the filter: See if an attribute in the session has been set
If not: Check if user is authenticated and perform your operation if they are. Then set the attribute in the session
Thus, the operation will be executed only once.