The great Spring Security Plugin is now available for Grails 3!
I will leave these blog posts up as a reference, but I would strongly suggest (as if you needed the suggestion) to use the Spring-Security plugin for Grails 3
Since Spring Security Core PluginUses:
- Grails Version: 3.0.0.M2
- Groovy Version: 2.4.1
- JVM Version: 1.7.0_51
Setting up Security:
Simply add the following to build.gradle in the dependencies:compile "org.springframework.boot:spring-boot-starter-security"This will cause ALL HTTP endpoints to require authorization and a random password to be generated each time you start up your app. Also, because Spring-Boot-Security-Starter logs the randomly generated password at level INFO, you need to add the following to your logback.groovy file.
//see http://logback.qos.ch/manual/groovy.html for more info logger('org.springframework.boot.autoconfigure.security', INFO)This is not sufficient for anything but a demo, so let's customize it a bit. Let's start with the easiest part, creating a fixed password. There are a few methods of setting a static password, but we'll concentrate on two 1) in the application.yml or 2) in a WebSecurityConfigurerAdapter Class.
In the Application.yml file
security: user: password: password
In a WebSecurityConfigurerAdapter Class
Using a WebSecurityConfigurerAdapter class, we can override the default implementation(s) used in spring-boot-starter-security.grails-app/init/simpleappwithsecurity/SecurityConfiguration.groovy
package simpleappwithsecurity import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("pwd").roles("USER"); } }One important note, Grails does NOT know anything about the SecurityConfiguration class unless you do something to tell your Grails' app about the new class. The two easiest methods are to specify a bean in resources.groovy
grails-app/conf/spring/resources.groovy
import simpleappwithsecurity.SecurityConfiguration beans = { webSecurityConfiguration(SecurityConfiguration) }If you use this, you do not need the class annotations @Configuration and @EnableWebSecurity on the SecurityConfiguration class. Another method is to enable Spring's Component Scan on the Grails application in the Application.groovy file by adding @ComponentScan to the Application class, such as
grails-app/init/Application.groovy
... import org.springframework.context.annotation.ComponentScan; @ComponentScan class Application extends GrailsAutoConfiguration { ...I think this depends on how you view your application. If it is a Grails Application, using primarily Grails Plugins with Spring sprinkled in, then use the first method. If it is a Spring Boot application with Grails sprinkled in, use the latter method. For now, our app is a Grails app, so we'll use the bean definition in resources.groovy.
Securing specific URIs (or request maps)
Let's extend our example by adding pattern matches to our SecurityConfiguration class.grails-app/init/simpleappwithsecurity/SecurityConfiguration.groovy
... @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers('/admin/**').hasAnyRole('ADMIN') .antMatchers('/home/**').hasAnyRole('USER', 'ADMIN') .antMatchers('/').permitAll() .and() .formLogin().permitAll() .and() .logout().permitAll() } //<-- --="" .inmemoryauthentication="" .withuser="" auth="" code="" configureglobal="" end="" exception="" in="" of="" password="" previous="" public="" roles="" snippet="" throws="" user="" uthenticationmanagerbuilder="" utowired="" void=""> .and() .withUser('admin').password('admin').roles('ADMIN'); } ...-->Restarting the application now will allow you to see the index page, but require authentication when attempting to access /home or /admin controllers.
Thanks. Clean an simple. Just what i was looking for. Next step is security with OAuth2 ;)
ReplyDeleteI'll see what I can do ;), but Spring has a blog post https://spring.io/blog/2015/02/03/sso-with-oauth2-angular-js-and-spring-security-part-v
DeleteThanks for the article. Could you please hint how to display username in the gsp after successful login? Which tag should I use?
ReplyDeleteUnfortunately, I have been working in Angular on the front end so I am not sure what tag library to use, however, I am guessing that the traditional Spring Security JSP tag libs would still work. I would have a look at http://docs.spring.io/spring-security/site/docs/4.0.1.RELEASE/reference/htmlsingle/#the-authentication-tag.
DeleteHi David
ReplyDeleteWe will be waiting for second part of the post! Hope you will be covering JDBC configuration with it.
A taglib can do that... in the GSP, put:
ReplyDelete<g:username />
Then create a file in the taglib folder such as:
UserTagLib.groovy
class CommonTagLib {
def username = {
def user = session.SPRING_SECURITY_CONTEXT?.getAuthentication()?.getPrincipal()
out << user?.getUsername()
}
}
Oops, this was meant to be posted as a reply to the April 21 question above. Anyway, a better formatted version of the code at is at: stackoverflow.com/a/30448442
DeleteHi! Great post. Do you know if it's possible to change the default login form, and how to do it ?
ReplyDeleteGood stuff, but way too much work :) The spring-security-core plugin has been updated to work with Grails 3 - see the docs at https://grails-plugins.github.io/grails-spring-security-core/
ReplyDeleteHow could i change the spring login view??
ReplyDelete