0

Followed this post to change the request to json.

My configurations

Filter:

@Component
@Order(value = Integer.MIN_VALUE)
public class JsonToUrlEncodedAuthenticationFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        if (Objects.equals(request.getContentType(), "application/json") && Objects.equals(((RequestFacade) request).getServletPath(), "/oauth/token")) {
            InputStream is = request.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            int nRead;
            byte[] data = new byte[16384];

            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.flush();
            byte[] json = buffer.toByteArray();

            HashMap<String, String> result = new ObjectMapper().readValue(json, HashMap.class);
            HashMap<String, String[]> r = new HashMap<>();
            for (String key : result.keySet()) {
                String[] val = new String[1];
                val[0] = result.get(key);
                r.put(key, val);
            }

            String[] val = new String[1];
            val[0] = ((RequestFacade) request).getMethod();
            r.put("_method", val);

            HttpServletRequest s = new MyServletRequestWrapper(((HttpServletRequest) request), r);
            chain.doFilter(s, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}

Request Wrapper:

public class MyServletRequestWrapper extends HttpServletRequestWrapper {
    private final HashMap<String, String[]> params;

    public MyServletRequestWrapper(HttpServletRequest request, HashMap<String, String[]> params) {
        super(request);
        this.params = params;
    }

    @Override
    public String getParameter(String name) {
        if (this.params.containsKey(name)) {
            return this.params.get(name)[0];
        }
        return "";
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return this.params;
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return new Enumerator<>(params.keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
}

the above configuration is working in spring boot embedded tomcat. Unfortunately its not working in tomcat 9.0.1 when i debug the filter , its gets values once and pass through it to doFilter(), from there its again looping, next time its get error

ERROR boot.web.support.ErrorPageFilter - Forwarding to error page from request[/oauth/token] due to exception [No content to map due to end-of-input]

its due to json is not there for second loop, but when springboot is used it doesn't enter it into second loop.

Any suggestion to make it work in springboot as well standalone tomcat also.

Dipen Chawla
  • 331
  • 2
  • 10
user_vs
  • 1,021
  • 3
  • 16
  • 29
  • How is that question related to Spring Security? It is a question about Spring Boot, Servlet and Tomcat. – dur Nov 09 '17 at 10:47

1 Answers1

0

The issue was Duplicate Filter registration for 'springSecurityFilterChain'

. The Spring boot starts once in the beginning, my code also tries to register springSecurityFilterChain manually extending

AbstractSecurityWebApplicationInitializer.class

, which cause the trouble.After removing that, its working in spring boot as well as in standalone tomcat.

user_vs
  • 1,021
  • 3
  • 16
  • 29