java.lang.String cannot be cast to java.lang.Long in Spring Security ACL

眉间皱痕 提交于 2019-12-08 14:24:05

问题


I use Spring Security ACL plugin and have no ACLs set before. I want to access the following service method:

@PostFilter("hasPermission(filterObject, read) or hasPermission(filterObject, admin)")
List<Company> list(Map params = [:]) {
   return Company.list(params)
}

I gave permission to the admin user for a company. When I access the above method everything works fine. The problem occurs when I stopped the server and do grails clean. When I restart and access the above method I get the following error. It is very strange because it worked the first time before the grails clean without errors.

2015-08-08 14:57:02,509 [http-nio-8080-exec-5] ERROR errors.GrailsExceptionResolver  - ClassCastException occurred when processing request: [GET] /test2/home/list
java.lang.String cannot be cast to java.lang.Long. Stacktrace follows:
Message: java.lang.String cannot be cast to java.lang.Long
    Line | Method
->>  305 | doCall                 in org.grails.datastore.gorm.GormStaticApi$_withCriteria_closure11
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    302 | execute                in org.grails.datastore.mapping.core.DatastoreUtils
|     37 | execute . . . . . . .  in org.grails.datastore.gorm.AbstractDatastoreApi
|    304 | withCriteria           in org.grails.datastore.gorm.GormStaticApi
|    128 | lookupObjectIdentities in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy
|    106 | doCall                 in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy$_readAclsById_closure1
|     78 | readAclsById . . . . . in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy
|    288 | readAclsById           in grails.plugin.springsecurity.acl.AclService
|    127 | list . . . . . . . . . in test2.HomeController
|    198 | doFilter               in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter . . . . . . . in grails.plugin.cache.web.filter.AbstractFilter
|     53 | doFilter               in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
|     62 | doFilter . . . . . . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|   1142 | runWorker              in java.util.concurrent.ThreadPoolExecutor
|    617 | run . . . . . . . . .  in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run                    in java.lang.Thread
Error |
2015-08-08 14:57:03,030 [http-nio-8080-exec-6] ERROR errors.GrailsExceptionResolver  - ClassCastException occurred when processing request: [GET] /test2/home/list
java.lang.String cannot be cast to java.lang.Long. Stacktrace follows:
Message: java.lang.String cannot be cast to java.lang.Long
    Line | Method
->>  305 | doCall                 in org.grails.datastore.gorm.GormStaticApi$_withCriteria_closure11
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    302 | execute                in org.grails.datastore.mapping.core.DatastoreUtils
|     37 | execute . . . . . . .  in org.grails.datastore.gorm.AbstractDatastoreApi
|    304 | withCriteria           in org.grails.datastore.gorm.GormStaticApi
|    128 | lookupObjectIdentities in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy
|    106 | doCall                 in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy$_readAclsById_closure1
|     78 | readAclsById . . . . . in grails.plugin.springsecurity.acl.jdbc.GormAclLookupStrategy
|    288 | readAclsById           in grails.plugin.springsecurity.acl.AclService
|    127 | list . . . . . . . . . in test2.HomeController
|    198 | doFilter               in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter . . . . . . . in grails.plugin.cache.web.filter.AbstractFilter
|     53 | doFilter               in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
|     62 | doFilter . . . . . . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|   1142 | runWorker              in java.util.concurrent.ThreadPoolExecutor
|    617 | run . . . . . . . . .  in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run                    in java.lang.Thread

I created a demo project here: https://github.com/confile/Spring-Security-ACL-Bug

Reproduce it:

  • create a mysql database name: test
  • grails dbm-update
  • grails run-app
  • http://localhost:8080/test2/home/list
  • login with user: admin pw: admin
  • http://localhost:8080/test2/home/createCompany1
  • http://localhost:8080/test2/home/addPerm
  • http://localhost:8080/test2/home/createCompany2
  • http://localhost:8080/test2/home/list
  • stop server
  • grails clean
  • grails run-app
  • http://localhost:8080/test2/home/list

Edit: I found that when I shut down my mysql server and restart it then the error is gone. It might belong to some caching issues here.

Is there a way to catch this error, e.g., in case where no ACLs have been set before?

Note: This question is still unanswered.


回答1:


The issue seems actually related to the way AclSid overrides the one in the plugin.

You will see the java.lang.String cannot be cast to java.lang.Long issue when the plugins class won somehow.

There is an easy fix in general you always should be running grails package after you do a grails clean also you need to make sure on your ci server you run the package step before you build your war.

I have seen this same issue since we use UUIDs and had to make the AclSid class has a string for the sid as well. I've had no issues in production or locally once we started to correctly run the package step.



来源:https://stackoverflow.com/questions/31597897/java-lang-string-cannot-be-cast-to-java-lang-long-in-spring-security-acl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!