I've got a Jersey API that's protected by Shibboleth, an SSO implementation. Shibboleth puts the id of the logged-in user in a request attribute. On the back end, I'm using Shiro for authorization. Shiro would like to know the logged-in user so it can load up permissions.
What is the correct way to get that userId out of the request attribute and into Shiro? Right now, what I'm trying is:
@Provider
public final class ShiroLoginFilter implements ContainerRequestFilter {
@Context
private HttpServletRequest request;
@Override
public void filter(final ContainerRequestContext requestContext)
throws IOException {
final String userId = (String) this.request.getAttribute("nameid");
final Subject subject = SecurityUtils.getSubject();
subject.login(new LocusAuthenticationToken(userId));
}
}
Unfortunately, due to JERSEY-1960, I can't inject the request context into a filter. Every user needs to "login" in order to load permissions. I'd rather not have to repeat the login code in every method of the API. I am also not permitted to use a web.xml filter (by my boss). Do I have any good option here?
ContainerRequestFilter this is an interface and should be implemented by the container request filters. We should annotate the filter class that implements this interface with @Provider so that the JAX-RS runtime will discover this filter. As always, this annotation is sufficient and there is no other configuration required in web.xml
These filters work in the same way as server filters, and the interfaces we have to implement are very similar to the ones for the server side. Let's see it in action with a filter that adds a property to the request: Let's also create a Jersey client to test this filter:
filter(ContainerRequestContext requestContext) Filter method called before a request has been dispatched to a resource. Method Detail filter void filter(ContainerRequestContext requestContext) throws IOException
Implementing a Request Server Filter Let's start with the filters on the server side and create a request filter. We'll do that by implementing the ContainerRequestFilter interface and registering it as a Provider in our server: This simple filter just rejects the requests with the language “EN” in the request by calling the abortWith () method.
You should also be able to obtain ServletRequest
attributes directly from ContainerRequestContext
via ContainerRequestContext#getProperty as described in the JavaDoc of the method:
In a Servlet container, the properties are synchronized with the
ServletRequest
and expose all the attributes available in theServletRequest
. Any modifications of the properties are also reflected in the set of properties of the associatedServletRequest
.
Note: Injecting HttpServletRequest
should work as expected since Jersey 2.4 (released in 10.2013).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With