0

I am trying to use RESTEasy with undertow. First I tired the UndertowJaxrsServer source but figured out it is directly using the PathHandler. So I drove another class inheriting from the PathHandler and changed the UndertowJaxrsServer to use that class.

Here is the handleRequest Method in the new Handler I driven from PathHandler

@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
if (exchange.isInIoThread()) {
    exchange.dispatch(this);
    return;
}
boolean processed = exchange.getQueryParameters().get("INSPECTED") != null;
if (!processed) {
    exchange.addQueryParam(REQUEST_INSPECTED_PARAM, "T");
    String path = exchange.getRequestPath();
    if (!path.endsWith("/users/authenticate")) {
    String token = exchange.getRequestHeaders().getFirst("TOKEN");
    if (!AppUtil.isNullOrEmpty(token)) {
        try {
        User user = ServiceLocator.SECRUTIY_SERVICE.validateToken(token);
         exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY).getServletRequest()
         .setAttribute("USER",  user);

        super.handleRequest(exchange);
        return;
        } catch (Exception e) {
        logger.warn("handleRequest(HttpServerExchange) - exception ignored", e);
        }
    }
    exchange.setResponseCode(HttpResponseCodes.SC_FORBIDDEN);
    exchange.endExchange();
    return;
    }
}
super.handleRequest(exchange);

} }

This is the resource doing the authentication

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Formatted
public class Users {
    @Context
    HttpServletRequest request;
    @Context
    HttpServletResponse response;

    @POST
    @Path("/authenticate")
    public String authenticate(@FormParam("username") String username, @FormParam("password") String password) {
    return "{\"token\":\"" + ServiceLocator.SECRUTIY_SERVICE.authenticate(username, password) + "\"}";
    }
}

The client should call the authenticate then obtain the token to be used with the next calls.

My questions are

  1. I need to analyse the Token to get the logged in user and then pass it in the HttpRequest so that the Resources can easily access it. Iam doing this by this code

    exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY).getServletRequest() .setAttribute("USER", user);

But it throwing NPE, as exchange.getAttachement() is returning null.

  1. I noticed that the MyHandler is invoked twice (before and after serving the request) I need to do my logic (analysing the token) only one time. I am setting a flag in the request parameters to do so, but I am not sure this is the correct way.
Amr Eladawy
  • 4,193
  • 7
  • 34
  • 52

1 Answers1

0

Well, this is a workaround,

public class MyTSA implements ThreadSetupAction {

private static final Logger logger = LoggerFactory.getLogger(MyTSA.class);

@Override
public Handle setup(HttpServerExchange exchange) {
if (exchange == null)
    return null;
    String token = exchange.getRequestHeaders().getFirst(TOKEN_HEADER_PARAM);
    if (!AppUtil.isNullOrEmpty(token)) {
    try {
        User user = ServiceLocator.SECRUTIY_SERVICE.validateToken(token);
        exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY).getServletRequest()
            .setAttribute("USER", user);

    } catch (Exception e) {
        logger.warn("setup(HttpServerExchange) - exception ignored", e);
    }
}
return null;
}}

Before that, while creating deployment info, pass new instance of this Thread Setup Action to the deployment info.

DeploymentInfo di = ....

di.addThreadSetupAction(new MyTSA());
Amr Eladawy
  • 4,193
  • 7
  • 34
  • 52