Prevent direct access to composite components by placing them inside /WEB-INF - security

I'm trying to define some composite components in my web application. According to the tutorials i read, i have to place the xhtml files inside a resource folder located in webcontent.
This solution is problematic, given that it would make those files available for public access from an url.
Is there a way to put this components inside the web-inf folder, and make the jsf look for the files there?
If not, is there another way to avoid direct access?
Thanks.
P.S.: I have looked into this answer, and if i understood BalusC's answer correctly, what I intend to do is possible.

"Composite components" are not exactly the same as "compositions" in the question/answer you found. The OP was clearly talking about compositions as in <ui:include> files which are including <ui:componsition> content.
You effectively want to prevent direct access to /resources. This can be achieved by adding the following security constraint entry to web.xml:
<security-constraint>
<display-name>Restrict direct access to JSF resources</display-name>
<web-resource-collection>
<web-resource-name>JSF resources</web-resource-name>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
<auth-constraint /><!-- Empty auth constraint! -->
</security-constraint>
As per the upcoming JSF 2.2, this would not be necessary anymore as it allows you to move the whole /resources folder into /WEB-INF by the following configuration entry in web.xml:
<context-param>
<param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
<param-value>WEB-INF/resources</param-value>
</context-param>

Related

Username not displayed after a successful login with Spring Security and Java Server Faces [duplicate]

