How to redirect error page when url contains special character? - apache

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

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 change the content of the 401 response to individual format?

I have a JAX-RS application on WildFly 10 which shall be secured by a simple Basic Auth.
It works so far, but if the authentication fails, the server responds with
<html>
<head>
<title>Error</title>
</head>
<body>Unauthorized</body>
</html>
which is not my desired response. I would prefer a customized (json) response.
How to do that?
What I did so far:
I configured a new Wildfly security domain in my server configuration with a simple UserRolesLoginModule (which is sufficient in my case):
<security-domain name="MySecurityDomain" cache-type="default">
<authentication>
<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
<module-option name="usersProperties" value="${jboss.server.config.dir}/users.properties"/>
<module-option name="rolesProperties" value="${jboss.server.config.dir}/roles.properties"/>
<module-option name="hashAlgorithm" value="MD5"/>
<module-option name="hashEncoding" value="base64"/>
<module-option name="hashCharset" value="UTF-8"/>
<module-option name="unauthenticatedIdentity" value="UnauthenticatedAccess"/>
</login-module>
</authentication>
</security-domain>
I annotated all services in the app:
#SecurityDomain("MySecurityDomain")
#RolesAllowed({ "RoleFromPropertyFile", "AnotherRoleFromPropertyFile" })
I created a jboss-web.xml with the content
<jboss-web>
<security-domain>MySecurityDomain</security-domain>
</jboss-web>
I have a web.xml where I tried a lot of different things without any success... :-(
Current content:
<security-constraint>
<display-name>Deny all HTTP methods except GET and POST</display-name>
<web-resource-collection>
<web-resource-name>NextTest</web-resource-name>
<url-pattern>/mypattern/*</url-pattern>
<http-method-omission>GET</http-method-omission>
<http-method-omission>POST</http-method-omission>
</web-resource-collection>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>MySecurityRealm</realm-name>
</login-config>
<security-role>
<description>Access to all application parts</description>
<role-name>all</role-name>
</security-role>
<!-- and some more roles -->
I also implemented a ExceptionMapper<EJBAccessException> to generate my own response. But this mapper is only reached when I remove all content of web.xml.
My guess is that undertow is doing the authorization and handles the response on unauthorized access. If I remove the security configuration in the web.xml, the EJBs are accessed, but without evaluating the BasicAuth header. In this case, all requests are denied.
I possible I would avoid to write a Servlet and use an ExceptionMapper instead.
Any ideas what I missed?
I did a little experiment with some code and, while it's not pretty, you could try something like:
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
#Provider
public class AuthBodyResponseFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
if((responseContext.getStatus() == 401) &&
(responseContext.getEntity() instanceof String))
responseContext.setEntity("no services for you!");
}
}
I tested it a bit and it seems to work. Of course, the challenge is where else is there a 401 with a String response body? I'd have to test more to see if this covers everything.
Here is how I do it:
#POST
#Consumes("application/json")
#Produces("application/json")
public Response create(Entity entity) {
try {
Entity created = service().create(entity);
return Response.created(location(created)).entity(created).build();
} catch (ServiceException e) {
return Response.status(e.getStatus()).entity(e).build();
}
}
Notice the return type, Response. This allows you to customize the response, including setting headers etc. It also means you have to write some more wiring code.
I'm using a custom ServiceException here that already has the status in it and use it to set the response code. Then I pass the exception itself which will be returned as JSON.

How to redirect invalid URLs with valid action at the end

When accessing our website with an invalid action in the url followed by a valid action, web xml is not filtering it out. Below is an example.
https://portal.abcd.org/Enroll - Loading Enroll Page
https://portal.abcd.org/sdafj - Loading Page not found
https://portal.abcd.org/adasdada/Enroll - Not working
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/</url-pattern>
<url-pattern>/RedirectForTesting</url-pattern>
<url-pattern>/FAQ</url-pattern>
<url-pattern>/TnC</url-pattern>
<url-pattern>/Enroll</url-pattern>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/apppages/error_page.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/apppages/Error.jsp</location>
</error-page>

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...

Filter not functioning when used with omnifaces extensionless URLs

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)