Assume I have the following Domain class:
import grails.rest.Resource
@Resource(formats=['json'], uri='/api/book')
class Book {
String name
static belongsTo = [user: User]
}
I have defined spring security interceptUrlMap in Config.groovy to restrict url access:
'/api/book': ['ROLE_USER']
Lets assume that there are two books and two users in the system and book with id 1 belongs to user 1 and the second book belongs to user 2. User 1 is logged in and the following request should return book 1 (which it does):
localhost:8080/myapp/api/book/1
but if the same user makes a request to the following resource:
localhost:8080/myapp/api/book/2
I want the rest API to return an empty array or "access denied". How do I achieve this? I need an approach there all request types i.e. GET/POST/PUT/DELETE are taken care of.
Solved this issue by generating the corresponding web-service controller:
grails generate-controller Book
And added restriction for every actions, i.e. Index, Show, Save, Update, Delete.
For example the Show action which is used to GET a resource:
localhost:8080/myapp/api/book/1
is changed to look as the following code:
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class BookController {
def springSecurityService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
Code omitted...
def show(Book bookInstance) {
if(bookInstance == null){
notFound()
return
}
def user = springSecurityService.currentUser
if(bookInstance.user.id == user.id) {
respond bookInstance
return
}
notFound()
}
Code omitted...
}
Grails version: 2.4.4