Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPSPRINGSECURITYCORE-78: spring-security-core doesn't work with mongodb grails plugin #314

Closed
graemerocher opened this issue May 10, 2011 · 5 comments

Comments

@graemerocher
Copy link
Member

Original Reporter: bond
Environment: Ubuntu 11.04, Grails 1.3.7, Mongo DB plugin:1.0.M5, MongoDB:1.8.0
Version: Grails-Spring-Security-Core 1.1.1
Migrated From: http://jira.grails.org/browse/GPSPRINGSECURITYCORE-78

Steps to reproduce:

Create a sample app
uninstall hibernate plugin
install spring-security-core and mongodb plugin

Add a line in the User, Role and UserRole domain classes which is
--> static mapWith = "mongo" <--

That's all issue run-app and goto the login controller and login you'll get the stack trace below

Stacktrace observed:

org.springframework.beans.NotWritablePropertyException: Invalid property 'authorities' of bean class [com.testapp.User]: Bean property 'authorities' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1024)

at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:880)

at org.springframework.datastore.mapping.engine.EntityAccess.setProperty(EntityAccess.java:69)

at org.springframework.datastore.mapping.engine.NativeEntryEntityPersister$NativeEntryModifyingEntityAccess.setProperty(NativeEntryEntityPersister.java:844)

at org.springframework.datastore.mapping.engine.NativeEntryEntityPersister.refreshObjectStateFromNativeEntry(NativeEntryEntityPersister.java:269)

at org.springframework.datastore.mapping.engine.NativeEntryEntityPersister.createObjectFromNativeEntry(NativeEntryEntityPersister.java:249)

at org.springframework.datastore.mapping.mongo.query.MongoQuery$MongoResultList.convertDBObject(MongoQuery.java:658)

at org.springframework.datastore.mapping.mongo.query.MongoQuery$MongoResultList.get(MongoQuery.java:648)

at org.springframework.datastore.mapping.query.Query.singleResult(Query.java:497)

at org.springframework.datastore.mapping.query.Query$singleResult.call(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)

at org.grails.datastore.gorm.GormStaticApi$13.doInSession(GormStaticApi.groovy:448)

at org.grails.datastore.gorm.SessionCallback$doInSession.call(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)

at org.grails.datastore.gorm.SessionCallback$doInSession.call(Unknown Source)

at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:37)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)

at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)

at org.grails.datastore.gorm.GormStaticApi.findWhere(GormStaticApi.groovy:441)

at org.grails.datastore.gorm.GormStaticApi$findWhere.callCurrent(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:153)

at org.grails.datastore.gorm.GormStaticApi.findWhere(GormStaticApi.groovy:429)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)

at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058)

at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)

at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:793)

at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:776)

at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:163)

at org.grails.datastore.gorm.StaticMethodInvokingClosure.call(GormEnhancer.groovy:245)

at org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod.invoke(ClosureStaticMetaMethod.java:59)

at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce.invoke(StaticMetaMethodSite.java:148)

at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:88)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)

at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService$_loadUserByUsername_closure1.doCall(GormUserDetailsService.groovy:53)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)

at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058)

at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)

at groovy.lang.Closure.call(Closure.java:282)

at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:51)

at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:82)

at $Proxy15.doInTransaction(Unknown Source)

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:188)

at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)

at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:516)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)

at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058)

at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070)

at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)

at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:793)

at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:776)

at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:163)

at org.grails.datastore.gorm.StaticMethodInvokingClosure.call(GormEnhancer.groovy:245)

at org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod.invoke(ClosureStaticMetaMethod.java:59)

at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce.invoke(StaticMetaMethodSite.java:148)

at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:88)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)

at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:52)

at org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService$loadUserByUsername.callCurrent(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:153)

at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:70)

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:378)

at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79)

at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)

at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)

at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)

at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:167)

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.filter.GrailsReloadServletFilter.doFilterInternal(GrailsReloadServletFilter.java:104)

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.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.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 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.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:662)
@graemerocher
Copy link
Member Author

bond said:
There is a work around for this don't know if this implementation is correct or not but it worked:

{code:title=/domain/.User.groovy|borderStyle=solid}
package

import org.bson.types.ObjectId

class User {
/*
* Include the BSON ObjectId type if you do not include this
* the mongo gorm will include one for you (Integer based) which
* is not preferable for MongoDB database
*/
ObjectId id
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired

/* 
 * Changes to be made and remove the autogenerated setter 
 * which is generated with `grails s2-quickstart com.example User Role` (for example)
 */
Set<Role> authorities

/* 
 * Include this in every domain class generated by spring security
 * if you do not include this it will search for hibernate to persist it
 */
static mapWith = 'mongo'

static embedded = ['authorities']
/* 
 * End of changes
 */

static constraints = {
    username blank: false, unique: true
    password blank: false
}

static mapping = {
    password column: '`password`'
}

}
{code}

@graemerocher
Copy link
Member Author

bond said:
There are quite a lot of String based queries here and there I forgot to mention that most of them don't work with mongodb plugin

@graemerocher
Copy link
Member Author

alexander_riss_xing said:
i am using the morphia plugin with grails und spring-security and it is working fine even with removing the hibernate plugin. You only need this UserDetailsService class to handle the lookups:

{code:title=UserController|borderStyle=solid}
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException

/**

  • user lookup service for SPRING Security
  • slightly adapted for MongoDB

*/
class UserDetailsService implements GrailsUserDetailsService {

UserDetails loadUserByUsername(String username) {
loadUserByUsername(username, true)
}

UserDetails loadUserByUsername(String username, boolean loadRoles) {
def user = SecUser.findByUsername(username)
if(!user) {
throw new UsernameNotFoundException('User not found: ', username)
}

def authorities = user.authorities?.collect { new GrantedAuthorityImpl(it.authority) }
if(authorities?.size() == 0) authorities = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

new GrailsUser(username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities, user.id)

}
}

{code}

@graemerocher
Copy link
Member Author

bond said:
I was specifically pointing out mongodb plugin not mongodb-morphia. I was using this plugin since it has some GORM style of coding and a plugin backed by SpringSource developers, no other specific reason.

@graemerocher
Copy link
Member Author

burtbeckwith said:
Version 1.2 works with the upcoming M7 release of the MongoDB plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants