Adding RequestMap - grails

how can I upgrade an existing grails application with a request map?
I didn't use
grails s2-quickstart package user role requestmap
but only
grails s2-quickstart package user role
AFAIK I have to 1) set a line in Config.groovy:
grails.plugins.springsecurity.securityConfigType = "Requestmap"
and then 2) set all the entries via BootStrap.groovy (according to spring's docs ), I get that, but how does the RequestMap Domain Class have to look like? Anything else to do?
Thanks

It's a simple class; this is what would be generated if you specify package your.package.name and class name Requestmap:
package your.package.name
class Requestmap {
String url
String configAttribute
static mapping = {
cache true
}
static constraints = {
url blank: false, unique: true
configAttribute blank: false
}
}
Once you create this, add this line in Config.groovy:
grails.plugin.springsecurity.requestMap.className = 'your.package.name.Requestmap'

Related

Grails 4 Audit Logging w/ Spring Security does not record "Actor"

I'm using Spring Security Rest and the Grails Audit Logging plugin. Audit log records are being created with all the correct information except the actor property is always saved with the defaultActor value.
Below is my configuration. Does anyone have any ideas? What should I be looking for? Thanks in advance for your time.
build.gradle
ext.springSecurityRestVersion = '3.0.0.RC1'
dependencies {
...
compile "org.grails.plugins:spring-security-rest:${springSecurityRestVersion}"
compile "org.grails.plugins:spring-security-rest-gorm:${springSecurityRestVersion}"
compile 'org.grails.plugins:audit-logging:4.0.3'
...
}
application.yml
grails.plugin.auditLog:
auditDomainClassName: "us.mycompany.api.AuditLogEvent"
logFullClassName: false
defaultActor: "mycompany"
grails.plugin.springsecurity:
userLookup.userDomainClassName: 'us.mycompany.api.Person'
userLookup.authorityJoinClassName: 'us.mycompany.api.PersonRole'
authority.className: 'us.mycompany.api.Role'
filterChain.chainMap:
#Stateless chain
- { pattern: '/**', filters: 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter' }
rest.token:
storage.gorm.tokenDomainClassName: 'us.mycompany.api.AuthenticationToken'
validation:
useBearerToken: false
enableAnonymousAccess: true
As I debugged this, it seems like the springSecurityService dependency in SpringSecurityRequestResolver was null, so I had to explicitly wire SpringSecurityRequestResolver in resources.groovy.
I know that I shouldn't have to do that, but it did fix my problem, so this is at least a workaround.
resources.groovy
import grails.plugins.orm.auditable.resolvers.SpringSecurityRequestResolver
beans = {
auditRequestResolver(SpringSecurityRequestResolver) {
springSecurityService = ref('springSecurityService')
}
}

Grails 3.2.8 not able to get springSecurityService.currentUser in controller

I'm unable to get springSecurityService.currentUser from a controller in Grails 3.2.8.
Please note that Grails 3.2.8 made some performance improvements not in previous versions that seem to be breaking Spring Security Core. As per Grails 3.2.8 dependency injection in domain classes, I set grails.gorm.autowire = true, which fixed that incompatibility.
Steps to reproduce:
Create a new Grails 3.2.8 web app with Spring Security 3.1.1 using Roles and Groups.
In application.yml, set grails.gorm.autowire = true
In Bootstrap:
def init = { servletContext ->
User user = new User(username: 'foo', password:'foo').save(flush: true)
Role role = new Role(authority: 'SomeRole').save(flush: true)
RoleGroup roleGroup = new RoleGroup(name: 'SomeRole').save(flush: true)
RoleGroupRole.create(roleGroup, role)
UserRoleGroup.create(user, roleGroup)
}
Create a controller TestController:
#Secured(['SomeRole'])
class TestController {
def springSecurityService
def index() {
println "springSecurityService==null? ${(springSecurityService==null).toString()}"
println "SecurityContextHolder.context==null? ${(SecurityContextHolder.context==null).toString()}"
println "SecurityContextHolder.context?.authentication==null? ${(SecurityContextHolder.context?.authentication==null).toString()}"
println "springSecurityService.principal==null? ${(springSecurityService.principal==null).toString()}"
println "springSecurityService.currentUser==null? ${(springSecurityService.currentUser==null).toString()}"
render "1" //Render something so we don't get an exception.
}
}
Start up the server and go to /test. The output is:
springSecurityService==null? false
SecurityContextHolder.context==null? false
SecurityContextHolder.context?.authentication==null? true
springSecurityService.principal==null? true
springSecurityService.currentUser==null? true`
Is there a good workaround?
If SecurityContextHolder.context is not null (it should never be null) but
SecurityContextHolder.context?.authentication is null, then this is probably not a Grails or a plugin issue - you're not authenticated. So there's no principal to get the cached user id from (i.e. springSecurityService.principal is null as your output shows) and there's no way to retrieve the current User instance.
SOLVED. Since version 3.2.8 there is this default setting in application.yml: grails.gorm.autowire=false. You have to set it to true then the services autowire as always.

Grail's Spring security: Use email instead of username to switch users in SwitchUserFilter

I have a modified User class in my spring security which use attribute email instead of username. Now I want to a functionality to switch users, so an admin can login seamlessly as a particular user without logging out. I came across this Link , which shows there is a switchUserFilter to achieve this. So I tried to get it working by passing j_username as email,but it gets redirected to a blank page and the user does not switch.
I have tried all these things but still could not figure out a way around it:
1) Added to Config.groovy:
grails.plugins.springsecurity.userLookup.usernamePropertyName='email'
2) Create a method in User class getUserName() to return email.
P.S: I looked into the source code of springSecurity switchUserFilter(link)and came across this code on line 209:
protected Authentication attemptSwitchUser(HttpServletRequest request)
throws AuthenticationException {
UsernamePasswordAuthenticationToken targetUserRequest;
String username = request.getParameter(usernameParameter);
But I am not sure if that is the issue and do not want to make changes in the plugin.
The usernameParameter property of the SwitchUserFilter is set to username by default. That does seem to be part of your problem.
The SwitchUserFilter has a method named setUsernameParameter() that allows you to change this default. It seems the filter is a bean, so you might be able to do something like this in grails-app/conf/spring/Config.groovy
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter
beans = {
switchUserFilter {
usernameParameter = 'email'
}
}
Or maybe something like this in grails-app/config/BootStrap.groovy
def switchUserFilter
def init = { servletContext ->
switchUserFilter.usernameParameter = 'email'
}
Finally found the solution: Add this to the config.groovy file
grails.plugin.springsecurity.userLookup.usernamePropertyName = 'email'
grails.plugin.springsecurity.useSwitchUserFilter = true
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
....
'/j_spring_security_switch_user': ['ROLE_SWITCH_USER', 'isFullyAuthenticated()'],
'/j_spring_security_exit_user': ['isFullyAuthenticated()'],
'/public/**': ['permitAll']
.....
]
2) Then create a Role ROLE_SWITCH_USER in bootstrap.groovy
def switchUserRole = Role.findByAuthority('ROLE_SWITCH_USER') ?: new Role(authority: 'ROLE_SWITCH_USER').save(flush: true, failOnError: true)
And assign it to a super user
3) Then follow the instruction(here) to update the view to add a switch button

Why grails domain validation reject a url like http://wctest.jenkins:8080/CRMGateway

Why grails domain validation reject a url like http://wctest.jenkins:8080/CRMGateway. Though the url supplied is correct in structure.Do this want it be a url with no port?
Below is the domain that I have
class Configuration{
String username
String password
String gatewayURL
//constraints
static constraints = {
gatewayUrl nullable: true, blank: false, url: true
}
}
In bootstrap file, code is like
Configuration config = new configuration(username:'abc',password:new
SHA256("w3lc0m3"),"http://wctest.jenkins:8080/CRMGateway")
config.save flush:true
It is because the default url validation rejects wctest.jenkins.
But it accepts wctest.com or wctest.ch.
If it is too restrictive, you will need to customize the validation (as in http://java.dzone.com/articles/grails-goodness-add-extra or using Grails custom validation).

grails 2.1.1 command object service injection for custom validator

Grails 2.1.1
I can't seem to get a command object to be injected with a service so that I can use custom validator. I've tried several things, including
Grails command object data binding and
what the 2.1.1 docs on custom validator suggest, I just can't figure this one out..
Relevant Code:
class RegistrationCommand {
String username
def registrationService
static constraints = {
username validator: { val, obj ->
obj.registrationService.isUsernameUnique(val) }
}
}
class RegistrationService {
def isUsernameUnique(username){
def user = new User(username:username)
user.validate()
if(user.errors.hasFieldErrors("username")){
return false
}else{
return true
}
}
Resolved.. Issue was due to plugin.
I'm using a plugin for client side jquery validation (jquery-validation-ui-1.4.2). The command object being created by the plugin's controller wasn't getting injected with the service. The issue was reported https://github.com/limcheekin/jquery-validation-ui/issues/17 . The fix does work but has not been pushed upstream yet.

Resources