grails spring-security-oauth-facebook:0.2
Posted
技术标签:
【中文标题】grails spring-security-oauth-facebook:0.2【英文标题】: 【发布时间】:2015-02-12 11:18:31 【问题描述】:我一直在尝试实现 grails 插件 spring-security-oauth-facebook:0.2 并且没有从 spring 插件获得成功的身份验证。我可以访问 facebook,成功输入我的凭据,但是当 facebook 重定向回我的本地站点时,我获得了分配的标准 ROLE_ANONYMOUS 并重定向到登录页面。通过 Spring Security 的标准站点登录完美运行。
I'm using Grails 2.4.4
BuildConfig.groovy applicable plugins are:
compile ':spring-security-core:2.0-RC4'
compile ":spring-security-oauth:2.1.0-RC4"
compile ":spring-security-ui:1.0-RC2"
compile ':spring-security-oauth-facebook:0.2'
Config.groovy:
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.myapp.domain.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.myapp.domain.UserRole'
grails.plugin.springsecurity.authority.className = 'com.myapp.domain.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/assets/**': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll'],
'/login/**': ['permitAll'],
'/logout/**': ['permitAll'],
'/register/**': ['permitAll'],
'/oauth/**': ['permitAll'],
'/oauth/facebook/**': ['permitAll']
]
def appName = 'myapp'
def baseURL = grails.serverURL ?: "(myurl):$System.getProperty('server.port', '8050')/$appName"
oauth
debug = true
providers
facebook
api = gweb.FaceBookCustomAPI
key = 'my-key'
secret = 'my-seceret'
successUri = "/oauth/facebook/success"
failureUri = "/oauth/facebook/failure"
callback = "$baseURL/oauth/facebook/callback"
// Added by the Spring Security OAuth plugin:
grails.plugin.springsecurity.oauth.domainClass = 'com.myapp.domain.OAuthID'
当我点击 facebook 链接登录时(网址:/oauth/facebook/authenticate?redirectUrl=),我得到以下日志:
....matcher.AntPathRequestMatcher Request '/oauth/facebook/authenticate' matched by universal pattern '/**'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
context.HttpSessionSecurityContextRepository No HttpSession currently exists
context.HttpSessionSecurityContextRepository No SecurityContext was available from the HttpSession: null. A new one will be created.
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 5 of 8 in additional filter chain; firing Filter: 'GrailsRememberMeAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 6 of 8 in additional filter chain; firing Filter: 'GrailsAnonymousAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
intercept.FilterSecurityInterceptor Secure object: FilterInvocation: URL: /oauth/facebook/authenticate?redirectUrl=; Attributes: [permitAll]
intercept.FilterSecurityInterceptor Previously Authenticated: grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken@dc4337e: Principal: org.springframework.security.core.userdetails.User@dc730200: Username: __grails.anonymous.user__; Password: [PROTECTED]; Enabled: false; AccountNonExpired: false; credentialsNonExpired: false; AccountNonLocked: false; Granted Authorities: ROLE_ANONYMOUS; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
hierarchicalroles.RoleHierarchyImpl getReachableGrantedAuthorities() - From the roles [ROLE_ANONYMOUS] one can reach [ROLE_ANONYMOUS] in zero or more steps.
intercept.FilterSecurityInterceptor Authorization successful
intercept.FilterSecurityInterceptor RunAsManager did not change Authentication object
web.FilterChainProxy /oauth/facebook/authenticate?redirectUrl= reached end of additional filter chain; proceeding with original chain
gweb.FaceBookCustomAPI AuthorizationUrl: facebook.com/dialog/oauth?client_id=123MYCLIENTID123&redirect_uri=http%3A%2F%2Flocal.myappname.com%3A8050%2Fgweb%2Foauth%2Ffacebook%2Fcallback api key: 123MYCLIENTID123 seceret: d3996df187347f9f6b8021dd223acdf5
access.ExceptionTranslationFilter Chain processed normally
context.HttpSessionSecurityContextRepository SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
context.SecurityContextPersistenceFilter SecurityContextHolder now cleared, as request processing completed
matcher.AntPathRequestMatcher Request '/oauth/facebook/callback' matched by universal pattern '/**'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
context.HttpSessionSecurityContextRepository HttpSession returned null object for SPRING_SECURITY_CONTEXT
context.HttpSessionSecurityContextRepository No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@28b44fe3. A new one will be created.
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 5 of 8 in additional filter chain; firing Filter: 'GrailsRememberMeAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 6 of 8 in additional filter chain; firing Filter: 'GrailsAnonymousAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
intercept.FilterSecurityInterceptor Secure object: FilterInvocation: URL: /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw; Attributes: [permitAll]
intercept.FilterSecurityInterceptor Previously Authenticated: grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken@dc6f3f8: Principal: org.springframework.security.core.userdetails.User@dc730200: Username: __grails.anonymous.user__; Password: [PROTECTED]; Enabled: false; AccountNonExpired: false; credentialsNonExpired: false; AccountNonLocked: false; Granted Authorities: ROLE_ANONYMOUS; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@255f8: RemoteIpAddress: 127.0.0.1; SessionId: AE8351B5D34F45ED370ED63F6FB7C3A8; Granted Authorities: ROLE_ANONYMOUS
hierarchicalroles.RoleHierarchyImpl getReachableGrantedAuthorities() - From the roles [ROLE_ANONYMOUS] one can reach [ROLE_ANONYMOUS] in zero or more steps.
intercept.FilterSecurityInterceptor Authorization successful
intercept.FilterSecurityInterceptor RunAsManager did not change Authentication object
web.FilterChainProxy /oauth/facebook/callback?code=AQCgtBI6VeUcWF7xUN5G4n9IU3Owyjm9HiM3OiPWvI2-w5FILyeqNEYPKOgDVGvyLShnNBcwzTjgPuJLls-9VFXrVCQrH4nWOzbUmUukoJVusMQUXhX6fjO_XY8a21VuJh9RkpTg-isZCSSEe86Nz9rbF4c9NK_-GRUa0onNwAbzvMSUG-IqzfzZaxyFoDcBWxS6VDuZrqVyFKEiTa0mgDjRgCZ077KMLdWJn8tWB8E9jR59CnWrvpXvfpcHz4w5NWmfmKE7Johh9ymYn8YeLr0L_7OlSydDQAyO-ERJf2JTvraQzNY0e-CA2SxTWL4lVxw reached end of additional filter chain; proceeding with original chain
gweb.FaceBookCustomAPI accessTokenEndpoint: https://graph.facebook.com/oauth/access_token
access.ExceptionTranslationFilter Chain processed normally
context.HttpSessionSecurityContextRepository SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
context.SecurityContextPersistenceFilter SecurityContextHolder now cleared, as request processing completed
matcher.AntPathRequestMatcher Request '/oauth/facebook/success' matched by universal pattern '/**'
web.FilterChainProxy /oauth/facebook/success at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
context.HttpSessionSecurityContextRepository HttpSession returned null object for SPRING_SECURITY_CONTEXT
context.HttpSessionSecurityContextRepository No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@28b44fe3. A new one will be created.
web.FilterChainProxy /oauth/facebook/success at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
web.FilterChainProxy /oauth/facebook/success at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/success at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
web.FilterChainProxy /oauth/facebook/success at position 5 of 8 in additional filter chain; firing Filter: 'GrailsRememberMeAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/success at position 6 of 8 in additional filter chain; firing Filter: 'GrailsAnonymousAuthenticationFilter'
web.FilterChainProxy /oauth/facebook/success at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
web.FilterChainProxy /oauth/facebook/success at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
intercept.FilterSecurityInterceptor Secure object: FilterInvocation: URL: /oauth/facebook/success; Attributes: [_DENY_]
intercept.FilterSecurityInterceptor Previously Authenticated: grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken@dc6f3f8: Principal: org.springframework.security.core.userdetails.User@dc730200: Username: __grails.anonymous.user__; Password: [PROTECTED]; Enabled: false; AccountNonExpired: false; credentialsNonExpired: false; AccountNonLocked: false; Granted Authorities: ROLE_ANONYMOUS; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@255f8: RemoteIpAddress: 127.0.0.1; SessionId: AE8351B5D34F45ED370ED63F6FB7C3A8; Granted Authorities: ROLE_ANONYMOUS
hierarchicalroles.RoleHierarchyImpl getReachableGrantedAuthorities() - From the roles [ROLE_ANONYMOUS] one can reach [ROLE_ANONYMOUS] in zero or more steps.
access.ExceptionTranslationFilter Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager.decide(AuthenticatedVetoableDecisionManager.java:47)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
savedrequest.HttpSessionRequestCache DefaultSavedRequest added to Session: DefaultSavedRequest[http://local.myappname.com:8050/gweb/oauth/facebook/success]
access.ExceptionTranslationFilter Calling Authentication entry point.
web.DefaultRedirectStrategy Redirecting to 'local.myappname.com:8050/gweb/login/auth'
context.HttpSessionSecurityContextRepository SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
context. ..... this seems to repeat a couple more times...
我很茫然,好像 Facebook 身份验证正在工作。我可以终止我的 FB 会话/从我的个人资料中删除应用程序,当我尝试从我的站点验证 URL 时,一切似乎都正常,但我总是被重定向到带有上述日志的登录屏幕。我是否遗漏了实施的某些部分?
【问题讨论】:
所以当 FB 回复回调 url 时,处理回调的代码必须重新认证用户。您必须在某处保存 fb 信息并以某种方式与您自己的用户绑定。我所做的是捕获 FB uid,将其保存为关联到我自己的用户,然后调用以下命令: springSecurityService.reauthenticate("some user name") 我的所有用户都有一个唯一的用户名。 【参考方案1】:几天来我一直在遇到同样的问题,但我想我已经解决了:答案是插件似乎没有正确处理“注释”securityConfigType。
所以,为了让它工作,你需要改变: grails.plugin.springsecurity.securityConfigType = "注解" 到 grails.plugin.springsecurity.securityConfigType = "InterceptUrlMap"
然后您需要将 grails.plugin.springsecurity.controllerAnnotations.staticRules 配置转换为 grails.plugin.springsecurity.interceptUrlMap,然后将基于注释的安全性从控制器移植到此配置。
这是我可以让这个插件真正工作的唯一方法。希望这会有所帮助。
【讨论】:
以上是关于grails spring-security-oauth-facebook:0.2的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Grails 之外使用 Grails 验证?如何?
Grails - grails.converters.JSON - 删除类名