java - Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same -
i using jsf2. have implemented custom faces servlet so:
public class myfacesservletwrapper extends myfacesservlet { // ... }
wherein i'm doing authorization checks , sending redirect when user not logged in:
public void service(servletrequest request, servletresponse response) { httpservletrequest req = (httpservletrequest) request; httpservletresponse res = (httpservletresponse) response; if (...) { string loginurl = req.getcontextpath() + "/loginpage.faces"; res.sendredirect(loginurl); } }
this works when user tries navigate page. however, not work when jsf form submitted jsf command link/button. line sendredirect()
line hit , executed, no exception been thrown, user stays @ same page. basically, there's no visual change @ all.
why work on page navigation, not on form submit?
your concrete problem caused because jsf command link/button sending ajax request in turn expects special xml response. if you're sending redirect response ajax request, re-send ajax request url. in turn fails without feedback because redirect url returns whole html page instead of special xml response. should returning special xml response wherein jsf ajax engine been instructed change current window.location
.
but you've bigger problems: using wrong tool job. should use servlet filter job, not homegrown servlet , sure not 1 supplants facesservlet
responsible jsf works.
assuming you're performing login in request/view scoped jsf backing bean follows (if you're using container managed authentication, see 2nd example of performing user authentication in java ee / jsf using j_security_check):
externalcontext.getsessionmap().put("user", user);
then kickoff example of filter should do:
@webfilter("/*") // or @webfilter(servletnames={"facesservlet"}) public class authorizationfilter implements filter { private static final string ajax_redirect_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<partial-response><redirect url=\"%s\"></redirect></partial-response>"; @override public void dofilter(servletrequest req, servletresponse res, filterchain chain) throws servletexception, ioexception { httpservletrequest request = (httpservletrequest) req; httpservletresponse response = (httpservletresponse) res; httpsession session = request.getsession(false); string loginurl = request.getcontextpath() + "/login.xhtml"; boolean loggedin = (session != null) && (session.getattribute("user") != null); boolean loginrequest = request.getrequesturi().equals(loginurl); boolean resourcerequest = request.getrequesturi().startswith(request.getcontextpath() + resourcehandler.resource_identifier + "/"); boolean ajaxrequest = "partial/ajax".equals(request.getheader("faces-request")); if (loggedin || loginrequest || resourcerequest)) { if (!resourcerequest) { // prevent browser caching restricted resources. see https://stackoverflow.com/q/4194207/157882 response.setheader("cache-control", "no-cache, no-store, must-revalidate"); // http 1.1. response.setheader("pragma", "no-cache"); // http 1.0. response.setdateheader("expires", 0); // proxies. } chain.dofilter(request, response); // so, continue request. } else if (ajaxrequest) { response.setcontenttype("text/xml"); response.setcharacterencoding("utf-8"); response.getwriter().printf(ajax_redirect_xml, loginurl); // so, return special xml response instructing jsf ajax send redirect. } else { response.sendredirect(loginurl); // so, perform standard synchronous redirect. } } // ... }
Comments
Post a Comment