Reputation: 2062
in my JSF application I throw a java.lang.SecurityException
when the user is not logged on. In the web.xml
I redirect to login.jsf
when a SecurityException
ocurrs.
Now my problem is that when I look in to the server response, it is a 500 - Internal Server Error
. Can I somehow throw the SecurityException
and say it should be a 401
?
Thanks
Upvotes: 2
Views: 1802
Reputation: 1108762
When an exception bubbles up all the way to the servlet container and arrives as an unhandled exception, then it's per definition always a HTTP 500 error. You can't change that part.
You can however control that by catching and suppressing the specific exception somewhere and then explicitly invoke HttpServletResponse#sendError()
, passing the desired 4xx/5xx status code.
On synchronous requests, most sensible place for that would be a servlet filter.
try {
chain.doFilter(request, response);
}
catch (SecurityException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
}
Note: if it's not a RuntimeException
, catch ServletException
and inspect its getRootCause()
instead. See also a.o. How does server prioritize which type of web.xml error page to use?
On asynchronous (Ajax) requests, you do however need an additional custom exception handler. See also a.o. Exception handling in JSF ajax requests. This is of course only relevant if you perform the login via Ajax.
Or, if you already have a servlet filter in place wherein you perform authorization, then just perform sendError()
instead of throwing SecurityException
. Provided that your authorization filter look like as the one in How implement a login filter in JSF?, then just replace the redirect in the bottom by:
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
Either way, it will end up in the error page associated with <error-code>
of 401.
<error-page>
<error-code>401</error-code>
<location>/WEB-INF/errorpages/unauthorized.xhtml</location>
</error-page>
Upvotes: 7