Announcement Announcement Module
Collapse
No announcement yet.
Redirection with parameters in Spring MVC + Spring Security Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Redirection with parameters in Spring MVC + Spring Security

    Hi, I'm developing an app with Spring MVC + Spring Security 3.1 and my app is called through a certain URL that contains a parameter that is a XML file as a string.

    I'm developing on a test-environment so I built a test controller and I do:

    Code:
    String parameter = "<Usuario>\n\t<ID>primaria</ID>\n</Usuario>";
    return "redirect:/autenticacion/primaria?parametro=" + parameter;
    And I get the following exception:

    Code:
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Invalid characters (CR/LF) in redirect location
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:88)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
        org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
        org.springframework.security.config.debug.DebugFilter.doFilterInternal(DebugFilter.java:45)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
        org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    What can I do to simmulate the external call with that parameter?
    Last edited by diminuta; Nov 26th, 2012, 08:41 AM.

  • #2
    Hvae you actually looked at the stacktrace?!

    Also you shouldn't redirect in the way you do... Spring caches views based on the view name and now for each user a view is created and cached not something you probably want... Return a ModelAndView and add your parameter as a parameter to the model, spring will then append it and encode it. That way your redirection should work.

    Code:
    String parameter = "<Usuario>\n\t<ID>primaria</ID>\n</Usuario>";
    ModelAndView mav = new ModelAndView("redirect:/autenticacion/primaria");
    mav.addObject("parametro", parameter);
    return mav;
    Something like that... If you are using spring 3.1 you can also simply return the view name and add the objects to the Model. Spring will then still append it to the URL.

    Edit: I also suspect that you haven't posted the full stacktrace, I would expect a message from the dispatcher servlet to appear somewhere in your stacktrace...

    Edit2: Why is this in the security forum? It isn't related to security it is all about encoding your parameters...
    Last edited by Marten Deinum; Nov 26th, 2012, 09:50 AM.

    Comment


    • #3
      Originally posted by Marten Deinum View Post
      Have you actually looked at the stacktrace?!
      Yes, why?

      Originally posted by Marten Deinum View Post
      Also you shouldn't redirect in the way you do... Spring caches views based on the view name and now for each user a view is created and cached not something you probably want... Return a ModelAndView and add your parameter as a parameter to the model, spring will then append it and encode it. That way your redirection should work.
      Altough I redirect in the test controller like you say it won't prevent the error as I don't control and obviously am not the person who develops the other app that calls mine... so this doesn't solve the problem for me...

      Originally posted by Marten Deinum View Post
      Edit: I also suspect that you haven't posted the full stacktrace, I would expect a message from the dispatcher servlet to appear somewhere in your stacktrace...
      I thought I had pasted the full stacktrace, but here it is, I think it doesn't add any significant information :S

      Code:
      26-nov-2012 16:31:38 org.apache.catalina.core.StandardWrapperValve invoke
      GRAVE: Servlet.service() para servlet Spring MVC Dispatcher Servlet lanzó excepción
      java.lang.IllegalArgumentException: Invalid characters (CR/LF) in redirect location
      	at org.springframework.security.web.firewall.FirewalledResponse.sendRedirect(FirewalledResponse.java:23)
      	at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:126)
      	at org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper.sendRedirect(SaveContextOnUpdateOrErrorResponseWrapper.java:74)
      	at org.springframework.web.servlet.view.RedirectView.sendRedirect(RedirectView.java:555)
      	at org.springframework.web.servlet.view.RedirectView.renderMergedOutputModel(RedirectView.java:281)
      	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
      	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1180)
      	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950)
      	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
      	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
      	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      	at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:88)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
      	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
      	at org.springframework.security.config.debug.DebugFilter.doFilterInternal(DebugFilter.java:45)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
      	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
      	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
      	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
      	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
      	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
      	at java.lang.Thread.run(Thread.java:662)
      Originally posted by Marten Deinum View Post
      Edit2: Why is this in the security forum? It isn't related to security it is all about encoding your parameters...
      Because it throws the exception only when I activate Spring Security... If I get rid of security it works...

      Comment


      • #4
        In the end I haven't changed my test controller and I built a filter that rewrites the request URL:

        Code:
        @Override
        	public void doFilter(ServletRequest request, ServletResponse response,
        			FilterChain chain) throws IOException, ServletException {
        		HttpServletRequest httpRequest = (HttpServletRequest) request;
        
        		String incomingUrl = httpRequest.getRequestURI();
        		// Se comprueba si la url original tiene caracter de retorno de carro
        		if (incomingUrl.indexOf('\r') >= 0) {
        			//Sustituye todos los caracteres retorno de carro por caracter vacío.
        			String newUrl = incomingUrl.replaceAll("\n", "");
        			//Asigna una nueva url a la petición.
        			RequestDispatcher requestDispatcher = request
        					.getRequestDispatcher(newUrl);
        			requestDispatcher.forward(request, response);
        		}
        		//Sique adelante la cadena de filtros.
        		chain.doFilter(request, response);
        	}
        And now it works... and it will work also in their production environment...
        Last edited by diminuta; Nov 26th, 2012, 12:25 PM.

        Comment


        • #5
          Because it throws the exception only when I activate Spring Security... If I get rid of security it works...
          That wasn't apparent from your initial stacktrace, the full stacktrace does indeed show this. That shows the framework servlet throwing an exception not a spring security filter...

          I wouldn't do it the way you dit... I would create a request wrapper which does this instead of forwarding the request... It basically saves you a request but alas.

          However it still is a hack as your parameters should be properly encoded and that is something you aren't doing...

          Comment


          • #6
            Originally posted by Marten Deinum View Post
            However it still is a hack as your parameters should be properly encoded and that is something you aren't doing...
            The thing is that I'm not the one who encodes it... a 3rd party app is calling my app with that parameter, I don't have any control over it...

            Comment


            • #7
              The problem is still y our test code (afaik) as it fails on the redirect... So not sure where your 3rd party code comes in here....

              I only see a failing redirect which comes from your code...

              If you have a controller which redirects the user based on something the 3rd party code sends fix the controller don't put this hack in place. Encode the parameter...

              Comment


              • #8
                Maybe I'm not explaining myself...

                A 3rd party app is going to call my app with a call like:

                http://myserver:myport/myapp/autenticacion/primaria?parametro="<?xml version="1.0" encoding="UTF-8"?>\n<solicitud version = "v1.1">\n\t<paramLlamada><Usuario>\t<ID>primar ia</ID>\t<IP>1.1.1.1</IP>\t<datosEspecificos>\t\t<CNP>2</CNP>\t</datosEspecificos></Usuario><Peticion>\t<idioma>GL</idioma>\t<ID_Paciente>\t\t<NASI>726686</NASI>\t</ID_Paciente>\t<Operacion>\t<tipoOperacion>CRI_COLO RECTAL</tipoOperacion>\t</Operacion></Peticion>\t<sello>2012-11-26T16:27:58</sello>\t</paramLlamada>\n\t<paramSeguridad>\n\t\t<firma>Q7xc 74HxHGb8HTu4liow/CECTChI7fHmM7hx8hnC9nIciteSRuNpKskU6IJiVOK7blJMwWg 1WqCP\nXMTn30ybA8kfzkarqAgoIloL0jjaolzY3ieyFoZ/Saj3qjk arCoitcQ39la8CvOjSCVP66WrV a\nv76p01VTLVZBzcNwE3Q=</firma>\n\t\t<certificado>MIIC5jCCAc6gAwIBAgIGATsei mv7MA0GCSqGSIb3DQEBBQUAMFExCzAJBgNVBAYTAkVTMQ8wDQY D\nVQQKDAZTRVJHQVMxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24 gQXV0aG9yaXR5MQ8wDQYDVQQDDAZT\nRVJHQVMwHhcNMTIxMTI wMTU1ODA2WhcNMjIxMTE4MTU1ODA2WjA8MQswCQYDVQQGEwJFU zEPMA0G\nA1UECgwGU0VSR0FTMQwwCgYDVQQLDANERVMxDjAMB gNVBAMMBUlBTlVTMIGfMA0GCSqGSIb3DQEB\nAQUAA4GNADCBi QKBgQCC7bqyKfR6iDgJeTes1sLHWWrR 2Qqbx62EwPSBVPYYCW5KCTdouDMeq1 \niJFrMiAGPR9mxY/LkcVNbMHB7KXIXBkz6NUZK56kFjes86Q03H5MHlJohS6tjTE3a 0gMhXK3rgT9\nwR81gLRXU3KEB61ANtzPjoojrMkjNmam8eGbI wIDAQABo10wWzAfBgNVHSMEGDAWgBSkr85e8M/q\nbIWKDIYNXwoutQAFKTAdBgNVHQ4EFgQUKd4NBdM9 svLSIV7kw4ulS59F UwDgYDVR0PAQH/BAQD\nAgWgMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEB AMRqmbw5LQQAcT f4786vEGJigWagJXu\n6l0OhZl/Y2QkClqfydc17CX1aSaj8oQu1Gt2Cq1JOpvIMZALC4otGdMBMv/9kcp2AKvuIbAvpt74\nUY /xm19BmxVMSBtBsYjDaNFLrb7OSclzzmwsQ Z1ubb /TOr1L5E9ef4v6AzDRHIxprUOoo1z80\nX4L8c0Q7NeOC5DqLvm 5ubRKxfVdpZBTRvyrQHBuGsO8R4ASEEZhkBxaIIkO9gGFxsdOE IBAflugG\nGXlgJFZzl239bPolHST5J86cH LU9iRe WllQxgvlgXi1kMurGKj34SJfwWi YTuTb7n21 4vYvZ\nUdJDCh4=</certificado>\n\t\t<algoritmo>SHA1withRSA</algoritmo>\n\t</paramSeguridad>\n</solicitud>\n"

                Sooo I built a test controller that mocks this behavior... that's the piece of code I posted at the beginning (with a simpler example)

                When my app is called with this request Spring Security throws an exception... so I figured I could avoid it with a filter that transformed the parameter that I receive from the other app.

                Anyways... replaceAll("\\n", "") is not working on that parameter, I don't know why...

                Comment


                • #9
                  Your test is flawed (which is what I tried to explain over all the posts). The error you get from your test isn't the error you get with calling your test controller. So basically you are fixing the wrong problem! As I mentioned before you are getting the error on the REDIRECT not on the incoming request...

                  Sooo I built a test controller that mocks this behavior...
                  Which is the wrong approach... As that leads to another error and that error isn't going to be fixed by your filter.

                  Use another tool to call your application (or at least don't call it from within your application) and fix that problem. I also doubt spring security is throwing an exception on the incoming request (your stacktrace cleary shows that it is throwing an exception on the redirect and not the incoming request.).

                  Code:
                  at org.springframework.security.web.firewall.FirewalledResponse.sendRedirect(FirewalledResponse.java:23)

                  Comment


                  • #10
                    Originally posted by Marten Deinum View Post
                    I also doubt spring security is throwing an exception on the incoming request (your stacktrace cleary shows that it is throwing an exception on the redirect and not the incoming request.).

                    Code:
                    at org.springframework.security.web.firewall.FirewalledResponse.sendRedirect(FirewalledResponse.java:23)

                    Then why it works when I turn off Spring Security? :S

                    Comment


                    • #11
                      Your TEST works but you still haven't fixed the problem you set out to fix..

                      As mentioned you shouldn't be calling your webapp from within your webapp like that (at least not to fix a bug). Write a test that calls your application (or a script which used curl or something).

                      Again you are fixing something that isn't broken but which is a problem in the first place or at least a problem introduced byt your test due to not proberly encoding the parameter...

                      Comment


                      • #12
                        So how I should encode the parameter?

                        Comment


                        • #13
                          Spring does this for you if you use the correct way of redirecting (which I mentioned in my first post) . You could also use URLEncoder.encode.

                          However as mentioned before you shouldn't be doing this if you want to test write a test and not a test controller which is being deployed... IMHO you are using the wrong tool to simulate something...

                          Comment


                          • #14
                            Originally posted by Marten Deinum View Post
                            Spring does this for you if you use the correct way of redirecting (which I mentioned in my first post) . You could also use URLEncoder.encode.
                            I already tried this two options but the error remains the same...

                            Originally posted by Marten Deinum View Post
                            However as mentioned before you shouldn't be doing this if you want to test write a test and not a test controller which is being deployed... IMHO you are using the wrong tool to simulate something...
                            I'll try something different then... thanks

                            Comment


                            • #15
                              Just to let you know that you were absolutely right I developed the test as a sepparate Struts app and now it works withouth that ugly hack, thanks

                              Comment

                              Working...
                              X