Reputation: 360
Good morning Community.
I use Grails for a backend app and therefore want to check if users are allowed to do the requested action.
So I call checkPermission() at the begin and redirect to the index page if user is not allowed. But I'm occuring this error:
Cannot issue a redirect(..) here. A previous call to redirect(..) has already redirected the response.
Extract from my source:
def test() {
println("test()")
checkPermission([TaskXYZ])
println("AfterCheck")
redirect(action: "profile", params: [lang: params.lang])
}
private checkPermission(def tasks) {
println("checkPermission()")
if ( ! userService.isAllowed(tasks)) {
println("NotAllowed")
flash.error = message(code: "msg.actionIsNotAllowed")
redirect(action: "index", params: [lang: params.lang])
return false
}
}
Output:
test()
checkPermission()
NotAllowed
AfterCheck
So the redirect doesn't work from the private method and return false causes the return to the called method.
What can I do alternatively? I considered beforeInterceptor, but I need to pass custom parameters for every method.
Thanks, Rob.
Upvotes: 0
Views: 986
Reputation: 24776
The problem you are encountering is that issuing a redirect doesn't stop the execution of the controller method/action. After your redirect
within checkPermission
your controller code continues to execute after checkPermission
and is encountering the next redirect
. You need to return
from your controller if your checkPermission
is to terminate the execution of the controller method/action.
For example:
...
private boolean checkPermission(def tasks) { ... }
...
if (!checkPermission([TaskXYZ])) return
...
Upvotes: 2
Reputation: 911
you can't call redirect() method twice during one request, though that's what your code is doing, but you can simply change it in numerous ways, i.e.
def test() {
boolean hasPermission = checkPermission([TaskXYZ])
if (!hasPermission) {
return ; // you have to finish the action, because you already called redirect inside checkPermission() method
}
// do further actions when permission granted
redirect(action: "profile", params: [lang: params.lang])
}
private checkPermission(def tasks) {
if ( ! userService.isAllowed(tasks)) {
return false
}
return true
}
you could also improve it so that you can make different redirects:
def test() {
boolean checkPermissionResult = checkPermission([TaskXYZ])
if (checkPermissionResult != null) {
return redirect(checkPermissionResult)
}
// do further actions when permission granted
redirect(action: "profile", params: [lang: params.lang])
}
private checkPermission(def tasks) {
if ( ! userService.isAllowed(tasks)) {
return [action: "index", params: [lang: params.lang]]
} else if (userService.userNotExists()) { // or any different situatoin
return [action: "register", params: [lang: params.lang]]
}
return null
}
Upvotes: 2