

How to avoid basic authentication when session has expired in JasperServer 5.5.0
Recently I had an issue with our clients in which they complained about showing a basic authentication popup window when the session is timeout and the user changes the values of the input controls in order to execute a report. I have decided to implement a solution in which when this event occurs the user will be redirected to the login page avoiding the basic authentication.
First I needed to find out where in the project is used basic authentication. The easiest way is to search for string “WWW-Authenticate” which according to the standard must be included in the HTTP request header. The result after the search was one – ForbiddenEntryPoint.java. The definition of the class is:
public class ForbiddenEntryPoint implements AuthenticationEntryPoint { public final String SUPPRESS_BASIC_HEADER = “X-Suppress-Basic”; public final String HTTP_WWW_AUTHENTICATE_HEADER = “WWW-Authenticate”; public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; if (!”true”.equalsIgnoreCase(httpRequest.getHeader(SUPPRESS_BASIC_HEADER))){ httpResponse.setHeader(HTTP_WWW_AUTHENTICATE_HEADER, “Basic realm=\”Protected area\””); } httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); } }
The basic authentication popup window will appear if in the header of the request the value of “X-Suppress-Basic” is NOT “true”, otherwise the response will be with status code 401(httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());) which means the authorization has been denied. Now we have to find out where in the project is generated the request from the input controls of the report. After debugging a couple of hours with the help of the “Developer tools” in Chrome I found out that the file which I need is controls.datatransfer.js
First we need to add “X-Supress-Basic” with value “true” so we will modify the sendRequest function to look like this:
sendRequest : function(url, data, settings) { var defaultSettings = { url : url, type : “GET”, dataType : “json”, cache : false, headers : {‘X-Suppress-Basic': ‘true’} }; if (!_.isEmpty(data)) { _.extend(defaultSettings, { type : “POST”, processData : false, data : JSON.stringify(data), contentType : “application/json” }); } return jQuery.ajax(_.defaults(settings || {}, defaultSettings)). fail(commonErrorHandler); }
Only the red line is the modification.
Now we need to handle the response which will be with status code 401. The modification is in the commonErrorHandler function.
function commonErrorHandler(err) { try { try { var errorObject = jQuery.parseJSON(err.responseText); } catch (e) {} if (errorObject && errorObject.error) { _.each(errorObject.error, function (error) { //TODO: try to avoid it var viewModel = Controls.getViewModel(); var controlUri = error.inputControlUri.replace(“repo:”, “”); var control = viewModel.find({uri:controlUri}); if (error.errorCode) { control.set({error:error.errorCode}); } else if (error.defaultMessage) { control.set({error:error.defaultMessage}); } }); } else { if (err.getResponseHeader(“LoginRequested”) || err.status == 401) { document.location.href = ‘login.html'; } else if (err.status == 500 || (err.getResponseHeader(“JasperServerError”) && !err.getResponseHeader(“SuppressError”))) { var message = “”; if (errorObject) { message = Mustache.to_html(“<div><b>{{message}}</b></div><p>{{#parameters}}<div>{{.}}</div>{{/parameters}}</p>”, errorObject); } else { message = statusText; } dialogs.errorPopup.show(message); } } } catch (e) { // In this scenario security error is handled earlier, in errorHandler, so we can ignore exception here. // Comment this because it will not work in IE, but can be uncommented for debug purpose. // console.error(“Can’t parse server response: %s”, “controls.core”, err.responseText); } }
Again the modification is red. So if we receive status code 401 the user will be redirected to the login page.