Welcome file ignores security constraint
-
01-06-2021 - |
Question
my web.xml:
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<welcome-file-list>
<welcome-file>/secured/secure.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>jdbc-realm</realm-name>
<form-login-config>
<form-login-page>/public/login.xhtml</form-login-page>
<form-error-page>/public/error.xhtml</form-error-page>
</form-login-config>
</login-config>
I want my web app to redirect unauthorized users to login page. The funny thing i had this working but i made some stupid changes and now on accessing localhost:8080
i always see secure.xhtml even when not logged in. localhost:8080/secured/secure.xhtml
redirects fine.
Solution
You are not using <welcome-file>
entirely correctly. It should represent the sole filename of the file which needs to be served whenever a folder is been requested, irrespective of the requested folder (the root /
, or /public/
or /secured/
, etc).
The welcome file is served by an internal forward as performed by RequestDispatcher#forward()
. Internal forwards do not trigger the security constraints. You need to send a redirect instead.
Change the <welcome-file>
to a more sane default, e.g. index.xhtml
.
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
And create one in the webapp's root like /index.xhtml
. If you need to redirect every request on /index.xhtml
to /secured/secure.xhtml
, then there are basically 2 ways:
Map a
Filter
on the URL pattern of/index.xhtml
and callresponse.sendRedirect("secured/secure.xhtml")
inside thedoFilter()
method. E.g.@WebFilter("/index.xhtml") public class IndexFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.sendRedirect("secured/secure.xhtml")); } // ... }
Put a
<f:event type="preRenderView">
in the/index.xhtml
which calls a backing bean method which in turn does aexternalContext.redirect("secured/secure.xhtml")
. E.g.<f:event type="preRenderView" listener="#{indexBean.redirect}" />
with
@ManagedBean @ApplicationScoped public class IndexBean { public void redirect() throws IOException { FacesContext.getCurrentInstance().getExternalContext().redirect("secured/secure.xhtml"); } }