Grails with Spring Security Plugin and Salted Passwords - grails

I am trying to do salted password hashing in my Grails + Spring Security application. I have used the tutorials on the Grails site, and also ones I found randomly on the Internet.
At the moment, I have everything set up according to this tutorial. However I run into a problem when deploying the application with the following bean declaration in resources.groovy:
saltSource(cq.MySaltSource) {
userPropertyToUse = CH.config.grails.plugins.springsecurity.dao.reflectionSaltSourceProperty
}
It complains that it cannot find CH.
After digging around, I found a post on nabble stating the following:
Also - don't use ConfigurationHolder (CH) since it's deprecated in 2.0. You can pass in a reference to the grailsApplication bean and get the config from there:
saltSource(MySaltSource) {
grailsApplication = ref('grailsApplication')
}
and then in your class add
def grailsApplication
and get the property via
String userPropertyToUse grailsApplication.config.grails.plugins.springsecurity.dao.reflectionSaltSourceProperty
The part that I do not follow is the last statement about "...and get the property via...". The line of code he gives there seems malformed to me.
If anyone can shed some light here, or provide a different approach to using salted passwords with Grails and Spring Security, I would appreciate it. Note that it needs to be unique salts per user, not system-wide or a single salt, or a salt derived from username.
Thanks
UPDATE
So I got it working with the first tutorial (forgot the import statement at the top of resources.groovy. But I would still like to use the second way (to stay compatible with the future version).
UPDATE 2
I have written a complete tutorial on this if anyone browsing here is interested:
Setting up a Grails web application using Spring Security and salted passwords.

In resources.groovy where you're defining the saltSource bean the GrailsApplication is available as the application variable, so you can change the bean declaration to
saltSource(cq.MySaltSource) {
userPropertyToUse = application.config.grails.plugins.springsecurity.dao.reflectionSaltSourceProperty
}

Related

Dynamic Controller Plugin for grails

I'am new to grails, I wanted to make use of Dynamic Controller Plugin (http://grails.org/plugin/dynamic-controller) in my project.
I am using grails version 3.2.11
I've added the dependency as directed on the page. It downloads the dependency in the form of zip, I can see it in External libraries. But when I am trying to import two classes (as directed on http://burtbeckwith.com/blog/?p=1041 Linking to existing Controller Actions
approach)
import com.burtbeckwith.grails.plugins.dynamiccontroller.ControllerClosureSource
import com.burtbeckwith.grails.plugins.dynamiccontroller.DynamicControllerManager
it gives " unable to resolve class" error. Please suggest what am I doing wrong here. Thanks!
You're trying to install a Grails 2 plugin in a Grails 3+ app, but that's not possible since they're not compatible. Grails 2 plugins must be upgraded and reworked to be used in Grails 3, and there's no plan to do so for this plugin.
I would say take a look at the URL Mappings & Embedded variables in the grails documentation.
https://docs.grails.org/3.2.11/guide/single.html#embeddedVariables
For example:
static mappings = {
"/blog/$topic"(controller: "blog")
}
which gives you a feeling like you are dynamically declaring actions.
And the topic variable is accessible through GrailsParameterMap params object # controller.
With this you can construct url like:
www.mysite.com/blog/football
www.mysite.com/blog/tvshow
www.mysite.com/blog/etc
Edit: you can also take a look at Dynamic Controller and Action Names [https://docs.grails.org/3.2.11/guide/single.html#_dynamic_controller_and_action_names]

Grails 3.2.4 Application Won't Load After Adding Spring Security Plugin 3.1.1

I generated a new Grails 3.2.4 application. I generated some domain objects, controllers, and services, then got the app to compile and run. I then added the following line to my build.gradle.
dependencies {
...
compile "org.grails.plugins:spring-security-core:3.1.1"
...
}
I then ran the following command, as specified in the plugin docs.
grails s2-quickstart --uiOnly
I already had User, Role, and UserRole classes defined, which I pointed to in the application.groovy that this command generated, as well as defining:
grails.plugin.springsecurity.active = true
I also added some usages of the <sec:ifNotGranted> tag to some of my views.
As far as I can tell from the docs, I shouldn't have to do anything else. The Spring Security properties should have default values defined in the DefaultSecurityConfig.groovy file provided by the plugin, according to the docs linked above. However, the application will not even run now. The first error I got was:
groovy.lang.MissingMethodException: No signature of method: static grails.plugin.springsecurity.SpringSecurityUtils.findFilterChainNames() is applicable for argument types: (org.grails.config.NavigableMap$NullSafeNavigator, java.lang.Boolean, java.lang.Boolean, java.lang.Boolean, java.lang.Boolean, java.lang.Boolean, groovy.util.ConfigObject) values: [[:], false, false, false, false, false, [:]]
Possible solutions: findFilterChainNames(java.lang.Object, boolean, boolean, boolean, boolean, boolean, boolean)
at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1503)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1489)
at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at grails.plugin.springsecurity.ReflectionUtils.findFilterChainNames(ReflectionUtils.groovy:214)
I looked in the code where findFilterChainNames is called, and the issue is that there are some properties that should have default boolean values of either true or false (according to the docs above), but instead they aren't defined at all, causing the error shown here. I confirmed that if I define those properties myself in application.groovy, this error goes way. However, it is replaced by another error for the next undefined property the Spring Security code runs into, and so on, for each property I attempt to define myself, even though I shouldn't have to, according to the docs.
I stepped through the code where the default values from DefaultSecurityConfig.groovy should be merged into the values defined in the application.groovy. However, when DefaultSecurityConfig is loaded from the classpath and parsed in, the properties I see in the file do not end up in the returned configuration map.
I cannot figure out what I'm doing wrong, as I followed the instructions in the documentation. I tried searching for similar issues online, but couldn't find anything. Does anyone have any ideas or has anyone else run into this?
Whelp, I figured it out. I was stepping further into the code that should be merging the properties from the provided DefaultSecurityConfig and I noticed that a) as it was stepping through the DefaultSecurityConfig file, the breakpoints weren't lining up with the code and b) some of the returned properties had the old grails.plugins prefix instead of the new grails.plugin prefix. This got me suspicious that somehow an old version of DefaultSecurityConfig (and possibly other groovy classes) were being pulled in instead of the proper versions. I thus emptied out my ~/.grails, ~/.gradle, and ~/.m2 directories of all cached jars and classes. After that, my application seems to properly initialize Spring Security (it then fails due to being unable to find a bean that I have configured Spring Security to use as a logout handler, and I'm not sure why, but that seems to be unrelated to this issue).
I am using grails 3.2.8 and after configuring Spring security ldap, form based Authentication worked fine.
However, when I switched to Basic Authentication, I had same error. I was using application.properties file for configuration props for ldap and setting Basic Authentication to true.
grails.plugin.springsecurity.useBasicAuth = true
Added to application.yml and everything worked file.

