I'm working with jersey 2.17 and HK2 to create a simple rest app.
I have a ContainerRequestFilter
that rejects any request that doesn't have the "currentuser" cookie.
I have something like this:
@Path("/users")
public class UserResource {
private UserService userService;
@GET
@Path("/orders")
@Produces("application/json")
public List<Order> findOrdersOfCurrentUser() {
// some ugly code to access headers, extract cookies, and finally
// extract username (a String) from a particular cookie
return this.userService.findOrdersByUsername(username) ;
}
}
I want to code something more elegant than that. Like this:
@Path("/users")
public class UserResource {
private UserService userService;
@CurrentUsername
private String currentUser;
@GET
@Path("/orders")
@Produces("application/json")
public List<Order> findOrdersOfCurrentUser() {
return this.userService.findOrdersByUsername(username) ;
}
}
I'm really new to hk2 and is getting real hard to find the way to do it.
I'm just asking for the right interface to implement (or class to extend).
What you're looking for is not trivially done. One way you could handle this is setting the
SecurityContext
inside theContainerRequestFilter
, as seen here. This doesn't involve any direct interaction with HK2. You could then inject theSecurityContext
in your resource class. And get the user byIf you really want to go with injecting the username with a custom annotation, you will need to create a
InjectionResolver
(See Defining Custom Injection Annotation. You could injectContainerRequestContext
(the same one passed to the filter method in theContainerRequestFilter
) or theSecurityContext
into theInjectionResolver
. For exampleFilter
Annotation
InjectionResolver
Bind the InjectionResolver
Resource
Now I'm not quite sure about this second approach, at least the part about the filter being a
@PreMatching
filter. If I don't make it a pre-matching, theUser
will be null. It seems theContainerRequestContext
does not yet have the property we set, meaning what appears to be happening is the the theInjectResolver
is being called before the filter. I will need to look into this. Making it a pre-matching, IMO should not be required.Personally though, I would go with the first approach, just using the
SecurityContext
. A full example is in the link I provided above. With this approach, you can take advantage of Jersey'sRolesAllowedDynamicFeature
if needed.