У меня есть стандартное веб-приложение Grails, использующее Spring Security, и я хочу предоставить небольшую его часть как REST API, используя подключаемый модуль spring-security-rest (версия 1.5.1). Кажется, все настроено правильно, но любой запрос, который я делаю, возвращается с ошибкой 403, говорящей «insufficient_scope». Ни в одном из документов ничего об этом нет, поэтому я надеюсь, что кто-то может помочь. Вот моя установка с использованием Grails 2.4.4:
config.groovy:
grails.plugin.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
grails.plugin.springsecurity.ui.register.defaultRoleNames = ['ROLE_USER']
grails.plugin.springsecurity.logout.postOnly = false
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.luncho.UserLuncho'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.luncho.UserLunchoRole'
grails.plugin.springsecurity.authority.className = 'com.luncho.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['ROLE_USER'],
'/user/create': ['ROLE_ADMIN'],
'/register/*': ['permitAll'],
'/login/*': ['permitAll'],
'/logout/*': ['permitAll'],
'/index.gsp': ['permitAll'],
'/plugins/**': ['permitAll'],
'/assets/**': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll'],
'/restaurant/**': ['ROLE_USER']
]
Я могу аутентифицироваться просто отлично, и я получаю обратно токен на предъявителя. Однако следующая команда curl (с реальным токеном вместо «my_token») всегда возвращает ошибку недостаточного_скопа:
curl -i http://localhost:8080/lunchoweb/api/restaurant -H "Авторизация: Предъявитель my_token"
Также стоит отметить, что методы контроллера содержатся в отдельном контроллере под названием RestaurantAPIController. Сейчас это очень просто:
class RestaurantAPIController {
def getAllRestaurants() {
render Restaurant.findAll() as JSON
}
}
с сопоставлением URL:
// REST end points
"/api/restaurant" {
controller="restaurantAPI"
action = "getAllRestaurants"
}
Что дает?