Grails 3 (GORM) datasource properties not loading from Spring Cloud Config Server

I am trying to use Spring Cloud Config Server to externalize my Grails 3 (personnel) application configuration, but I cannot seem to set the dataSource properties.
Currently, I can load other properties (sample.message) into my Grails 3 (personnel) application and retrieve them using grailsApplication.config.sample.message without an issue. And hitting the REST endpoint on the Config Server (localhost:8888/personnel/master) is showing the configuration information I want, so I'm a bit confused.
I have tried each of the following in my personnel.properties file in my Git repo:
datasource.user=example
datasource.password=example
grails.datasource.user=example
grails.datasource.password=example
spring.datasource.user=example
spring.datasource.password=example
But none of them work. I continue to see error messages saying sa#localhost (using password: no) suggesting that the datasource properties, in particular, are not working.
I know it is possible with spring-boot-starter-data-jpa, so I'm wondering:
Is it possible with GORM?
If so, do I need to manually create the datasource bean?
What property names do I use datasource.user, grails.datasource.user, spring.datasource.user, etc?
After Shashank's edit, I realized that it was an issue with my property settings. datasource should have been dataSource and user should be username. Once those corrections were made, the application (personnel) worked perfectly. So,
Yes it is possible.
No, you don't need to create the bean manually
Property names are:
personnel.properties
dataSource.username=example
dataSource.password=example
dataSource.url=jdbc:mysql://localhost:3306/personnel

How can use Flyway with grails

I know there is a Flyway2 plugin. However im not satisfied since it seems fitted for working by console commands. What i want is to integrate Flyway in a programatic way so:
1st Integration tests use flyway to handle db schema with H2 database
2nd Flyway get's triggered on tomcat deployment and handles also the environment database (maybe through running it from bootstrap?)
Does anyone has experienced with this?
EDIT after some discussion:
In order to use the plugin i would need to get a fully configured instance of GFlyway from spring context. This becomes difficult since the bean only property is def config from where it will read all the required properties. The question is how to replicate this behavior within the resources.groovy ... how to provide the application config as a parameter to the bean.
As we have been discussing in the comments, the correct way to configure this as a bean would be:
// Resources.groovy
beans {
grailsApplication = ref('grailsApplication')
gFlyaway(gflyway2.GFlyway) {
config = grailsApplication.config
}
}
Configure the settings as usual within your Config.groovy per the documentation of the plugin.
That should get you closer, if not all the way there.

Applying Spring Security to a plugin

I'm developing a plugin to provide some specific functionality. The plugin "has it all": the complete vertical slice (services, controllers, domain-classes, GSPs). On the plugin level no security is used.
Now I want to integrate the plugin into the main app, and apply some security rules like #Secured(['ROLE_SUPER']).
The way I'm doing it now is not too elegant:
#Secured(['ROLE_SUPER'])
class SomeController extends SomePluginController {}
This mass of such zero-value code grows along with the number of controllers.
What can be improved here?
TIA
UPDATE:
the grails.plugin.springsecurity.controllerAnnotations.staticRules map doesn't work.
I have a plugin AggregationPlugin with TaskController and index-action inside.
I tried to put it so:
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/task/**': ['ROLE_SUPER'],
'/aggregation/**': ['ROLE_SUPER'],
'/plugins/aggregation-0.1/**': ['ROLE_SUPER'],
]
but I still can access the page anonymously.
I'm using Grails 1.3.7 and spring-security-core 1.2.7.2
UPDATE #2:
So, after some attempts I found the most elegant solution. Instead of staticRules which doesn't work for some reason in my setup and which can become really big, if you have many plugins to apply security to, I added a dependency to the plugin:
compile( 'org.springframework.security:spring-security-core:3.0.7.RELEASE' )
so that I can use the #Secured in my controllers now without the whole security plugin. Upon installation into the main app they will be picked automatically by the security plugin.
You can put the configuration for the plugin controllers in Config.groovy:
grails.plugins.springsecurity.controllerAnnotations.staticRules = [
'/somePlugin/': ['ROLE_SUPER']
]
Check out the official docs, scroll down to section controllerAnnotations.staticRules.

Resources