I have some Facelets files like below.
WebContent
|-- index.xhtml
|-- register.xhtml
|-- templates
| |--userForm.xhtml
| `--banner.xhtml
:
Both pages are using templates from /templates directory. My /index.xhtml opens fine in browser. I get the generated HTML output. I have a link in /index.xhtml file to /register.xhtml file.
However, my /register.xhtml is not getting parsed and returns as plain XHTML / raw XML instead of its generated HTML output. All EL expressions in form of #{...} are displayed as-is instead of that their results are being printed. When I rightclick page in browser and do View page source, then I still see the original XHTML source code instead of the generated HTML output. For example, the <h:body> did not become a <body>. It looks like that the template is not being executed.
However, when I open the /register.xhtml like /faces/register.xhtml in browser's address bar, then it displays correctly. How is this caused and how can I solve it?
There are three main causes.
FacesServlet is not invoked.
XML namespace URIs are missing or wrong.
Multiple JSF implemenations have been loaded.
1. Make sure that URL matches FacesServlet mapping
The URL of the link (the URL as you see in browser's address bar) has to match the <url-pattern> of the FacesServlet as definied in web.xml in order to get all the JSF works to run. The FacesServlet is the one responsible for parsing the XHTML file, collecting submitted form values, performing conversion/validation, updating models, invoking actions and generating HTML output. If you don't invoke the FacesServlet by URL, then all you would get (and see via rightclick, View Source in browser) is indeed the raw XHTML source code.
If the <url-pattern> is for example *.jsf, then the link should point to /register.jsf and not /register.xhtml. If it's for example /faces/*, like you have, then the link should point to /faces/register.xhtml and not /register.xhtml. One way to avoid this confusion is to just change the <url-pattern> from /faces/* to *.xhtml. The below is thus the ideal mapping:
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
If you can't change the <url-pattern> to *.xhtml for some reason, then you probably would also like to prevent endusers from directly accessing XHTML source code files by URL. In that case you can add a <security-constraint> on the <url-pattern> of *.xhtml with an empty <auth-constraint> in web.xml which prevents that:
<security-constraint>
<display-name>Restrict direct access to XHTML files</display-name>
<web-resource-collection>
<web-resource-name>XHTML files</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
JSF 2.3 which was introduced April 2017 has already solved all of above by automatically registering the FacesServlet on an URL pattern of *.xhtml during webapp's startup. The alternative is thus to simply upgrade to latest available JSF version which should be JSF 2.3 or higher. But ideally you should still explicitly register the FacesServlet on only one URL pattern of *.xhtml because having multiple possible URLs for exactly the same resource like /register.xhtml, /register.jsf, /register.faces and /faces/register.xhtml is bad for SEO.
See also:
Set default home page via <welcome-file> in JSF project
Opening JSF Facelets page shows "This XML file does not appear to have any style information associated with it."
Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?
JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used
Which XHTML files do I need to put in /WEB-INF and which not?
Our servlets wiki - to learn the mandatory basics about servlets
2. Make sure that XML namespaces match JSF version
Since introduction of JSF 2.2, another probable cause is that XML namespaces don't match the JSF version. The xmlns.jcp.org like below is new since JSF 2.2 and does not work in older JSF versions. The symptoms are almost the same as if the FacesServlet is not invoked.
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
If you can't upgrade to JSF 2.2 or higher, then you need to use the old java.sun.com XML namespaces instead:
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
But ideally you should always use the latest version where available.
See also:
Which XML namespace to use with JSF 2.2 and up
JSF tags not executed
Warning: This page calls for XML namespace http://xmlns.jcp.org/jsf/XXX declared with prefix XXX but no taglibrary exists for that namespace
3. Multiple JSF implementations have been loaded
One more probable cause is that multiple JSF implementations have been loaded by your webapp, conflicting and corrupting each other. For example, when your webapp's runtime classpath is polluted with multiple different versioned JSF libraries, or in the specific Mojarra 2.x + Tomcat 8.x combination, when there's an unnecessary ConfigureListener entry in webapp's web.xml causing it to be loaded twice.
<!-- You MUST remove this one from web.xml! -->
<!-- This is actually a workaround for buggy GlassFish3 and Jetty servers. -->
<!-- When leaving this in and you're targeting Tomcat, you'll run into trouble. -->
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
When using Maven, make absolutely sure that you declare the dependencies the right way and that you understand dependency scopes. Importantingly, do not bundle dependencies in webapp when those are already provided by the target server.
See also:
Configuration of com.sun.faces.config.ConfigureListener
How to properly install and configure JSF libraries via Maven?
Make sure that you learn JSF the right way
JSF has a very steep learning curve for those unfamiliar with basic HTTP, HTML and Servlets. There are a lot of low quality resources on the Internet. Please ignore code snippet scraping sites maintained by amateurs with primary focus on advertisement income instead of on teaching, such as roseindia, tutorialspoint, javabeat, baeldung, etc. They are easily recognizable by disturbing advertising links/banners. Also please ignore resources dealing with jurassic JSF 1.x. They are easily recognizable by using JSP files instead of XHTML files. JSP as view technology was deprecated since JSF 2.0 at 2009 already.
To get started the right way, start at our JSF wiki page and order an authoritative book.
See also:
Java / Jakarta EE web development, where do I start and what skills do I need?
What is the need of JSF, when UI can be achieved with JavaScript libraries such as jQuery and AngularJS

Websphere extendedDocumentRoot how to restrict by security role

We are using Websphere 8.5.5 Traditional
I have added an extended document root to Websphere's ibm-web-ext.xml file and set file sharing to true.
<fileServingAttribute name="extendedDocumentRoot" value="C:/extdocroot"/>
<enable-file-serving value="true"/>
inside the extended document root folder (C:/extdocroot) is a folder called pdfs. I would like to restrict the pdfs folder to only users who have logged in and have a particular role of 'school'.
the URL to serve up the pdf's is https://domain-name:9080/context-path/pdf/pdf-name.pdf
I added a security constraint in the web.xml file
<security-constraint>
<display-name>school PDFs</display-name>
<web-resource-collection>
<web-resource-name>School PDFs</web-resource-name>
<url-pattern>/pdf/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>school</role-name>
</auth-constraint>
</security-constraint>
No matter what role a user is logged in as the PDF's will get served by the the server. Websphere is ignoring the security constraint for the URL that serves up PDF's from the extended document root. Is it possible to constrain these PDF's by the roles a logged in user has.
Note: My company has asked me to try and put these files outside of the ear file and also have Websphere secure the files using user's role. I was also instructed not to use the Apache HTTP Server to host these files since it is in the DMZ.
I have found that this was a bug in Websphere 8.5.5.11. After upgrading to 8.5.5.12 I was able to add security constraints in the web.xml for folders that were in the extended document root.
I have also tested this in Websphere 9.0.0.5 and everything worked as it should.

h:outputStylesheet generates RES_NOT_FOUND URL for resources in /WEB-INF/resources

I am trying to include my stylesheets within the <h:head> tag utilising the following JSF tag: <h:outputStylesheet name="stylesheets/bootstrap.min.css" />, however when I load my page I get RES_NOT_FOUND for this specific CSS resource when looking through dev tools in the web browser.
I am trying to call the stylesheet within one of my template files I have created, "default.xhtml". Please refer to the image attached below to see my project directory structure, and where the red arrow indicates where the tag is being utilised.
Within the default.xhtml template, I have defined the <h:head> tags although it appears to still not be working. Is there anything I am missing which is not allowing this to be loaded?
If you require more information, please let me know. I would like to resolve this issue as quickly as possible.
I figured out the issue here.
By default, I believe that JSF resource handling mechanism does not support for mapping the resource directory which resides in the WEB-INF directory. In order to overwrite this default, you need to explicitly define a new <context-param> within the project web.xml file.
The following fragment of code below specifies the directory used for resource lookup in the file system of the web application.
<context-param>
<param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
<param-value>/WEB-INF/resources</param-value>
</context-param>

Changing welcome file location results in deployment failure

I am getting below error.
FAIL - Application at context path /sampleJSF could not be started
I want to change my welcome file location. I have a index.jsp page at WEB-INF/pages/index.jsp. How can I modify servlet mapping and welcome file list to achive this?
Here is my servlet-mapping and welcome-file-list from web.xml.
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>WEB-INF/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>WEB-INF/pages/index.jsp</welcome-file>
</welcome-file-list>
It look like that you misunderstood the purpose of both the welcome file setting and the /WEB-INF folder.
The welcome file must represent the name of the file which the server should serve from the current folder when a folder is been requested instead of a file in URL. E.g. /, /foo/, /bar/, etc. So, when you set it to index.jsp, then it will serve /index.jsp when / is requested, and /foo/index.jsp when /foo/ is requested, etc.
The /WEB-INF folder is for files which shouldn't be independently publicly accessible. For example, include files, template files, error files, tag files, configuration files, etcetera. Mapping the Faces Servlet on /WEB-INF makes no utter sense as the servlet container already restricts direct (public) access to /WEB-INF folder when the enduser purposefully enters the /WEB-INF folder in the URL.
Undo all those changes you made on the sample web application. They make simply no sense. Whatever functional requirement you had in mind for which you incorrectly thought that this is the right solution must be solved differently.
Unrelated to the concrete problem, it look like that you're just getting started with JSF, but do you know that JSP is deprecated since JSF 2.0 in 2009? Are you absolutely positive that you're learning JSF based on the right and up to date resources? I strongly recommend to do so, or you will end up having confusion headache and code disaster. Start at our JSF wiki page.

Configuring container-managed security in Weblogic

Anyone know of any guides for this? I'm a complete newbie to weblogic and to container-managed security. What I've done already is:
setup an LDAP authenticator in Weblogic
created a simple webapp in Eclipse
Configure web.xml: Added security-constraint, security-role and login-config elements. The realm name used is "myrealm" which already exists in Weblogic. The role name I used is "Admin" which is a global role in Weblogic
Create a simple jsp page "login.jsp". It doesn't actually do any logging in but just a Hello World type of thing. I set this page as form-login-page and form-error-page in login-config in web.xml
Export this webapp to a war file and deploy it in Weblogic
I test it by accessing http://weblogic-server/test/login.jsp, and I expect that I'll be asked to login using an LDAP user first. This doesn't happen, it just shows the Hello World jsp.
I've also tried adding a weblogic.xml to map the "Admin" role to a specific LDAP user (didn't work).
Any advice? It seems there's a lack of online references for this sort of thing (or I don't really know what I should be searching for)
Edit: I've also tried using BASIC auth instead of FORM (no luck)
My web.xml settings are below:
<security-constraint>
<display-name>Test SC</display-name>
<web-resource-collection>
<web-resource-name>Test WR</web-resource-name>
<url-pattern>/hello.jsp</url-pattern>
<http-method>*</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>Admin</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>myrealm</realm-name>
</login-config>
The login page must do some sort of logging in, with the 2 required fields. You have protect the hello_world.jsp page in the web.xml and go to that pages, the login page will be presented.
Edit:
The order is incorrect: it should be security-constraint, login-config and security-role.
Within the web-resource-collection the value of * is invalid for http-method. If you want to protect every method just leave it away.
Note: the server logging whould have hinted the incorrect order of elements in your web.xml.

Resources