我正在尝试使用Spring安全性来创建REST API的基本示例。 我正在使用Grails插件spring-security-rest:2.0.0.M2
我试图遵循这个优秀的tutorial,并且遇到了范围不足的错误。
我正在定义一个角色ADMIN_ROLE。 成功登录后,我收到了access_token
我在ProjectController类中添加了@Secured(['ROLE_ADMIN'])
标记:
@Secured(['ROLE_ADMIN'])
class ProjectController extends RestfulController {
static responseFormats = ['json', 'xml']
ProjectController() {
super(Project)
}
def active() {
respond Project.findAllByActive(true), view: 'index'
}
}
My UrlMappings指向ProjectController: 包dk.mathmagicians.demo
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/projects"(resources:"project")
"/active"(controller: 'project', action: 'active')
"/"(view: '/index')
"500"(view: '/error')
"404"(view: '/notFound')
}
}
我已使用过滤器配置了我的application.groovy文件,如下所示
grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/assets/**', filters: 'none'],
[pattern: '/**/js/**', filters: 'none'],
[pattern: '/**/css/**', filters: 'none'],
[pattern: '/**/images/**', filters: 'none'],
[pattern: '/**/favicon.ico', filters: 'none'],
[pattern: '/api/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter']
]
当我尝试调用我的api时($ TOKEN是一个env变量,其中存储令牌用于测试目的)
curl -v -i -H "Authorization: Bearer $STOKEN" 0:8080/api/projects'
我收到403错误,范围不足:
* Trying 0.0.0.0...
* Connected to 0 (127.0.0.1) port 8080 (#0)
> GET /api/projects HTTP/1.1
> Host: 0:8080
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y
>
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Server: Apache-Coyote/1.1
Server: Apache-Coyote/1.1
< WWW-Authenticate: Bearer error="insufficient_scope"
WWW-Authenticate: Bearer error="insufficient_scope"
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Date: Mon, 10 Oct 2016 22:17:11 GMT
Date: Mon, 10 Oct 2016 22:17:11 GMT
<
* Connection #0 to host 0 left intact
{"timestamp":1476137831338,"status":403,"error":"Forbidden","message":"Access is denied","path":"/api/projects"}
我启用了调试日志记录,这里是grails应用程序的输出
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/assets/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/**/js/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/**/css/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/**/images/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/**/favicon.ico'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/api/**'
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 1 of 7 in additional filter chain; firing Filter: 'SecurityRequestHolderFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 2 of 7 in additional filter chain; firing Filter: 'MutableLogoutFilter'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/api/projects'; against '/logoff'
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 3 of 7 in additional filter chain; firing Filter: 'RestAuthenticationFilter'
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationFilter - Actual URI is /api/projects; endpoint URL is /api/login
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 4 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 5 of 7 in additional filter chain; firing Filter: 'RestTokenValidationFilter'
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Looking for bearer token in Authorization header, query string or Form-Encoded body parameter
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Found bearer token in Authorization header
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Token: eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Token found: eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Trying to authenticate the token
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Use JWT: true
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Trying to validate token eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - Successfully verified JWT
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - Trying to deserialize the principal object
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - UserDetails deserialized: grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Now is Tue Oct 11 00:17:11 CEST 2016 and token expires at Tue Oct 11 01:04:58 CEST 2016
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Expiration: 2867
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y, expiration:2867, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN, super:grails.plugin.springsecurity.rest.token.AccessToken@3afafc74: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN)
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Token authenticated. Storing the authentication result in the security context
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y, expiration:2867, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN, super:grails.plugin.springsecurity.rest.token.AccessToken@3afafc74: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN)
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Continuing the filter chain
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /api/projects at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /api/projects; Attributes: [_DENY_]
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUFdcL1RRQmgrSGRJUFVhbGZVcEU2bElXeUlVZUNNVk9cL1FGUW1RWVFzUmFLNjJHXC9kYTg5Mzd0MjVUWllxRXd3WldnR1JrUGdMK1NmdDBoOVF3Y0RhbVpYMzNLWk9XU3B1c3Q5N1wvSHk5SGx6Qm1OSHdJdGFNQytPbklvdTU5RTJxdVl3Tmhwbm10dU5uQm5XRU5rZTh5b0ZObXNEMThVcmdCVkRpa1lYNVlJOGRzb3BnTXE3VVczc1kybXBidzNPbDR4dkdIYzBTUEZKNjM3XC9sRHBYR093SUZ0WGRhZ29rdG1HTmhxREpwYTBwdXRGT3VNZHFDMldJV3FIRGZqUlpDdWtGcE9STm1GRHFCa3JVRVJnRk1zY3p1S2xMbGFDek1YSnZOTEJlVkJ0cHFBSk1wTTRiY1wvWk9rWVoxMWQrOXNTa3B3QU1kUWJxY2VIZXJ1cVlQNmpzZGZVMEpRYXE2a1dXN0tSRVY4aHp0eDR1OHVmYms0K2RGdGxnQ29rMmYzZjFQTUYxZWhlXC9ieHorTzhhQyswOEdqRWVnR3J0bE55TTFjd3Y5Zm9sQytcL3ZcLzNhdlwvcjg0UUVwTzhUTFwvOVwvSDhzcE5jNTAxbGFSTU02dEdka1MwUjJYM1RPU3I5NU1QdDlEeEd6eEpCZElmSlMxR3R4SUZNY1V0YXlXR2ZWdDQrSzRlYkd5dnJMOTVYWE92NCt0S01oR1I3SFNlMnEzTER4UXRxXC9mNzlQemt5VStpMklTeFF5WXlwTkpuQzFBdFMxcW9QdzM2UzFQZmZ2WHlDTVBmK1M5TElGejNFZ01BQUE9PSIsInN1YiI6IkRvbmFsZCIsInJvbGVzIjpbIlJPTEVfQURNSU4iXSwiZXhwIjoxNDc2MTQwNjk4LCJpYXQiOjE0NzYxMzcwOTh9.wSwQad4POS77y61ULiTeOWEjxGcSv7xuDRryfWpZa-Y, expiration:2867, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN, super:grails.plugin.springsecurity.rest.token.AccessToken@3afafc74: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@7a593596: Username: Donald; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN)
DEBUG org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl - getReachableGrantedAuthorities() - From the roles [ROLE_ADMIN] one can reach [ROLE_ADMIN] in zero or more steps.
DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)
at grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager.decide(AuthenticatedVetoableDecisionManager.groovy:50)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at javax.servlet.FilterChain$doFilter.call(Unknown Source)
at grails.plugin.springsecurity.rest.RestTokenValidationFilter.processFilterChain(RestTokenValidationFilter.groovy:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:190)
at grails.plugin.springsecurity.rest.RestTokenValidationFilter.doFilter(RestTokenValidationFilter.groovy:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at javax.servlet.FilterChain$doFilter.call(Unknown Source)
at grails.plugin.springsecurity.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.groovy:143)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/assets/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/**/js/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/**/css/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/**/images/**'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/**/favicon.ico'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/error'; against '/api/**'
DEBUG org.springframework.security.web.FilterChainProxy - /error has no matching filters
对于我做错了什么的任何想法? 有关如何解决此错误的任何提示?
最佳阿形
使用ProjectController和UrlMapping更新了问题
答案 0 :(得分:1)
我已经解决了这个问题。 结论是,如果您尝试访问的资源不存在,则可以获得Insufficient_scope错误。
事实证明,grails中的s2-quickstart命令正在application.groovy
文件中生成一些代码。
我使用模式pattern: '/api/**',
将过滤器添加到filterChain地图中,而我的api则驻留在模式/
上。
获得的经验:
如何打开spring安全类的调试级别日志:将以下内容添加到Logback.groovy文件中:
logger(“org.springframework.security”,DEBUG,['STDOUT'],false) logger(“grails.plugin.springsecurity”,DEBUG,['STDOUT'],false) 记录器(“org.pac4j”,DEBUG,['STDOUT'],false)
如果您尝试访问的资源不存在,您可能会收到Insufficient_scope错误