Java Security is my main topic for the last couple of weeks and I archive the following:
- Custom Valve Authentificator (
extends AuthenticatorBase) - Custom Login Module for jBoss (
extends UsernamePasswordLoginModule) - Secured Endpoint (JAX-RS)
My major problem is, that my endpoint works only with the annotation @DeclareRoles, if I don’t use it I cant get through authentication. In detail the method AuthenticatorBase.invoke (from org.apache.catalina.authenticator) calls the method RealmBase.hasResourcePermission and there the roles will be checked.
Since I don’t use any predefined roles the check will fail.
My question: Is there any way to use code like that:
@Path("/secure")
@Stateless
public class SecuredRestEndpoint {
@Resource
SessionContext ctx;
@GET
public Response performLogging() {
// Receive user information
Principal callerPrincipal = ctx.getCallerPrincipal();
String userId = callerPrincipal.getName();
if (ctx.isCallerInRole("ADMIN")) {
// return 200 if ok
return Response.status(Status.OK).entity(userId).build();
}
...
}
}
Some additional background: There is the requirement to use a reverse proxy for authentication just the username gets forwarded (X-FORWARD-USER). Thats why I use my own Authenticator class and the custom Login module (I dont have any password credentials). But I think the problem also occurs with standard authentication methods from application server itself
Since your code is static (meaning you have a static set of resources that can be secured), I do not understand your requirement for adding security roles aside from increasing access granularity. I could see this requirement in a modular environment, where the code is not static, in which case you would need to support the additional security roles declared by later deployments.
That said, I had to implement something similar, a security system that supports:
I’ll describe on a high level of abstraction what I did and hopefully it will give you some useful ideas.
First off, implement an
@EJB, something like this:Then you implement a custom
javax.security.auth.spi.LoginModule. I’d recommend implementing it from scratch, unless you know the container provided abstract implementation will work for you, it didn’t for me. Also, I suggest you get familiar with the following, if you aren’t, to better understand what I’m getting to:In order to allow dynamic configuration (i.e. declaring roles, associating users), build a UI that uses that same @EJB
MySecurityDataManagerto CRUD your security settings that the login module will use to determine security roles.Now, you can package these the way you want, just make sure that the
MyLoginModulecan look up theMySecurityDataManagerand that you deploy them to the container. I worked on JBoss, and you mentioned JBoss, so this should work for you as well. A more robust implementation would include the lookup string in the LoginModule’s configuration, which you then can read at runtime from the options map in theinitialize()method. Here’s an example configuration for JBoss:At this point you can use this security domain
mydomainto manage the security of any other deployments in the container.Here are a couple usage scenarios:
mydomainsecurity domain. The .war comes with predefined security annotations throughout its code. Your security realm doesn’t have them initially, so no user can log in. But after deployment, since the security roles are well documented, you open themydomains configuration interface you wrote and declare those roles, then assign users to them. Now they can log in.mydomainand no one will be able to use it.The best part, especially about #2 is no redeployment. Also, no editing XML to override the default security settings declared with annotations (That is assuming your interface is better than that).
Cheers!
I’ll be happy to provide more specifics, but for now, this should at least tell you if you would need them.