2

In Grails 3.3 I was using a custom extension of RestOauthController from spring-security-rest:2.0.0.M2 plugin, which I'd overriden in UrlMappings.groovy like this:

"/oauth/access_token"(controller: "restOauthMy", action: "accessToken", method: "POST")

However, after upgrading to Grails 4, a POST request to /oauth/access_token now leads to the original controller, my RestOauthMyController.accessToken() is never called. Is there a way to get rid of the original URL mapping? More generally, what determines priority of conflicting URL mappings in Grails?

andysh
  • 339
  • 1
  • 15
  • Is there a reason you want to use a milestone of the plugin (`spring-security-rest:2.0.0.M2`)? – Jeff Scott Brown Apr 07 '21 at 19:10
  • No strong reason for that, probably used a recommendation in a guide at the time. But now I tried the latest 3.0.0.RC1 and it behaved identically. – andysh Apr 13 '21 at 12:27

2 Answers2

1

I found a functional workaround adding the URL mapping dynamically in BootStrap.groovy:

def grailsUrlMappingsHolder

def init = {
    grailsUrlMappingsHolder.addMappings {
        "/oauth/access_token" (controller: "restOauthMy", action: "accessToken", method: "POST")
    }
}

This way the dynamic mapping seems to take priority and my overriden code executes.

I would very much like to know how to do this properly, though.

andysh
  • 339
  • 1
  • 15
  • 1
    That's why I added that sentence and haven't accepted it. The solution I found answers the question partially, but not fully and I'll be happy to accept a better answer. – andysh Apr 02 '21 at 19:08
  • @Jeff He's not really answering his own question. By default, Grails tends to map all controllers with a Rest Mapping but (AFAIK) uses a URLHandlerMapping for the UrlMapping (much like he did above in INIT). It looks like the URLHandlerMapping is not mapping to the RestMappings like they did in 3.0. This is the same way you would do it in spring-boot but you have to manually do it whereas Grails used to do it for you. Looks like Grails is doing less and less. – Orubel Apr 03 '21 at 17:30
  • @Andysh Check to see if there is a plugin handling the URLMapping that may be overwriting your rules. This is the only other thing I could think of. At that point, you would have to fork the plugins code to fix that mapping. – Orubel Apr 03 '21 at 18:17
  • @Andysh one more late point... your controller may not be registered as a bean or cannot be found. So it may be using what is sees as a default. I suggest filing a bug with as much info as you can possibly supply. The most likely scenario is that your controller may not be being seen but if you give them access to your codebase and create some tests, you may catch them in a good mood. – Orubel Apr 03 '21 at 18:32
  • 1
    @Orubel yes spring-security-rest plugin overrides my mappings, it's obvious, also checked with debugger. My controller is loaded as a bean correctly including the mapping as is also seen in url-mappings-report (otherwise my trick wouldn't work). The plugin's mapping is prioritized though, but it shouldn't (from my point of view). – andysh Apr 06 '21 at 14:22
  • @andysh yes you are right, you SHOULD be able to override the plugin. Thats why this is a bug. You obviously have a TEMPORARY FIX but it is not a permanent one for issues of this nature and is NOT a fix that they have enforced and expected for the community at large for plugins. – Orubel Apr 06 '21 at 19:17
0

So in looking over the Grails 4.0 code (and other plugins), this appears to be a VERY HARDCODED endpoint specific to spring-security-rest which was discontinued and brought in-house

So until they fix their issue, you have the best workaround. Still... this is a bug that they have yet to fix as functionality DID WORK in 3.0 when spring-security-rest was a separate plugin and now it is BORKED!

Orubel
  • 316
  • 4
  • 16
  • [This](https://github.com/grails-plugins/grails-spring-security-rest/blob/develop/spring-security-rest/grails-app/controllers/grails/plugin/springsecurity/rest/RestOauthUrlMappings.groovy) is the official repo mapping file, I believe. But I don't see anything abnormal or hardcoded there, plugins are allowed to define their URL mappings. I just don't see why it should be disallowed to override (and it wasn't until Grails 4). Also where do you see any hints of discontinuation? – andysh Apr 06 '21 at 14:12
  • Yes you are right. It wasn't disallowed until they brought it in-house recently for the 4.0 version and did a sloppy rewrite for it. Now it is bugged. They have like 3-4 guys maintaining ALL the plugins now so don't expect them to be getting to those 4.0 bugs anytime soon. I'd suggest just switching back to 3.0 til they get their sh*t together – Orubel Apr 06 '21 at 19:23