How I get the service springSecurityService bean in a own plugin?
I tried this, but i don't now if this is the correct strategy.
def doWithSpring = {
springSecurityService(application.mainContext.getBean('springSecurityService'))
}
If attempting to use it from a service or controller in the plugin, you can simply use
def springSecurityService
as a member variable in the groovy class. Since this is purely a runtime dependency, your plugin does not have to depend directly on the Spring Security Plugin. However, if your plugin is ever used in an application that does not make the Spring Security Plugin available at runtime, this will fail for obvious reasons.
Also important to note: this is true for any Grails service, not just the Spring Security Service.
Related
I want to migrate an application from grails 2.4.4 to grails 3.3.9.
As the structure of the conf directory in grails 2.x is completely different from 3.x, there is no config.groovy in 3.x anymore. In config.groovy of 2.x I used to define lists of constants for my select boxes like:
metals=['au','ag','pl']
and I accessed them via
static List getMetals() {
grails.util.Holders.config.metals
}
in my groovy code.
What is the corresponding way in 3.x?
I would start by checking out the upgrade guides:
http://docs.grails.org/latest/guide/upgrading.html
http://docs.grails.org/3.2.0/guide/upgrading.html#upgrading2x
config.groovy, by default becomes application.yml, but you can convert that to application.groovy, and there is a script in the external config plugin that will help with that:
http://plugins.grails.org/plugin/grails/external-config
In general it is conserdered back practice to use the holders, it would be better to use either an injected bean/service
GrailsApplication grailsApplication
grailsApplication.config.etc
Or wire in a bean using resources. The only reason to use holders is in another object that is outside of grails, that for some reason, you can't wire up as a bean. In that cases there is now a Holders class, that you can get the config from. Here's some other ways to get at the config from an OCI blog:
http://grailsblog.objectcomputing.com/posts/2016/08/31/retrieving-config-values.html
I currently have a spring mvc application which I'm trying to add spring security to. However, I can't use the #PreAuthorize annotation without getting the following error:
Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/cglib/transform/impl/MemorySafeUndeclaredThrowableStrategy
I'm currently using Spring Version 4.1.0 and Spring Security 3.2.5, which according to spring's documentation and other posts on here should work fine.
There's also a sample on their github which appears to be using the same versions without issue.
Any ideas?
The PreAuthorize tag has been added to a Controller, cglib is in the classpath, yet still the same error message. Any ideas?
Turns out it was version issues. Spring Security is currently at 3.2.5.Release, which I was using, but Spring was at 4.1.0.
As of 4.0.2, some of the cglib classes have been removed. The solution was to go down to 4.0.1 in Spring, or use the 4.0.0.M2 milestone release for spring security.
#PreAuthorize is implemented via AOP. If the method on which you put the annotation are not declared in an interface implemented by the class, Spring cannot use the default of JDK proxy, but uses CGLIB to proxy classes.
The error suggests you use class proxying, but do not have CGLIB in classpath.
Two ways to fix it :
add CGLIB to classpath
make your class implements an interface
BTW, you say you added #PreAuthorize to a RestController. #PreAuthorize annotation is more frequent in service layer. Normally, you use URL based authorization for what could exists in controller. The best way to fix the problem could be to move the #PreAuthorize annotation to the service class that should already be wired as an interface.
Similar to this question: Share config between two grails apps that share a common plugin
But regarding resources.groovy instead of Config.groovy.
Is there some way to have a resources.groovy in a plugin that is then depended on from multiple apps so they have those resources available and autowired?
I'm not sure of a convenient way to do this, but since the purpose of resources.groovy is to configure Spring beans you could create a plugin and configure the beans from the plugin's doWithSpring closure in its plugin descriptor. This would additionally benefit from versioning, dependency management, etc.
I cite from mybatis plugin documentation:
"When working with MyBatis plugin your "Domain" classes should be
located in src/groovy and not in grails-app/domain. This is necessary
to avoid conflict with GROM since MyBatis plugin can coexist with
existing GORM Domain classes."
So where should the validation and constraints be located, when I want to use grails with MyBatis plugin ?
You can add a #Validateable annotation to any Groovy class in Grails, and you will be able to validate it... The Plugin currently doesn't check for any validation errors so you will have to implement that code yourself.
From official Grails documentation:
Classes which define the static constraints property and are annotated
with #Validateable can be made validateable by the framework
http://grails.org/doc/2.1.0/guide/validation.html#validationNonDomainAndCommandObjectClasses
You could even write a custom MyBatis Interceptor (see https://github.com/fzilic/Grails-MyBatis/blob/master/src/groovy/org/grails/plugins/mybatis/locking/OptimisticLockingInterceptor.groovy) and register it after the SqlSession is created...
Currently the MyBatis plugin doesn't support registering custom Interceptors in it's configuration, but they could be added to the interceptor chain
def factory = GrailsApplication.mainContext.getBean("sqlSessionFactoryBean_dataSource")
factory.configuration.interceptorChain.addInterceptor(Interceptor)
Support for this might be added in future versions.
How do I get the services in the grails console? My business rules are implemented in services but I don't have access to them in the grails console. Does anyone know how to help me?
The Spring ApplicationContext is available as the ctx variable in the console, and you can use this to access Spring beans such as services. Typically that would be def myService = ctx.getBean('myService') but Grails adds a metaclass helper so you can just do def myService = ctx.myService