I´ve got some weird behaviour using Grails 2.2.4, SpringSecurityCore 2.0 RC in Production on a Tomcat 7 with Groovy Compiler 2.0.8, Java 1.7.0.
We build a plugin which realize basic behaviors. We included the SpringSecurityCore plugin in it with a person class named User. There are some domain classes in the basic plugin which got User fields.
Then we build an application which include our basic plugin. The application got a special application person class called RUser which extend from User. RUser is set to SpringSecurityCore as person class.
Problem:
The application runs about 1 to 3 days without errors, but then ClassCastExceptions are thrown trying to set a RUser object on a User field of a plugin domain class.
User classes:
Plugin User class:
class User implements Serializable {
transient springSecurityService
String username
String password
...
}
Application User class:
class RUser extends User implements Serializable{
Cart cart
boolean businessUser = false
boolean taxIncluded = false
...
}
Application Config.groovy:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'RUser'
Participated classes of our basic plugin:
class UserRole implements Serializable {
User user
Role role
static UserRole create(User user, Role role, boolean flush = false) {
new UserRole(user: user, role: role).save(flush: flush, insert: true)
}
...
}
class UserHistory implements Serializable{
User user
List historyEntries
static hasMany = [historyEntries:HistoryEntry]
...
}
The errors occur in this example situations:
In a Filter:
54: UserHistory.withTransaction{
def currentUser =springSecurityService.currentUser
def history = UserHistory.findByUser(currentUser)
if(!history){
96: history = new UserHistory(user:user).save(flush:true)
}
}
2014-05-23 13:52:17,279 ERROR errors.GrailsExceptionResolver| IllegalArgumentException occurred when processing request: [GET] /index
java.lang.ClassCastException#7ff92284. Stacktrace follows:
java.lang.reflect.UndeclaredThrowableException
at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
at de.neomatt.history.HistoryFilters$_closure1_closure2_closure4.doCall(HistoryFilters.groovy:54)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
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:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.reflect.InvocationTargetException
at de.neomatt.history.HistoryFilters$_closure1_closure2_closure4_closure5.doCall(HistoryFilters.groovy:96)
... 10 more
Caused by: org.springframework.beans.MethodInvocationException: Property 'springSecurityService' threw exception; nested exception is java.lang.IllegalArgumentException: java.lang.ClassCastException#7ff92284
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
... 11 more
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException#7ff92284
... 13 more
2014-05-23 13:52:17,288 ERROR errors.GrailsExceptionResolver| IllegalArgumentException occurred when processing request: [GET] /reservation_demo/ToolsOne
Method name must not be null. Stacktrace follows:
java.lang.IllegalArgumentException: Method name must not be null
at grails.plugin.cache.web.ProxyAwareMixedGrailsControllerHelper.retrieveAction(ProxyAwareMixedGrailsControllerHelper.java:41)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
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:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
In a Controller:
RegistrationCode.withTransaction {
def user = lookupUserClass().findByUsername(registrationCode.username)
def role = Role.findByAuthority(roleName)
281: UserRole.create user, role
}
2014-05-26 13:02:24,780 ERROR errors.GrailsExceptionResolver| IllegalArgumentException occurred when processing request: [GET] /app/register/verifyRegistration
java.lang.ClassCastException#a7c83d. Stacktrace follows:
java.lang.IllegalArgumentException: java.lang.ClassCastException#a7c83d
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at de.neomatt.security.UserRole.create(UserRole.groovy:32)
at de.neomatt.security.RegisterController$_closure4_closure14.doCall(RegisterController.groovy:281)
at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
at de.neomatt.security.RegisterController$_closure4.doCall(RegisterController.groovy:271)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
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:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
The ClassCastExceptions occurs everywhere, where an object with type RUser is setted on a User field. The RUser object is retrieved from springSecurityService.currentUser or with the lookupUserClass().findBy(...) method.
protected Class<?> lookupUserClass() {
grailsApplication.getDomainClass(lookupUserClassName()).clazz
}
As mentioned before, the application runs without errors for a undefined period of time in a production environment (no reloading, no config changes). A new deployment of the same war solves the problem for the next few hours/days.
Any suggestions?
#neomatt
Related
I am trying to understand the steps to support LDAP with Spring security...replacing our current basic authentication. Recently I made the changes to support the deprecation of the WebSecurityConfigurerAdapter and all is working fine. So now I want to swap out the basic authentication AuthenticationManager or AuthenticationProvider with their LDAP equivalents. There are several websites with partial information and I cant quite put the pieces together.
So I am starting with the spring guide on authenticating ldap (https://github.com/spring-guides/gs-authenticating-ldap) I took the "complete" example, modified for our version of Spring Boot 2.7.5 and the app starts and validates fine. I tried updating the example according to several websites from :
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource()
.url("ldap://localhost:8389/dc=springframework,dc=org")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
To :
#Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
}
#Bean
public AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
contextSource, new BCryptPasswordEncoder());
factory.setUserDnPatterns("uid={0},ou=people");
factory.setPasswordAttribute("pwd");
return factory.createAuthenticationManager();
}
Thinking this closer to the recommendations and closer to what I would be using in our real project. Now when I try to build ... the test phase keeps failing with the following stack trace
ERROR[m] loginWithValidUserThenAuthenticated Time elapsed: 0 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'authenticationManager' defined in class path resource [com/example/authenticatingldap/WebSecurityConfig.class]: Unsatisfied dependency expressed through method 'authenticationManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextSourceFactoryBean': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Unable to load LDIF classpath*:*.ldif
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextSourceFactoryBean': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Unable to load LDIF classpath*:*.ldif
Caused by: java.lang.IllegalStateException: Unable to load LDIF classpath*:*.ldif
Caused by: com.unboundid.ldap.sdk.LDAPException: An entry with DN 'dc=springframework,dc=org' already exists in the server.
I am using the same ldif file that worked with the other configuration. The code follows the other examples and recommendation but the embedded LDAP server wont load the file. Has anyone seen and solved this problem? Once this is working, do we simply remove the Embedded LDAP bean and somehow point the configuration to the real LDAP server?
I'm creating a Grails (3.3.9) plugin to hold shared back-end code for some internal applications. For some reason, when I run the plugin to test it, my service is not being injected into my controller.
I've started with the default web-plugin profile, created a single domain class called Entry, and run generate-all to create a controller, service, and views. When I try to run my plugin as an application and view a single domain instance, I get the following error:
Cannot invoke method get() on null object. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Cannot invoke method get() on null object
at com.mycompany.internal.EntryController.show(EntryController.groovy:18)
... 14 common frames omitted
The stacktrace takes me to line 18 in my controller:
def show(Long id) {
respond entryService.get(id)
}
This suggests to me that entryService is null.
My domain class looks like this:
class Entry {
String entryCode
String description
}
The controller is as follows:
class EntryController {
EntryService entryService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond entryService.list(params), model:[entryCount: entryService.count()]
}
def show(Long id) {
respond entryService.get(id)
}
//snipped for brevity
And the service looks like this:
#Service(Entry)
interface EntryService {
Entry get(Serializable id)
//snipped for brevity
}
Based on the Grails plugin documentation, I would expect to be able to run the plugin standalone like any other application, and in normal applications, defining the service as an interface works fine. If I install this plugin to my local maven cache and use it in an application, it works exactly as I would expect; I am able to hit the controller's show endpoint and get back a result from my database.
At one point I tried implementing the service as a class rather than having it be an interface, but then I receive this error:
URI
/entry/index
Class
java.lang.IllegalStateException
Message
null
Caused by
Either class [com.mycompany.internal.Entry] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
What am I missing about how to set up and run a Grails plugin correctly?
Finally found an answer by digging into the GORM issue: class Authority is not a domain class or GORM has not been initialized correctly or has already been shutdown
Apparently the root of the problem was the need to add compile "org.grails.plugins:hibernate5" to my dependencies block in build.gradle. The weird thing is that the web-plugin profile provides the create-domain-class command, so I would think GORM and Hibernate support would be included by default, but I'm apparently misunderstanding some aspects of how plugins are supposed to work.
As per the grails 3.1.13 guide I am trying to add service dependency to my controller, but somehow it is not working for me. It is throwing NullPointerException for Cannot get property 'serviceMethod' on null object. Below I am mentioning the steps to reproduce.
Execute following commands
grails create-app DepInjectionTest
grails create-controller com.abc.project.KpiReport
grails create-service com.abc.project.KpiReport
Above creates below directory structure
KpiReportService
#Transactional
class KpiReportService {
def serviceMethod() {
return "Hello from KpiReportService"
}
}
KpiReportController
class KpiReportController {
def index() {
def kpiReportService
render kpiReportService.serviceMethod
//render "Hello from KpiReportController"
}
}
Exception
Grails application running at http://localhost:8080 in environment: development
ERROR org.grails.web.errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [POST] /KpiReport/index
Cannot get property 'serviceMethod' on null object. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
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)
Caused by: java.lang.NullPointerException: Cannot get property 'serviceMethod' on null object
at com.abc.project.KpiReportController.index(KpiReportController.groovy:7)
... 13 common frames omitted
Using postman for request
I am new to grails, please help me figure out what is going wrong, may be I am missing something.
The error message indicates you are referring to a property that does not exist. Instead of render kpiReportService.serviceMethod you want render kpiReportService.serviceMethod().
Services are injected as class variables
class KpiReportController {
def kpiReportService
def index() {
render kpiReportService.serviceMethod()
//render "Hello from KpiReportController"
}
}
I have a service that's responsible for creating the relevant account hierarchy when a registration page is successfully filled out :
def userRole = Role.findByAuthority("ROLE_USER")
final account = new Account(email: command.email, password: command.password)
account.save(flush: true)
final publisher = new Publisher(name: command.name) //, account: account)
publisher.save(flush: true)
final accountRole = AccountRole.create account, userRole
Regardless of what I do, the AccountRole.create account, userRole fails at this line:
static AccountRole create(Account account, Role role) {
def instance = new AccountRole(account: account, role: role)
instance.save() // throws NullPointerException
instance
}
I have tried new AccountRole(account: account, role: userRole), but this too fails when I manually call save. The Account and AccountRole are classes generated (and tweaked slightly) by the Grails 3 Spring Security plugin.
Here's the stacktrace for the AccountRole.create(...) call that fails:
java.lang.reflect.InvocationTargetException: null
at grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:64)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
at grails.plugin.springsecurity.web.filter.DebugFilter.invokeWithWrappedRequest(DebugFilter.groovy:102)
at grails.plugin.springsecurity.web.filter.DebugFilter.doFilter(DebugFilter.groovy:69)
at grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:64)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
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)
Caused by: java.lang.NullPointerException: null
at package.AccountRole.create(AccountRole.groovy:48)
at package.RegistrationService.$tt__handleNewRegistration(RegistrationService.groovy:25)
Version information:
| Grails Version: 3.1.5
| Groovy Version: 2.4.6
| JVM Version: 1.8.0_73
Please save me from my misery! I've spent hours on this now :(
There's not really enough info to be sure, but it's unlikely that instance is null since you just created it with a constructor call, but you should check that to be sure, e.g.
static AccountRole create(Account account, Role role) {
def instance = new AccountRole(account: account, role: role)
println "instance null? ${instance == null}"
instance.save() // throws NullPointerException
instance
}
It's more likely that a problem during validation is causing the exception, so my guess is that there's something wrong with either userRole or account. Check that userRole was correctly retrieved and that there aren't validation errors from the Account save() call:
def account = new Account(email: command.email, password: command.password)
account.save(flush: true)
if (account.hasErrors()) {
log.warn "Failed to save Account $account: $account.errors"
}
I've deployed my grails application on weblogic server. The front end is grails and backend is using spring and hibernate (not using gorm).
I am seeing the following error when I try to access a static dummy page:
<Dec 11, 2011 5:15:02 AM EST> <Error> <HTTP> <BEA-101362> <[ServletContext#450252357[app: spec-version:2.5]] could not deserialize the request scoped attribute with name: "userService"
java.io.NotSerializableException: org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at org.springframework.transaction.interceptor.TransactionInterceptor.writeObject(TransactionInterceptor.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Truncated. see log file for complete stacktrace
><[ServletContext#450252357[app: spec-version:2.5]] could not deserialize the request scoped attribute with name: "referenceDataService"
java.io.NotSerializableException: org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at org.springframework.transaction.interceptor.TransactionInterceptor.writeObject(TransactionInterceptor.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Truncated. see log file for complete stacktrace
>
Here are the action & controller classes:
class UserAdminController {
def messageSource
def userService
def referenceDataService
def manageUsers = {
render(view: "manageUsers")
}
def showCreateUserAdmin = {
//code goes here
}
}
The reason for writing a dummy action is that the user shouldn't call the gsp page using manageUsers.gsp.
How can I fix this issue?