grails acegi 迁移到 spring-security-core

Posted

技术标签:

【中文标题】grails acegi 迁移到 spring-security-core【英文标题】:grails acegi migration to spring-security-core 【发布时间】:2011-12-24 10:58:05 【问题描述】:

我从 acegi 迁移到 spring-security-core 的过程很糟糕。当我尝试登录时,我不断收到以下错误:

The specified user domain class 'com.xxx.Person' is not a domain class

我的 Config.groovy 如下:

grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.xxx.Person'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.xxx.PersonRole'
grails.plugins.springsecurity.authority.className = 'com.xxx.Role'
grails.plugins.springsecurity.requestMap.className = 'com.xxx.Requestmap'
grails.plugins.springsecurity.securityConfigType = 'Requestmap'
grails.plugins.springsecurity.cacheUsers=false
grails.plugins.springsecurity.ui.register.defaultRoleNames=['ROLE_DEFAULT_USER']
grails.plugins.springsecurity.ui.register.emailFrom = 'xxx@example.com'
grails.plugins.springsecurity.useSecurityEventListener = true

打开debug 'org.springframework.security' 后会得到以下信息:

2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - Converted URL to lowercase, from: '/web-inf/grails-app/views/layouts/login.gsp'; to: '/web-inf/grails-app/views/layouts/login.gsp'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - Candidate is: '/web-inf/grails-app/views/layouts/login.gsp'; pattern is /**; matched=true
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 5 of 8 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG rememberme.RememberMeAuthenticationFilter  - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6fa90ed4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 42FC01C857E346E77C619175E0C44927; Granted Authorities: ROLE_ANONYMOUS'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG authentication.AnonymousAuthenticationFilter  - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6fa90ed4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 42FC01C857E346E77C619175E0C44927; Granted Authorities: ROLE_ANONYMOUS'
2011-12-24 05:56:04,748 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2011-12-24 05:56:04,768 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2011-12-24 05:56:04,768 [http-8080-3] DEBUG web.FilterChainProxy  - /WEB-INF/grails-app/views/layouts/login.gsp reached end of additional filter chain; proceeding with original chain
2011-12-24 05:56:04,776 [http-8080-3] DEBUG access.ExceptionTranslationFilter  - Chain processed normally
2011-12-24 05:56:04,777 [http-8080-3] DEBUG access.ExceptionTranslationFilter  - Chain processed normally
2011-12-24 05:56:04,777 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - SecurityContext is empty or anonymous - context will not be stored in HttpSession. 
2011-12-24 05:56:04,777 [http-8080-3] DEBUG context.SecurityContextPersistenceFilter  - SecurityContextHolder now cleared, as request processing completed
2011-12-24 05:56:13,946 [http-8080-3] DEBUG web.FilterChainProxy  - Converted URL to lowercase, from: '/j_spring_security_check'; to: '/j_spring_security_check'
2011-12-24 05:56:13,946 [http-8080-3] DEBUG web.FilterChainProxy  - Candidate is: '/j_spring_security_check'; pattern is /**; matched=true
2011-12-24 05:56:13,946 [http-8080-3] DEBUG web.FilterChainProxy  - /j_spring_security_check at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2011-12-24 05:56:13,946 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2011-12-24 05:56:13,946 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@7450fd85. A new one will be created.
2011-12-24 05:56:13,946 [http-8080-3] DEBUG web.FilterChainProxy  - /j_spring_security_check at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
2011-12-24 05:56:13,946 [http-8080-3] DEBUG web.FilterChainProxy  - /j_spring_security_check at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
2011-12-24 05:56:13,947 [http-8080-3] DEBUG authentication.ProviderManager  - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2011-12-24 05:56:13,959 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - SecurityContext is empty or anonymous - context will not be stored in HttpSession. 
2011-12-24 05:56:13,959 [http-8080-3] DEBUG context.SecurityContextPersistenceFilter  - SecurityContextHolder now cleared, as request processing completed
2011-12-24 05:56:13,961 [http-8080-3] ERROR [/xxx].[default]  - Servlet.service() for servlet default threw exception
java.lang.RuntimeException: The specified user domain class 'com.xxx.Person' is not a domain class
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
    at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:71)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:81)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:198)
    at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:53)
    at org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService$loadUserByUsername.callCurrent(Unknown Source)
    at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:76)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:86)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:129)
    at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:130)
    at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:97)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:40)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:65)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:185)
    at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:159)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Thread.java:722)
2011-12-24 05:56:14,151 [http-8080-3] DEBUG web.FilterChainProxy  - Converted URL to lowercase, from: '/grails-errorhandler'; to: '/grails-errorhandler'
2011-12-24 05:56:14,151 [http-8080-3] DEBUG web.FilterChainProxy  - Candidate is: '/grails-errorhandler'; pattern is /**; matched=true
2011-12-24 05:56:14,151 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2011-12-24 05:56:14,152 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@7450fd85. A new one will be created.
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 3 of 8 in additional filter chain; firing Filter: 'RequestHolderAuthenticationFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 5 of 8 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG authentication.AnonymousAuthenticationFilter  - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6fa90ed4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 42FC01C857E346E77C619175E0C44927; Granted Authorities: ROLE_ANONYMOUS'
2011-12-24 05:56:14,152 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2011-12-24 05:56:14,153 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2011-12-24 05:56:14,153 [http-8080-3] DEBUG intercept.FilterSecurityInterceptor  - Public object - authentication not attempted
2011-12-24 05:56:14,153 [http-8080-3] DEBUG web.FilterChainProxy  - /grails-errorhandler reached end of additional filter chain; proceeding with original chain
2011-12-24 05:56:14,212 [http-8080-3] DEBUG access.ExceptionTranslationFilter  - Chain processed normally
2011-12-24 05:56:14,212 [http-8080-3] DEBUG context.HttpSessionSecurityContextRepository  - SecurityContext is empty or anonymous - context will not be stored in HttpSession. 
2011-12-24 05:56:14,212 [http-8080-3] DEBUG context.SecurityContextPersistenceFilter  - SecurityContextHolder now cleared, as request processing completed

更新! 好像我的grails.plugins.springsecurity.userLookup.userDomainClassName 无法实现 java 接口 :(。当我删除接口时一切正常。

【问题讨论】:

【参考方案1】:

问题是我的 Person 类实现了一个接口 (IPerson)。我已经删除了界面并且它可以工作。

【讨论】:

以上是关于grails acegi 迁移到 spring-security-core的主要内容,如果未能解决你的问题,请参考以下文章

使用 Grails 和 Acegi 自动登录

Grails Spring Security 插件密码问题

在 grails + acegi 中测试 securityConfig 映射

Grails + Acegi:如何处理密码更新?登录用户与未登录用户

使用 Acegi 和 Grails 通过 LDAP 进行身份验证时出现 PartialResultException

Grails - Acegi:自定义身份验证方法