Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access wicket session from Jersey-2 request filter?

In Jersey 1.x we accessed the Wicket session from a (Jersey) session attribute, as described here https://stackoverflow.com/a/15767824/1399659.

In moving to Jersey 2.x it seems the proper pattern to use a ContainerRequestFilter, which also allows Spring bean injection as well. We have this working successfully by including

<param-name>jersey.config.server.provider.packages</param-name>

as an init-param to the ServletContainer and using the @Provider annotation on a ContainerRequestFilter implementation. But this container filter is a singleton, and it's not possible to inject the HttpServletRequest into this (see JERSEY-2114)

In the filter() method we have access to the ContainerRequestContext but can't access the HttpServletRequest from there.

So is there a way to either:

  1. Enable Spring bean injection within a servlet filter (with Jersey too)?
  2. Access the servlet request from within a ContainerRequestFilter?
  3. Access wicket session from Spring-bean-aware object with Jersey filtering ability some other way?

`

import java.io.IOException;

import javax.servlet.http.HttpSession;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;

import org.apache.wicket.injection.Injector;

@Provider
public class SecurityContextFilter implements ContainerRequestFilter {

//@Context
//HttpServletRequest webRequest;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    //HttpSession httpSession = webRequest.getSession();
    //MyWicketSession mySession = (MyWicketSession) httpSession.getAttribute("wicket:" + BaseConstants.WICKET_FILTER_NAME + ":session");
    //doAuthCheck(mySession, requestContext);
}
...
}

`

Thanks in advance

like image 226
Brad M Avatar asked Dec 26 '22 20:12

Brad M


1 Answers

Fixed in Jersey 2.4:

import javax.annotation.Priority;
import javax.ws.rs.Priorities;

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthRequestFilter implements ContainerRequestFilter {
    @Context
    HttpServletRequest webRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        final HttpSession session = webRequest.getSession();

        requestContext.setSecurityContext(new SecurityContext() {
            @Override
            public Principal getUserPrincipal() {
                return new PrincipalImpl((String)session.getAttribute("USER_NAME"));
            }

            @Override
            public boolean isUserInRole(String s) {
                return false;
            }

            @Override
            public boolean isSecure() {
                return false;
            }

            @Override
            public String getAuthenticationScheme() {
                return null;
            }
        });
    }
}

You can also register the filter without using @Provider annotation:

import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.ApplicationPath;

/**
 * Root REST resource class.
 */
@ApplicationPath("/rest")
public class RootResource  extends ResourceConfig {
    /**
     * Initializes all resources from REST package.
     */
    public RootResource() {
        packages("com.example.rest");
        register(AuthRequestFilter.class);
    }
}

Note: Glassfish 4.0.0 uses old Jersey 2.0. You will have to upgrade Jersey using these tips (it's not proven to work well). Or the better way is to download nightly build of Glassfish 4.0.1. but it's not completely stable at the moment. I hope the new version will be released soon.

like image 89
Viacheslav Dobromyslov Avatar answered Mar 08 '23 17:03

Viacheslav Dobromyslov