I have to say, I'm not 100% certain on this one. When I wrote that gist, I had assumed that Jersey would select a provider based on the type of the injected argument. But reading the code, I'm pretty sure that it wouldn't. So to use my gist, it would appear that you'd need to write a provider that would look at the type provided to getInjectable(), and select the Authenticator to use.
However, now that I know you'd have to write a new provider anyway, I think a better idea would be to use different annotations to select the kind of authentication you would want.
The idea is, if the provider returns null, Jersey will keep looking for a new provider that can do the job. So, create some marker annotations:
@Target(...)
@Retention(...)
public @interface HttpBasicAuth {}
use it, along with @Auth, in your resources:
@GET
public String resourceMethod(@Auth @HttpBasicAuth User user)
{
}
and register derived provider that looks for it:
public class AnnotatedBasicAuthProvider<T> extends BasicAuthProvider<T> {
public AnnotatedBasicAuthProvider(Authenticator<BasicCredentials, T> authenticator, String realm) {
super(authenticator, realm);
}
@Override
public Injectable<?> getInjectable(ComponentContext ic,
Auth a,
Parameter c)
{
if (c.isAnnotationPresent(HttpBasicAuth.class)) {
return super.getInjectable(ic, a, c);
}
return null;
}
}
This would allow multiple providers to be registered and doesn't require multiple user principal types.
Of course, you don't have to use marker annotations to select which methods get which auth type, the provider could use any logic it wanted.
HTH,
Christopher