0

I am a developer working on an application using JSF 2.1 with Primefaces 3.5 extensions and the Spring 3.1 Security framework. I come from a background working on Java Swing applications using Weblogic and EJB's, but am new to Web development.

I have a requirement similar to the solution described in this post. However, my situation requires obtaining the stream to send to the JSF page from a servlet's HttpResponse InputStream. I can make this work under Spring Security by allowing ROLE_ANONYMOUS to execute the servlet. If I add security by way of the Spring config <security:intercept-url> for the servlet's URL and specific roles, I have a problem. When I call the servlet using HttpURLConnection as shown below, the HttpSession for JSESSIONID appears to be invalidated when the HttpURLConnection is closed. The original session obtained from the JSF ExternalContext is not valid in the Spring Security framework during subsequent JSF navigation. I suspect this is by design to prevent session hijacking.

My question is, how can I call a servlet from a JSF backing bean within the context of the current JSF Request's authenticated session in order to get the streamed response to return as the JSF page response?

private InputStream getReportAsInputStream( URL servletUrl ) throws Exception{

    InputStream stream = null;

    ExternalContext exc = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletRequest req = (HttpServletRequest) exc.getRequest();

    // Find JSESSIONID
    Cookie[] cookies = req.getCookies();
    String name = null;
    String session = null;
    for( Cookie c : cookies ){
        name = c.getName();
        if ( _JSESSIONID.equals( name ) ){
            session = c.getValue();
            log.debug("_JSESSIONID: " + session );
            break;
        }    
    }

    if( null == session ){
        throw new Exception( "Session not available to run report" );
    }

    HttpURLConnection conn = (HttpURLConnection) servletUrl.openConnection();
    if( null != name ){
        StringBuilder sess = new StringBuilder( _JSESSIONID ).append( '=' ).append( session ); 
        conn.addRequestProperty("Cookie",  sess.toString() );
    }
    conn.setRequestMethod( "POST" );

    stream = conn.getInputStream();

    return stream;
}
Community
  • 1
  • 1
brobinso
  • 1
  • 1
  • So, as far as I understand, you've got an already implemented servlet which streams a file download and you've got to call it from JSF, is it ok? Why don't you just secure your servlet and implement the download using a link? – Aritz Jul 30 '14 at 05:54
  • There are a lot of servlet parameters that can only be supplied by the JSF backing bean, so calling it directly from the page is impractical. But thanks for your response. – brobinso Jul 30 '14 at 12:00
  • You could always render the desired parameters that already are in the bean in your HTML output. Then generate an url with them. It depends on the case to be possible or not, but that works for the totality of my application reports. – Aritz Jul 30 '14 at 12:04
  • 'Biker, I tried your suggestion of calling the servlet URL from the JSF page and that works as far as passing the session to Spring Security. Thanks for that. However, I find that the AccessDenied exceptions I am seeing seem to be coming from the window I am opening to display a report in Excel. I have no problems with PDF displayed by the browser plugin. I am going to post a question specific to opening an Excel file in JSF. Thanks again for your response. – brobinso Jul 31 '14 at 15:56

0 Answers0