Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Broke RESTfulness with Spring Security

  1. #1

    Question Broke RESTfulness with Spring Security

    Hi everyone,

    In my roo project I have an Entity that represents an uploaded File (name, mimetype, data itself). Now I have the upload working, I started to setup
    spring security.

    I have a whitelist configuration for URL-Interception allowing everyone for /static/** and /resource/** and /login but requiring login for everything else as the last rule.

    Now problem is this: In my controller, I adjusted code for the methods for creation (using POST) and update (using PUT). Unfortunately spring security seems to do a redirect so the original PUT-request from my update gets turned into a POST-request which in turn leads to the controller not finding a correct request mapping for the update URL (expects PUT, gets POST).

    Does that sound plausible?
    What can I do about it?

    (Sorry don't have access to code right now)

    Ben, I think this might be an easy one for you ;-)

  2. #2
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    It should work fine. But it does sound more like a Spring Security question than a Roo question, so you might find you receive better support by asking in the Spring Security forum. In any event would you please provide a debug-level log of the request processing and also the applicationContext-security.xml so we can help you figure it out.
    Ben Alex
    Project Founder, Spring UAA, Spring Roo and Spring Security

  3. #3

    Default

    Thanks for the quick reply. You guys are really caring about your users
    Will provide logs, code and config as soon as I have access to it again.

    Besides: Do you know how ROO-8 is doing?

  4. #4
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    ROO-8 is coming along brilliantly. Stefan is off to San Francisco this weekend to meet with our web team to fine-tune it some more. I've seen the work so far (it's not checked in yet) and it's impressive. I think people will really like it. We've spent a lot of time designing it so you can round-trip JSPX views in a very natural, usable way. And the JSPXs themselves are very small now and easily support the development of alternate tag libraries.
    Ben Alex
    Project Founder, Spring UAA, Spring Roo and Spring Security

  5. #5

    Default

    Wonderful :-)
    Just lost one hours adjustments because I forgot to automaticallyMaintainView=false

  6. #6
    Join Date
    Sep 2009
    Posts
    101

    Default

    tbender,

    I would check to make sure you are using the "form:form" MVC tag (<form:form method="PUT"..>) in your form. That creates a hidden field named "_method", which I believe Spring MVC uses to detect PUT requests.

    If you are using a single form for POST/PUT, you will need to create that hidden field another way.

    (This may not be the problem in your case, but it would cause the symptoms you describe, making it seem as if your PUT is getting turned into a POST.)

  7. #7

    Default

    Thanks mikej.

    AFAIR I use the spring form:from tag and the method is set to put.
    I'll see if I can get the log output.

  8. #8
    Join Date
    Jan 2009
    Location
    Huntington Beach, CA
    Posts
    718

    Default

    Quote Originally Posted by tbender View Post
    Thanks mikej.

    AFAIR I use the spring form:from tag and the method is set to put.
    I'll see if I can get the log output.

    Don't you have to put in the hidden field for _method yourself? Just vaguely recollect seeing it in the docs, but is in the far distance of my memory, so I can be very inaccurate here.

    Very cool news about ROO-8 and the possible new looks.

    Mark

  9. #9

    Default Configuration and Log output

    Hi here is my secruity configuration (auth mechanism omitted)

    Code:
    	<!-- HTTP security configurations -->
        <http auto-config="true" use-expressions="true">
        	<form-login login-processing-url="/static/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/>
            <logout logout-url="/static/j_spring_security_logout"/>
            
            <!-- Configure these elements to secure URIs in your application -->
    <!--        <intercept-url pattern="/choice/**" access="hasRole('ROLE_ADMIN')"/>--><!--
            <intercept-url pattern="/member/**" access="isAuthenticated()" />
            --><intercept-url pattern="/resources/**" access="permitAll" />
            <intercept-url pattern="/static/**" access="permitAll" />
            <intercept-url pattern="/login" access="permitAll" />
            <intercept-url pattern="/**" access="isAuthenticated()" />
        </http>
    Here is the controller method, that should be used:

    Code:
    	@RequestMapping(method = RequestMethod.PUT)    
        public String update(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap, HttpServletRequest request) {    
            if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        
            if (result.hasErrors()) {        
                modelMap.addAttribute("scriptFile", scriptFile);            
                modelMap.addAttribute("showcases", ShowCase.findAllShowCases());            
                return "scriptfile/update";            
            }
            setFileParameters(scriptFile, request);
            scriptFile.merge();        
            return "redirect:/scriptfile/" + scriptFile.getId();        
        }
    And here is waht the log says:
    Code:
    Converted URL to lowercase, from: '/scriptfile/3'; to: '/scriptfile/3'
    Candidate is: '/scriptfile/3'; pattern is /resources/**; matched=false
    Candidate is: '/scriptfile/3'; pattern is /static/**; matched=false
    Candidate is: '/scriptfile/3'; pattern is /login; matched=false
    Candidate is: '/scriptfile/3'; pattern is /**; matched=true
    Secure object: FilterInvocation: URL: /scriptfile/3; Attributes: [isAuthenticated()]
    Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@bad9b5a1: Principal: org.springframework.security.core.userdetails.User@0: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Password: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 127.0.0.1; SessionId: 127lj3enf736d; Granted Authorities: ROLE_ADMIN
    Voter: org.springframework.security.web.access.expression.WebExpressionVoter@73db92, returned: 1
    Authorization successful
    RunAsManager did not change Authentication object
    /scriptfile/3 reached end of additional filter chain; proceeding with original chain
    Using EntityManagerFactory 'entityManagerFactory' for OpenEntityManagerInViewFilter
    Returning cached instance of singleton bean 'entityManagerFactory'
    Opening JPA EntityManager in OpenEntityManagerInViewFilter
    DispatcherServlet with name 'sc' processing POST request for [/sc/app/scriptfile/3]
    Found multipart file [file] of size 1167 bytes with original filename [Lesson-1A-SQL-Injection.html], stored in memory
    Matching patterns for request [/scriptfile/3] are [/scriptfile/{id}, /scriptfile/**/, /scriptfile/**]
    Mapping [/scriptfile/3] to handler 'com.mycompany.sc.web.ScriptFileController@19a13e5'
    Resolving exception from handler [com.mycompany.sc.web.ScriptFileController@19a13e5]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
    Resolving to view 'uncaughtException' for exception of type [org.springframework.web.HttpRequestMethodNotSupportedException], based on exception mapping [.lang.Exception]
    Exposing Exception as model attribute 'exception'
    Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'uncaughtException'; model is {exception=org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported}
    org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodResolver.resolveHandlerMethod(AnnotationMethodHandlerAdapter.java:567)
    Here is the form-Tag as I use it (ony small modification from what roo generated):
    Code:
    <form:form action="${form_url}" method="PUT" modelAttribute="scriptFile" enctype="multipart/form-data">
    As you can see the form states PUT but the logoutput shows that spring-mvc is trying to map a POST method. I'll check the requests again with firebug.
    Last edited by tbender; Feb 22nd, 2010 at 07:28 AM.

  10. #10

    Question Checked with firebug

    Hi folks,

    Just checked the requests using firebug.

    I can see that the form sends a HTTP-Post request with the following content:

    Code:
    Content-Type: multipart/form-data; boundary=---------------------------16652697611625305771130515920
    
    5
    
    Content-Length: 2554
    
    -----------------------------166526976116253057711305159205
    
    Content-Disposition: form-data; name="_method"
    
    PUT
    
    -----------------------------166526976116253057711305159205
    
    Content-Disposition: form-data; name="name"
    
    ConfiguredAccounts
    
    -----------------------------166526976116253057711305159205
    
    Content-Disposition: form-data; name="showcase"
    
    1
    
    -----------------------------166526976116253057711305159205
    
    Content-Disposition: form-data; name="file"; filename="Default-Config-Accounts.html"
    Last edited by tbender; Feb 24th, 2010 at 04:52 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •