There are some obvious benefits to writing custom code versus using a plugin. When using a plugin you get a lot of things off the shelf rather than writing it yourself. But there is always that risk of adding more bloat to your code base than is needed, debugging and finally bug fixes. Using something as mature as Spring Security has its unique advantages and in my experience a very extensible family of plugins that have got the most love from the Grails community.
Integration Steps :-
- Create New Grails Project
Let’s create the new application, go to project folder then create new Grails application.
Console: $ grails create-app <ProjectName> GGTS IDE: File->New->Grails Project
-
Add the following plugins to your conf/BuildConfig.groovy
Next, we have to add spring-security-core and mongodb plugins. Open file conf/BuildConfig.groovy Then, add this lines in plugins.Comment hibernate because we are using only mongodb.
plugins { compile ":mongodb:3.0.2" compile ":spring-security-core:2.0-RC4" //runtime ":hibernate4:4.3.5.5" //comment hibernate because we are using mongodb }
- Add the following dependencies to your conf/BuildConfig.groovy
Next, we have to add encache plugin. Open file conf/BuildConfig.groovy Then, add this lines in dependencies.
dependencies { compile "net.sf.ehcache:ehcache-core:2.4.8" }
- Automatically Install Plugin Refresh dependencies
Install the plugin in your project using this command.
Console: $ grails refresh-dependencies GGTS IDE: Right Click the Project->Grails Tools->Refresh Dependencies (Shortcut GGTS ALT+G R)
- Run s2-quickstart
Execute the s2-quickstart command to setup the Spring Security. Change the domain names for User,Role and Requestmap if you prefer.
Console: $ grails s2-quickstart auth User Role Requestmap
Note:
auth is Package name
User is User Model
Role is Group Model
Requestmap Model is Set permission of Role
*UserRole- Remove this Model . We embed Role into User - For Mongodb customize the folowing domain classes
The following domains needed some changes. Replace the following domains.
6.1 Role
package auth import org.bson.types.ObjectId class Role { ObjectId id String authority static constraints = { authority blank: false, unique: true } }
6.2 User
username String password String email boolean enabled = true booleanaccountExpired package auth import org.bson.types.ObjectId class User { transient springSecurityService ObjectId id String booleanaccountLocked booleanpasswordExpired Set<String> authorities static embedded = ['authorities'] static transients = ['springSecurityService'] static constraints = { username blank: false, unique: true, size: 2..32,matches: "[a-zA-Z0-9_]+" email blank: false, unique: true, email: true password blank: false, size: 6..64 } def beforeInsert() { encodePassword() } def beforeUpdate() { if (isDirty('password')) { encodePassword() } } protected void encodePassword() { password = springSecurityService.encodePassword(password) } }
- Replace the following Datasource to conf/Datasource.groovy
Next, Replace the entire contents of the DataSource.groovy file with the following. If you don’t specify the databaseName, the application name will be used as the databaseName.
// environment specific settings environments { development { grails { mongo { host = 'localhost' port = 27017 username = "Username" password = "Password" databaseName = "dev-dbName" } } } test { grails { mongo { host = 'localhost' port = 27017 username = "Username" password = "Password" databaseName = "test-dbName" } } } production { grails { mongo { host = 'localhost' port = 27017 username = "Username" password = "Password" databaseName = "prod-dbName" } } } }
- Create a customUserDetailsService and register it in resources.groovy
Now, we have to override the User Details Service. For this we created a new service called MongoUserDetailsService.Open file src/groovy Then, add this file into appropriate package.
Adding and registering the file in the appropriate package:
package <package-name> import grails.plugin.springsecurity.userdetails.GormUserDetailsService import grails.plugin.springsecurity.userdetails.GrailsUser import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService import grails.plugin.springsecurity.userdetails.NoStackUsernameNotFoundException import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.security.core.authority.SimpleGrantedAuthority import org.springframework.security.core.userdetails.UserDetails import auth.User class MongoUserDetailsService implements GrailsUserDetailsService { private Logger log = LoggerFactory.getLogger(getClass()) UserDetailsloadUserByUsername(String username, booleanloadRoles) { def user = User.findByUsername(username) if (!user) { log.warn "User not found: $username" throw new NoStackUsernameNotFoundException() } def roles if (loadRoles) { roles = user.authorities?.collect {new SimpleGrantedAuthority(it)} } new GrailsUser(user.username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, roles ?: [GormUserDetailsService.NO_ROLE], user.id) } UserDetailsloadUserByUsername(String username) { loadUserByUsername username, true } }
Next, register MongoUserDetailsService in resources.groovy
import <package-nam>.MongoUserDetailsService beans = { userDetailsService(MongoUserDetailsService) }
- Create a initial role,user in conf/BootStrap.groovy
Next, added a Default User and Role. Below is the code we have to added in the conf/BootStrap.groovy
import auth.Role import auth.User class BootStrap { def init = { servletContext -> for (String url in [ '/', '/index', '/index.gsp', '/**/favicon.ico','/assets/**','/**/assets/**', '/**/js/**', '/**/css/**', '/**/images/**', '/login', '/login.*', '/login/*', '/logout', '/logout.*', '/logout/*']) { Requestmap.findByUrl(url) ?: new Requestmap(url: url, configAttribute: 'permitAll').save() } Role role = Role.findByAuthority("ROLE_ADMIN") ?: new Role(authority: "ROLE_ADMIN").save(flush: true) User user = User.findByUsername("admin") ?: new User(username: "admin",password: "admin", authorities: [role.authority]).save(flush: true) } }
- Remove the following lines in conf/Config.groovy
grails.plugin.springsecurity.userLookup.userDomainClassName = 'auth.User' grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'auth.UserRole' grails.plugin.springsecurity.authority.className = 'auth.Role'
- Add following tag to index.gsp
Next, replace the following code in index.jsp
<sec:ifLoggedIn> Welcome Back! </sec:ifLoggedIn> <sec:ifNotLoggedIn> <g:link controller='login' action='auth'>Login</g:link> </sec:ifNotLoggedIn>
- Run the Application
Console: $ grails run-app GGTS IDE: Right Click the Project->Run As->Grails Run-App
- After run the application.open the following running application url.
http://localhost:8080/<project-name>
This is quiet an example wherein the details can be gathered on the webURL specified here.
More Information: – http://grails-plugins.github.io/grails-spring-security-core/