Closed GoogleCodeExporter closed 8 years ago
Hi Bobby,
You should be able to protect JAX-RS resources like any other Grails web
application because all requests targeted at JAX-RS resources are dispatched by
the JaxrsController, a Grails controller which is part of the grails-jaxrs
plugin. So you should be able to use a security framework or plugin of your
choice.
If that security plugin makes use of Grails filters, an integration with
grails-jaxrs applications is possible too as described in
http://code.google.com/p/grails-jaxrs/wiki/AdvancedFeatures#Applying_filters.
I personally didn't use spring-security with grails-jaxrs yet so I don't know
if there are any issues with a combined usage. Do you see grails-jaxrs specific
exceptions when using spring-security? Just post a stacktrace if you want.
Original comment by krass...@googlemail.com
on 2 Feb 2011 at 3:58
[deleted comment]
Yup, I figured I could use a filter, but was just trying to use the config
options provided by spring-security.
$ grails create-plugin sampleplugin
$ cd sampleplugin
$ grails create-domain-class com.example.sampleplugin.Book
$ vi grails-app/domain/com/example/sampleplugin/Book.groovy
package com.example.sampleplugin
class Book {
String title
String author
static constraints = {
title(blank: false)
author(blank: false)
}
}
$ grails package-plugin
$ cd ..
$ grails create-app sampleapp
$ cd sampleapp
$ grails install-plugin ../sampleplugin/grails-sampleplugin-0.1.zip
$ grails install-plugin spring-security-core
$ grails s2-quickstart com.example.sampleapp User Role
$ vi grails-app/conf/BootStrap.groovy
import com.example.sampleapp.User
import com.example.sampleapp.Role
import com.example.sampleapp.UserRole
import com.example.sampleplugin.Book
class BootStrap {
def springSecurityService
def init = { servletContext ->
if (!Book.count()) {
new Book(author: "Stephen King", title: "The Shining").save(failOnError: true)
new Book(author: "James Patterson", title: "Along Came a Spider").save(failOnError: true)
}
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
String password = springSecurityService.encodePassword('password')
def testUser = new User(username: 'me', enabled: true, password: password)
testUser.save(flush: true)
UserRole.create testUser, userRole, true
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
def destroy = {
}
}
$ grails install-plugin jaxrs
$ grails generate-resources com.example.sampleplugin.Book
$ vi grails-app/conf/Config.groovy
Add these two lines to the bottom.
grails.plugins.springsecurity.useBasicAuth = true
grails.plugins.springsecurity.basic.realmName = "Sample App"
Then I tried both of these techniques.
Technique #1, static rules in grails-app/conf/Config.groovy
grails.plugins.springsecurity.controllerAnnotations.staticRules = [
'/api/**': ['ROLE_USER']
]
Technique #2, url map in grails-app/conf/Config.groovy
grails.plugins.springsecurity.interceptUrlMap = [
'/api/**': ['ROLE_USER']
]
$ grails run-app
$ open http://localhost:8080/sampleapp/api/book
There's no security, our sample data shows up in XML response with no Basic
Authentication needed.
Original comment by bobbywar...@gmail.com
on 2 Feb 2011 at 5:12
Does it work with other Grails artifacts that are not JAX-RS resources e.g. a
simple Grails controller?
Original comment by krass...@googlemail.com
on 2 Feb 2011 at 6:07
After a little more RTFM'ing, determined I just missed a step. You need these
two lines in Config.groovy too:
import grails.plugins.springsecurity.SecurityConfigType
grails.plugins.springsecurity.securityConfigType =
SecurityConfigType.InterceptUrlMap
Works great now! Please close this issue. Thanks! Bobby
Original comment by bobbywar...@gmail.com
on 2 Feb 2011 at 6:32
Ah, ok. Glad that it's working now.
Original comment by krass...@googlemail.com
on 2 Feb 2011 at 6:34
Hi all,
using jaxrs with spring-security-core I noticed the jaxrsFilter comes before
the springSecurityFilterChain. This lead to rest service calls miss security
checks. This is probably due to the fact that both plugins add their servlet
filters to the web.xml through a call to .doWithWebDescriptor(). This approach
doesn't guarantee any relative insertion order.
But I've seen that adding 'spring-security-core' to the loadAfter array into
JaxrsGrailsPlugin.groovy (i.e. def loadAfter =
['controllers','services','spring-security-core'])
solves the problem (as per
http://grails.org/doc/latest/guide/12.%20Plug-ins.html#12.10%20Understanding%20P
lug-in%20Load%20Order ).
Could it be considered a patch for the mainstream plugin version?
Cheers
Davide
Original comment by davide.cavestro
on 9 Jun 2011 at 12:22
@davide
the downside of this approach is that it doesn't scale when other/further
plugins are used that add further filters to web.xml: with every other plugin
that needs some special consideration, we'd need to modify the loadAfter array.
Also, the plugin makes then assumptions about the application configuration.
On the other hand, I currently don't know an alternative how to solve this
problem, so let's (temporarily) fix it as you've proposed. However, the ideal
solution would be that the application defines the plugin load order, but I'm
not sure if this is possible with Grails.
Original comment by krass...@googlemail.com
on 9 Jun 2011 at 6:26
Fixed and pushed to master. Can you please verify that it works?
Original comment by krass...@googlemail.com
on 9 Jun 2011 at 6:40
Hi Martin,
I can confirm your fix works like a charm.
About cleaner approaches, maybe you could search a way to modify the order of
listeners instead of simply adding it (maybe it's not so easy, as per
http://jira.grails.org/browse/GRAILS-3107 ) but I'm afraid since you're tied to
filter chains you always ends up with a way to say that your filter should be
first or after other ones (though it's surely less invasive that forcing the
entire plugins load order).
A working example could be taken from spring-security docs, that shows some
ways to register filters with relative positions
(http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/guide/16
%20Filters.html)
Cheers
Davide
Original comment by davide.cavestro
on 10 Jun 2011 at 2:28
Original comment by krass...@googlemail.com
on 30 Aug 2011 at 9:25
Hello guys,
i am facing the same issue. i am using grails 2.0.4 spring-security-core plugin
and jax-rs 0.6.
i found "spring-security-core" in loadAfter(JaxrsGrailsPlugin.groovy)
def loadAfter = ['controllers','services','spring-security-core']
But my resource are not secured yet.
I am using @secured i.e annotation based spring-security
Code Snippet to avail spring-security:
Config.grovvy:
grails.plugins.springsecurity.securityConfigType = "Annotation"
import static org.grails.jaxrs.response.Responses.*
import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.Produces
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.POST
import javax.ws.rs.core.Response
import grails.plugins.springsecurity.Secured
CategoryCollectionResource.groovy:
@Path('/api/category')
@Consumes(['application/json'])
@Produces(['application/json'])
@Secured(['ROLE_ADMIN','ROLE_USER'])
class CategoryCollectionResource {
@POST
Response create(Category dto) {
created dto.save()
}
@GET
Response readAll() {
ok Category.findAll()
}
@Path('/{id}')
CategoryResource getResource(@PathParam('id') String id) {
new CategoryResource(id:id)
}
}
CategoryResource.groovy:
import static org.grails.jaxrs.response.Responses.*
import javax.ws.rs.Consumes
import javax.ws.rs.DELETE
import javax.ws.rs.GET
import javax.ws.rs.Produces
import javax.ws.rs.PUT
import javax.ws.rs.core.Response
import org.grails.jaxrs.provider.DomainObjectNotFoundException
import grails.plugins.springsecurity.Secured
@Secured(['ROLE_ADMIN','ROLE_USER'])
@Consumes(['application/xml','application/json'])
@Produces(['application/xml','application/json'])
class CategoryResource {
def id
@GET
Response read() {
def obj = Category.get(id)
if (!obj) {
throw new DomainObjectNotFoundException(Category.class, id)
}
ok obj
}
@PUT
Response update(Category dto) {
def obj = Category.get(id)
if (!obj) {
throw new DomainObjectNotFoundException(Category.class, id)
}
obj.properties = dto.properties
ok obj
}
@DELETE
void delete() {
def obj = Category.get(id)
if (obj) {
obj.delete()
}
}
}
Controller are secured but Jax-rs resources are not.
Can anybody help me on this?
Thanks
Utsav
Original comment by jimuliau...@gmail.com
on 20 Jun 2012 at 9:36
Morning Utsav,
I'm seeing the same behavior as you described when using Annotation based
security. If you use the interceptUrlMap, it should work.
With that, I think that the right place to ask this question would be on the
forum or to open a new issue with the problem. This specific issue was
addressed in that it is possible to secure the resource using the
interceptUrlMap.
patrick
Original comment by psg9...@gmail.com
on 24 Jul 2012 at 3:21
Should have search before my first
post...http://code.google.com/p/grails-jaxrs/issues/detail?id=65
Original comment by psg9...@gmail.com
on 24 Jul 2012 at 3:23
import grails.plugins.springsecurity.SecurityConfigType
grails.plugins.springsecurity.securityConfigType =
SecurityConfigType.InterceptUrlMap
worked like a champ, thx.
Original comment by jmhed...@gmail.com
on 9 Nov 2012 at 7:17
Original issue reported on code.google.com by
bobbywar...@gmail.com
on 2 Feb 2011 at 3:23