Filter not functioning when used with omnifaces extensionless URLs - servlet-filters

I am using omnifaces extensionless URLS in my web application.
My web.xml is as below
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<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>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
<param-value>/*.xhtml</param-value>
</context-param>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>Login.xhtml</welcome-file>
</welcome-file-list>
</web-app>
My filter clas is as below
#WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" })
public class AuthenticationFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession ses = req.getSession(false);
String reqURI = req.getRequestURI();
System.out.println(reqURI);
if (reqURI.indexOf("/Login") >= 0
|| (ses != null && ses.getAttribute("user") != null)
|| (reqURI.indexOf("/ForgotPassword") >=0)
|| reqURI.contains("javax.faces.resource")) {
if ((reqURI.indexOf("/Login") >= 0 || (reqURI.indexOf("/ForgotPassword") >=0))
&& (ses != null && ses.getAttribute("user") != null)) {
System.out.println("Invalidating session");
ses.invalidate();
}
chain.doFilter(request, response);
} else {
res.sendRedirect(req.getContextPath() + "/Login");
}
} catch (Throwable t) {
System.out.println(t.getMessage());
}
} // doFilter
}
My requirement is that, if the user is logged in redirect him to all the pages except the Login and ForgotPassword pages. When the user is logged in and tries to access either of those pages, log him out and send him to the requested page. If the user is not logged in, all requests to Login and ForgotPassword pages should be allowed and access to any other page should redirect him to Login page.
The problem I am facing is that with the extensionless URLs, I can access a page with or without the .xhtml file extensions. The filter is invoked only when I access it using the extension. Without the extension, the filter is bypassed.
I am not sure what URL pattern to provide in the filter class to get it to process every request.
Kindly help.

Either, listen on all URLs:
#WebFilter(urlPatterns = "/*")
or, attach it to the FacesServlet:
#WebFilter(servletNames = "Faces Servlet")
(note that this way the filter thus doesn't run when the URL doesn't hit the FacesServlet)

Related

Getting 404 error on JAX-RS web service/ Maven/Eclipse/Tomcat 9

I am trying to show the Alien Object in XML format with AlienResouces as Resource.However, it is giving me 404 error during runtime on the browser and the debugging stmnt GeAlien called is not showing on Tomcat console
Web Service
package com.dip.testproj;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Alien {
private String name;
private int points;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}
The following is the Resource for the Alien object. The object Alien is getting the resource Name and Number and trying to display it on the browser during runtime.
We Service Resources
package com.dip.testproj
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("aliens")
public class AlienResources {
#GET
#Produces(MediaType.APPLICATION_XML)
public Alien getAlien(){
System.out.println("getAlien Called");
Alien a1 = new Alien();
a1.setName("Navin");
a1.setPoints(60);
return a1;
}
}
There is no compilation error or any error on the console for Tomcat. server. However, it is giving "404" or "Resource could not be found" while trying to run the THIS on the FF browser
The URL Pattern on WEB.xml looks like this.
WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.dip.testproj</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>

How to redirect error page when url contains special character?

I have a question in setting tomcat.
I want to show common error page when error occurs.
this is my client security needs.
But, if I access www.mydomain.com/..%5c, my common error page not works.
they show "HTTP ERROR 400 message".
I want to redirect my common error page..
this is my web.xml config.
<error-page>
<error-code>400</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>405</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.html</location>
</error-page>
And I add CATALINA_OPTS.
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
this option works in www.mydomain.com/%5c
but not working www.mydomain.com/..%5c
How can I redirect common error page when access www.mydomain.com/..%5c
You can try this program.
I think you can configure your filter in web.xml. In the filter you can implement the logic to process your request encoding and special characters, then redirect to the error page.
Configuration
<filter>
<filter-name>name</filter-name>
<filter-class>demoClass</filter-class>
</filter>
<filter-mapping>
<filter-name>name</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Class to be implemented
public class demoClass implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("----init----");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//TODO code
}
#Override
public void destroy() {
System.out.println("----destory----");
}
}
My English is poor

doFilter is calling too many times

This is my filter mapping in web.xml :-
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>login.LoginFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>This parameter is for testing.</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
my URL is like
"localhost:9966/RemindMe/"
When i paste this Url in browser doFilter method is calling many times.
This is my doFilter method :-
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
try {
HttpServletResponse response = (HttpServletResponse) res;
response.sendRedirect("./login.jsp");
return;
} catch (Exception e) {
System.out.println("Exception is " + e);
}
}
By "too many times" to you mean "infinite"?
Your filter redirects (the browser makes another request), which means your filter is hit, which means the browser makes another request, which means...

How to get id of authenticated user in Olingo ODataServiceFactory

I am trying to read the user id of the user that is calling my OData service.
In my web.xml the OData servlet is a protected area
<servlet>
<servlet-name>EJODataServlet</servlet-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
</init-param>
<init-param>
<param-name>org.apache.olingo.odata2.service.factory</param-name>
<param-value>com.wombling.odata.service.EJServiceFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>EJODataServlet</servlet-name>
<url-pattern>/EJOData.svc/*</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>FORM</auth-method>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/a/*</url-pattern>
<url-pattern>/index.html</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>/EJOData.svc/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>extension_user</role-name>
</auth-constraint>
</security-constraint>
When I create the factory to serve the response to a query:
public class EJServiceFactory extends ODataServiceFactory {
#Override
public ODataService createService(ODataContext ctx) throws ODataException {
return RuntimeDelegate
.createODataSingleProcessorService(
new AnnotationEdmProvider(
"com.wombling.odata.models"),
new EJODataProcessor("admin")); //TODO this should not be hardcoded
}
}
I cannot see any way that I can get from the ODataContext the user that has passed authentication. If I were to be using basic auth - then I could just get the header, but I'm not using basic auth, but OAuth2 bearer tokens (created by a SAML assertion).
I'd expect the ODataContext provide me access to the request user id, but no luck. Is there some other means that I can use? Or do I need to force the calling application to insert the user id in the request headers (doesn't seem ideal to me!)
To retrieve the request object via the ODataContext object is a little bit tricky. Try this:
HttpServletRequest r = (HttpServletRequest) ctx.getParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
ctx is your instance of the ODataContext class. From the request object you get all what you need.

Jersey/Glassfish: what is consuming POST parameters?

I have a Jersey 2.x servlet running under Glassfish 4.0. There is a method that processes a form submission:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("/{serial}")
public Response saveUnit(....) { ... }
I get the message "A servlet request to the ... contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters."
However, I don't have any filters defined. Other than whatever Glassfish and Jersey do by default.
I do however have a listener defined (which I had forgotten about).
I suspect this is why my attempt to use MultivaluedMap isn't working.
Any ideas what is consuming the request?
Here is the Jersey method:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("/{unitid}")
public Response saveUnit(#PathParam("unitid")int unitId, #Context UriInfo uri) {
MultivaluedMap<String, String> queryParams = uri.getQueryParameters();
for (String k:queryParams.keySet()) {
logger.info(k);
}
return Response.ok().build();
}
The map queryParams is empty.
Here is my web.xml.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>mycompany.ApplicationConfig</servlet-name>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>mypackage</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mycompany.ApplicationConfig</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<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>
<listener>
<listener-class>mycompany.ServletContextClass</listener-class>
</listener>
</web-app>
To get to the received form parameters in your resource method change the signature of the method to:
public Response saveUnit(#PathParam("unitid") int unitId,
final javax.ws.rs.core.Form form) {
...
}
or
public Response saveUnit(#PathParam("unitid") int unitId,
final MultivaluedMap<String, String> formData) {
...
}
Jersey will fill the values.
With your approach you're asking Jersey to return a map of query params (which are part of URI and assuming from the question you want Form params).