Question

I am developing a REST API using Jersey 2 and at the moment I am trying to incorporate basic authentication by use of an annotation similar to the @Auth found in Dropwizard. With

@Path("hello")
public class HelloResource {
    @GET
    @Produces("application/json")
    public String hello(@Auth final Principal principal) {
        return principal.getUsername();
    }
}

the hello resource invocation should be intercepted by some code performing basic authentication using the credentials passed in the Authorization HTTP request header and on success injecting the principal into the method principal parameter.

I have started creating an @Auth resolver, see below, but I do not see how I can access the Authorization HTTP request header from within that?

@Singleton
public class AuthResolver {
    public static class AuthInjectionResolver extends ParamInjectionResolver<Auth> {
        public AuthInjectionResolver() {
            super(AuthValueFactoryProvider.class);
        }
    }

    @Singleton
    public static class AuthValueFactoryProvider extends AbstractValueFactoryProvider {
        @Inject
        public AuthValueFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, final ServiceLocator injector) {
            super(extractorProvider, injector, UNKNOWN);
        }

        @Override
        protected Factory<?> createValueFactory(final Parameter parameter) {
            final Class<?> classType = parameter.getRawType();
            return classType == null || !classType.equals(Principal.class) ? null :
                   new AbstractContainerRequestValueFactory<Principal>() {
                       @Override
                       public Principal provide() {
                           // Authentication?
                       }
                   };
        }
    }

    public static class Binder extends AbstractBinder {
        @Override
        protected void configure() {
            bind(AuthValueFactoryProvider.class).to(ValueFactoryProvider.class).in(Singleton.class);
            bind(AuthInjectionResolver.class).to(
                    new TypeLiteral<InjectionResolver<Auth>>() {
                    }
            ).in(Singleton.class);
        }
    }
}

How to approach this? :)

Was it helpful?

Solution

Ah, in AbstractContainerRequestValueFactory<Principal> I can add

@Context private ResourceContext context;

and then extract the HTTP request and it's headers from there inside the provide method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top