Grails - Spring Security save UserRole - grails

I am new in Grails and Spring Security. I try to make a simple register view. I created the User, Role and UserRole domain classes with the s2-quickstart script from spring-security.
My problem is that only the User will be saved in the database.
But I want to save the User and the UserRole.
Thats my controller:
#Secured('permitAll')
class RegisterController {
def index() {
}
def register() {
def user = new User(params)
user.save()
def role = Role.findByAuthority('ROLE_USER') // ROLE_USER will be created in the bootstrap class
UserRole.create(user, role)
redirect view: 'index'
}
}
If i put the same code in the bootstrap class the UserRole will be saved too.
Hope someone can help and explain, why this not work.

update your code:
def register() {
def user = new User(params)
user.save(flush: true, failOnError: true)
new UserRole(user: admin, role: Role.findByAuthority('ROLE_USER')).save(flush: true, failOnError: true)
redirect view: 'index'
}
If there will any issue in during save the UserRole then failOnError: true with throw error, then you can track the issue.

Related

Spring security core plugin for grails - Not able to access RequestMap parameters from the database

I have installed grails Spring security core plugin with RequestMap to retrieve URL from the database. I assume I have setup everything as its mentioned in the guide. When I start my application(http://localhost:8080/scadmin/index/) I get 'sorry, you are not authorized to view this page'. The admin user authenticated properly but RequestMap isnt allowing me to access the url. What's that I am doing wrong? please help.
config.groovy
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.tx.sc.auth.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.tx.sc.auth.UserRole'
grails.plugin.springsecurity.authority.className = 'com.tx.sc.auth.Role'
grails.plugin.springsecurity.requestMap.className = 'com.tx.sc.auth.Requestmap'
grails.plugin.springsecurity.securityConfigType = 'Requestmap'
My controller -
class AdminController {
def index() {
List<Portal> pList = portalService.listAllPortalInfo()
render(view: "admin", model:[portalList:pList])
}
}
Setting Role
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
Admin User
def adminUser = new User(username: 'admin', password: '12345',email: 'admin#abc.com',enabled: true, accountLocked: false, accountExpired: false, passwordExpired: false).save(flush: true)
Map user and role-
if (!adminUser.authorities.contains(adminRole)) {
UserRole.create(adminUser, adminRole, true)
}
RequestMap-
new Requestmap(url: '/scadmin/admin/index', configAttribute: 'ROLE_ADMIN').save(flush: true)
/scadmin/admin/index should be /admin/index - don't include the context.

Grails - controller access variables from gsp

I have the following grails controller
class UserController {
def userService
def roleService
def index() {
def roles = roleService.listRoles()
[roles: roles]
}
def userDetails() {
[user: userService.getUser(params.id), role:params.role]
}
def updateUser() {
def user = userService.getUser(params.id)
if (!(params.username)) {
flash.message = "You have to enter a username!"
redirect(action: "userDetails")
}
else {
user.username = params.username
user.person.title = params.title
user.person.given = params.given
user.person.middle = params.middle
user.person.family = params.family
userService.updateUser(user)
redirect(action: "index")
}
}
}
Starting with index() the user gets a list of all roles and users currently available. The user may then select one particular user being linked to the userDetails()-action. There I retrieve the information about the id of the user with params.id and the user's role name with params.role.
In userDetails.gsp the user is able to update some of the user's properties. However, if he doesn't enter a username, he should be redirected back to the userDetails.gsp. (I know that I could check this with the required-attribute within the gsp - it's just to understand the functionality)
And here is where I get stuck - when using the userDetails()-action, two parameters are passed to the gsp. But now when committing the redirect I don't know how to access this information. As a result, rendering the userDetails.gsp results in an error as the required information concerning the user and the role are not available.
Any help would be highly appreciated!
You should change the form (presumably) that submits to the updateUser action, so that it also sends in the role. Then if the data submitted is invalid, you simply include these parameters when redirecting back to the userDetails action.
def updateUser() {
def user = userService.getUser(params.id)
// I'm not sure if this the right way to get a Role from the role parameter
// but presumably you can figure that out yourself
def role = roleService.getRole(params.role)
if (!(params.username)) {
flash.message = "You have to enter a username!"
redirect action: "userDetails", params: [id: params.id, role: params.role]
}
}
As an aside, the way you're manually binding each parameter to the user object is unnecessarily verbose. Grails' databinding can do this automatically.

How to add a User in Grails Bootsrap with Audit Trails on?

Hi I'm having a hard time trying to add the first user in my grails bootstrap. I've tried many different ways but all have failed since the Audit Trail plugin wants a user to stamp the createdBy and EditedBy fields but the first one doesn't exit yet.
Here is my config for Audit Trails, essentially it's the same as default except I'm using User.username over the User.id:
grails {
plugin {
audittrail {
createdBy.field = "createdBy"
createdBy.type = "java.lang.String" //Long is the default
editedBy.field = "editedBy"
editedBy.type = "java.lang.String" //Long is the default
createdDate.field = "createdDate"
editedDate.field = "editedDate"
currentUserClosure = {ctx->
def authPrincipal = ctx.springSecurityService.principal
if(authPrincipal && authPrincipal != "anonymousUser"){
return authPrincipal.username
} else {
return null //fall back
}
}
}
}
}
Here is what my User class looks like, ie. I just add the annotation for the plugin to work:
#gorm.AuditStamp
class User {
//... basic Spring Security Generated User File with minor changes
}
Here is the contents of my bootstrap file:
def adminUser = new User(
username: 'admin',
enabled: true,
password: 'password',
firstName: 'ADMIN',
lastName: 'ADMIN'
).save(flush: true)
// The below will work if I take off the annotation on User class.
SpringSecurityUtils.doWithAuth('admin') {
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
UserRole.create adminUser, adminRole, true
}
So now how can I add that first user? I've tried:
- Using annonymousUser
- Failed, plugin prevents it
- Hardcoding the createdBy and editedby to "admin"
- Failed get's overridden
- Use executeUpdate to insert the user directly in the DB
- Failed: in bootstrap
- Delay the save of the first user until the doWithAuth
- Failed: couldn't find the user
Any help would be great! Thanks!
I had the same problem and was searching for a solution. I managed to get it working by doing the below:
grails {
plugin {
audittrail {
createdBy.field = "createdBy"
createdBy.type = "java.lang.String" //Long is the default
editedBy.field = "modifiedBy"
editedBy.type = "java.lang.String" //Long is the default
createdDate.field = "createdDate"
editedDate.field = "modifiedDate"
//custom closure to return the current user who is logged in
currentUserClosure = {ctx->
//ctx is the applicationContext
def userName = ctx.springSecurityService.principal?.username
return userName != null ? userName : "System"
}
}
}
}
In the Bootstrap.groovy file, just do a save like:
def adminUser = new User(username: 'admin', enabled: true, password: 'password',
firstName: 'ADMIN', lastName: 'ADMIN').save(flush: true)
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
UserRole.create adminUser, adminRole, true
The newly created first user will be stamped with user "System" (createdBy and modifiedBy columns).

Multiple Roles for a single User

The Following Code Adds Multiple Roles to a Single user, it also should be noted that this will only work for a single session as we're trying to define the roles and users every time we start the app, to prevent any crashes due to that add a check for the database and create the roles and user IF they don't exist.
import trippinspring.*
class BootStrap {
def init = { servletContext ->
def adminRole = new SpringRole(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new SpringRole(authority: 'ROLE_USER').save(flush: true)
def testUser = new SpringUser(username: 'me', enabled: true, password: 'password')
testUser.save(flush: true)
if (!testUser.authorities.contains(adminRole)) {
new SpringUserSpringRole(springUser: testUser, springRole: adminRole).save(flush: true,failOnError: true)
}
if (!testUser.authorities.contains(userRole)) {
new SpringUserSpringRole(springUser: testUser, springRole: userRole).save(flush: true,failOnError: true)
}
}
}
Most of the code is a direct reference to Aram Arabyan's answer, and Ian Roberts comments with some fixes to work with my code.
if (!testUser.authorities.contains(adminRole)) {
new SpringUserSpringRole(user: testUser, role: adminRole).save(flush: true,failOnError: true)
}
if (!testUser.authorities.contains(userRole)) {
new SpringUserSpringRole(user: testUser, role: userRole).save(flush: true,failOnError: true)
}
Just a suggestion, maybe you should try creating a hierarchy for your roles instead of adding two roles for a single user:
see doc.

Grails Spring-Security-Core plugin - Cannot authenticate user

So I am banging my head against the wall trying to get spring-security-core-1.2.7.1 to work with Grails 2.0...
I have looked at the tutorial and run s2. Read that the new plugin encrypts passwords for you, so my bootstrap looks like:
def userRole = Role.findByAuthority('ROLE_USER') ?: new Role(authority: 'ROLE_USER').save(failOnError: true)
def adminRole = Role.findByAuthority('ROLE_ADMIN') ?: new Role(authority: 'ROLE_ADMIN').save(failOnError: true)
def adminUser = User.findByUsername('admin') ?: new User(
username: 'admin',
password: "admin",
enabled: true).save(failOnError: true)
def testUser = User.findByUsername('test') ?: new User(
username: 'test',
password: "test",
enabled: true).save(failOnError: true)
if (!adminUser.authorities.contains(adminRole)) {
UserRole.create adminUser, adminRole
}
if (!testUser.authorities.contains(userRole)) {
UserRole.create testUser, userRole
}
I can look at the H2 database and I see the users, their encoded passwords, see that the roles are created and can see the user role mappings are properly created as well.
However, I still get "Sorry, we were not able to find a user with that username and password." at the login prompt for both users.
I have turned on log4j debug 'org.springframework.security' but all I really get out of the logs is:
2012-01-23 23:08:44,875 ["http-bio-8080"-exec-5] DEBUG dao.DaoAuthenticationProvider - Authentication failed: password does not match stored value
I can't see anything obviously wrong with your code. I'm using the same version of Grails and the spring security plugin, and the following code in Bootstrap.groovy works for me:
def init = { servletContext ->
// create some roles
def userRole = createRole('ROLE_USER')
def adminRole = createRole('ROLE_ADMIN')
// create some users
User admin = createUser('Admin', 'admin#mailinator.com', adminRole)
User user = createUser('User', 'user#yahoo.co.uk', userRole)
}
private User createUser(name, username, role) {
def defaultPassword = 'password'
User user = User.findByUsername(username) ?: new User(
name: name,
username: username,
password: defaultPassword,
passwordConfirm: defaultPassword,
enabled: true).save()
if (!user.authorities.contains(role)) {
UserRole.create user, role
}
user
}
private createRole(String roleName) {
Role.findByAuthority(roleName) ?: new Role(authority: roleName).save()
}
I did have similar issue. Was because I've forgotten to add
grails.plugin.springsecurity.userLookup.userDomainClassName ='yourpackage.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName =yourpackage.UserRole'
grails.plugin.springsecurity.authority.className ='yourpackage.Role'
After that authentication was working.
You can fix the multiple datasources issue by updating the User class.
See https://stackoverflow.com/q/13296594
In the OP's original code, why is the username in single quotes and the password in double quotes. That might be the problem.

Resources