Grails

Declarative Syntax For Limiting Access To Actions Based On HTTP Request Method

Details

  • Type: New Feature New Feature
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 0.3
  • Component/s: Controllers
  • Labels:
    None
  • Patch attached:
    Yes
  • Testcase included:
    yes

Description

Grails provides no standard way for application authors to limit access to certain controller actions based on the http request method. Justifications for limiting access based on the http request method include but are not limited to the idea that destructive actions should not be allowed to be initiated via a GET. Application authors may code behavior in their controllers to inspect the request method and react accordingly. This may be desireable for certain scenarios but for many scenarios the author may simply want to deny access to certain actions when the action is invoked via an invalid request method.

One approach to the problem might be to come up with a way to indicate which actions are destructive and then have grails impose some restrictions based on that. I propose a more general solution that will allow controller authors to impose restrictions for whatever reasons they choose.

I propose a simple declarative syntax in the controller to represent these restrictions and have attached a patch to support this new syntax including test coverage of the new behavior.

Contollers may optionally declare a property called httpMethodRestrictions. The value of this property should be a Map with keys that correspond to action names. The value associated with the action names should be either a String representing an http method or a List containing any number of methods. The default behavior for all actions is to be accessible via any http method. Access to an action is only limited if the action is included in the Map. If no restrictions are to be imposed then there is no need to declare the httpMethodRestrictions property. This solution is completely backward compatible. When a restriction is violated a HttpServletResponse.SC_FORBIDDEN error is sent.

Example Controller:

EmployeeController.groovy
class EmployeeController {

  // action1 may be invoked via a POST
  // action2 has no restrictions
  // action3 may be invoked via a POST or DELETE
  def httpMethodRestrictions = [action1:'POST',
                                action3:['POST', 'DELETE']]

  def action1 { ... }
  
  def action2 { ... }

  def action3 { ... }

}

Summary of changes included in the patch:

GrailsControllerClass.java

  • added isHttpMethodAllowedForAction()

DefaultGrailsControllerClass.java

  • implemented isHttpMethodAllowedForAction()

SimpleGrailsControllerHelper.java

  • changed handleURI() to send HttpServletResponse.SC_FORBIDDEN if a restriction is violated per the new isHttpMethodAllowedForAction() in GrailsControllerClass.java

SimpleGrailsControllerTests.java

  • added testRestrictedControllerSuccess()
  • added assertResponseStatusCode() as a utility method called by testRestrictedControllerSuccess()
  • changed setUp() to support the new test
  • trivial refactoring of the execute() method to support the new test

DefaultGrailsControllerClassTests.java

  • added testHttpMethodRestrictions()

Activity

Hide
Jeff Brown added a comment -

We decided to change the property name to allowedMethods.

Show
Jeff Brown added a comment - We decided to change the property name to allowedMethods.
Hide
Jeff Brown added a comment -

Changes have been committed to SVN.

Show
Jeff Brown added a comment - Changes have been committed to SVN.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: