Search code examples
javarestresteasyrestful-architecturejavax.ws.rs

REST-ful webservice @Context Injection always returns null


I am creating my first Restful web service with Embedded Jetty with authentication and authorization and I have a filter in which I would like to inject a user object (Employee) which then I can retrieve in a service bean using ResteasyProviderFactory.pushContext() the @Context annotation, but whatever I try the object always is null. I would appreciate any kind of help.

@PreMatching
public class AuthenticationHandler implements ContainerRequestFilter {


@Inject private PxCredentialService credentialService;


@Override
public void filter(ContainerRequestContext requestContext) throws IOException {

    Response faultresponse = createFaultResponse();

    String authorization = requestContext.getHeaderString("Authorization");
    String[] parts = authorization.split(" ");
    if (parts.length != 2 || !"Basic".equals(parts[0])) {
        requestContext.abortWith(createFaultResponse());
        return;
    }

    String decodedValue = null;
    try {
        decodedValue = new String(Base64Utility.decode(parts[1]));
    } catch (Base64Exception ex) {
        requestContext.abortWith(createFaultResponse());
        return;
    }
    String[] namePassword = decodedValue.split(":");
    Employee emp = credentialService.getCredentialsByLoginAndPass(namePassword[0], namePassword[1], true);
    if ( emp != null) {
    ResteasyProviderFactory.pushContext(Employee.class, emp);
    } else {
        throw new NullPointerException("False Login");//requestContext.abortWith(Response.status(401).build());
    }

}

@Path( "/people" )
public class PeopleRestService implements credentials {
@Inject private PeopleService peopleService;
@Inject private GenericUserRightsUtil genericUserRightsUtil;


@Produces( { "application/json" } )
@GET
public Collection<Person> getPeople(@Context Employee emp) {

    Employee emp = (Employee)crc.getProperty("Employee");

    return peopleService.getPeople( page, 5 );
}

}


Solution

  • On my understanding, you want an easy way to identify the user who is performing the request in your resource methods. Have you ever considered setting a SecurityContext with a Principal for the request?

    In your filter, if the user credentials as valid, do the following

    final SecurityContext currentSecurityContext = requestContext.getSecurityContext();
    requestContext.setSecurityContext(new SecurityContext() {
    
        @Override
        public Principal getUserPrincipal() {
    
            return new Principal() {
    
                @Override
                public String getName() {
                    return username;
                }
            };
        }
    
        @Override
        public boolean isUserInRole(String role) {
            return true;
        }
    
        @Override
        public boolean isSecure() {
            return currentSecurityContext.isSecure();
        }
    
        @Override
        public String getAuthenticationScheme() {
            return "Basic";
        }
    });
    

    Your resource method will be like:

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response foo(@PathParam("id") Long id, 
                        @Context SecurityContext securityContext) {
        ...
    }
    

    To get the Principal, use:

    Principal principal = securityContext.getUserPrincipal();
    String username = principal.getName();