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;
}