0
votes

I want to prevent direct access to *.xhtml files in my project. In pages, there are commandLinks which calls some methods of some beans. Those beans return the name of view as string.

return "campaign.xhtml?faces-redirect=true";

If user writes to the address bar of browser the following, I don't want the user to see the xhtml file.

http://localhost:8080/myApp/faces/campaign.xhtml

or

http://localhost:8080/myApp/faces/campaign.xhtml?faces-redirect=true

Because, in some beans, I fill these xhtml views. However, if user directly accesses to the xhtml file, user sees these views without the filled information.

When I use in web.xml file, access is denied. However, in this case, when the bean returns the value "campaign.xhtml?faces-redirect=true", it can not also show the view too. The access is denied for the bean too.

What can I do to prevent this?

Thanks.

Faruk Kuşcan

2

2 Answers

5
votes

user sees these views without the filled information.

Just check in preRenderView event listener if the information is filled or not. If not, redirect back.

<f:event type="preRenderView" listener="#{bean.init}" />

with

public void init() throws IOException {
    if (information == null) {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        externalContext.redirect(externalContext.getRequestContextPath() + "/otherpage.xhtml");
    }
}

You could if necessary combine it with FacesContext#isValidationFailed() if you're actually also using <f:viewParam> with validation. E.g.

<f:viewParam name="id" value="#{bean.information}" required="true" />
<f:event type="preRenderView" listener="#{bean.init}" />

with

public void init() throws IOException {
    FacesContext context = FacesContext.getCurrentInstance();
    if (context.isValidationFailed()) {
        ExternalContext externalContext = context.getExternalContext();
        externalContext.redirect(externalContext.getRequestContextPath() + "/otherpage.xhtml");
    }
}

Update: in JSF 2.2, you can use <f:viewAction> for this.

<f:viewAction listener="#{bean.check}" />
public String check() {
    if (information == null) {
        return "otherpage?faces-redirect=true";
    } else {
        return null;
    }
}
-1
votes

In your case you need to map some pattern to your xhtml files in order to access them from the URL through that pattern while at the same time access to the .xhtml extension will be restricted. So in your web.xml:

<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>*.someExtension</url-pattern>
    </servlet-mapping>

  <security-constraint>  
    <display-name>Restrict access to XHTML Documents</display-name>
    <web-resource-collection>
      <web-resource-name>XHTML</web-resource-name>
      <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
  </security-constraint>

And this is what your bean should return:

return "campaign.someExtension?faces-redirect=true";

In this way you will be able to redirect the user to the page you wish through the commandLinks but when the user types

http://localhost:8080/myApp/faces/campaign.xhtml

or

http://localhost:8080/myApp/faces/campaign.xhtml?faces-redirect=true

to the URL access will be denied.