I am using grails 2.3.3 and groovy 2.2.0 version for my project. I was working fine until I decided to upgrade spring security core 1.2.7.3, ui 0.2 and acl 1.1.1 to spring security core 2.0, ui 1.0 and acl 2.0. I upgraded successfully. But When I try to login, I get "Sorry, you're not authorized to view this page." denied access message.
I have created users in bootstrap.groovy file which is below.
Bootstrap.groovy
import com.vproc.member.Address;
import com.vproc.member.Profile;
import com.vproc.member.Role ;
class BootStrap {
def init = { servletContext ->
def userRole = Role.findByAuthority('ROLE_USER') ?: new Role(authority: 'ROLE_USER').save(failOnError: true)
def adminRole = Role.findByAuthority('ROLE_COMPANY_ADMIN') ?: new Role(authority: 'ROLE_COMPANY_ADMIN').save(failOnError: true)
def guestRole = Role.findByAuthority('ROLE_GUEST') ?: new Role(authority: 'ROLE_GUEST').save(failOnError: true)
def csrRole = Role.findByAuthority('ROLE_CSR') ?: new Role(authority: 'ROLE_CSR').save(failOnError: true)
//PersonRole.create adminUser, adminRole
def address = new Address( city : 'Pune' , stateCode : 'MH' , countryCode : 'IN' )
def adminProfile = Profile.findByEmailAddress('[email protected]' )?: new Profile(
//privacyLevel: ProfilePrivacyLevelEnum.Private,
emailAddress: "[email protected]" ,
phoneNumber: "9325507992",
//status : 'Active'
) //.save( failOnError: true)
def adminPerson = Person.findByUsername( 'admin') ?: new Person( username : 'admin' , password : 'passw0rd' , enabled: true , firstName: 'admin' , lastName : 'user' , profile: adminProfile , status: StatusEnum.Active ).save( failOnError: true) ;
def vprocOrganization = Organization.findByOrgName('VPROCURE') ?: new Organization ( orgName: 'VPROCURE' , orgSize : 100 , mailingAddress: address, contact: adminPerson ).save( failOnError: true)
def vprocCustomer = Customer.findByParty( vprocOrganization) ?: new Customer ( party: vprocOrganization, status: StatusEnum.Active ).save(failOnError: true) ;
def adminUser = Subscriber.findByParty(adminPerson) ?: new Subscriber( party: adminPerson, customer: vprocCustomer , status: StatusEnum.Active ).save( failOnError: true)
if ( !adminUser.authorities.contains(adminRole)){
SubscriberRole.create adminUser, adminRole
}
JSON.registerObjectMarshaller(Date) {
return it?.format("MM/dd/yyyy")
}
def userProfile = Profile.findByEmailAddress( '[email protected]') ?: new Profile(
//privacyLevel: ProfilePrivacyLevelEnum.Private,
emailAddress: "[email protected]",
phoneNumber : "9325507992",
//status : 'Active'
) //.save( failOnError: true)
def userPerson = Person.findByUsername( 'plainuser') ?: new Person(username: 'plainuser', password : 'passw0rd' , enabled: true , firstName: 'plain' , lastName : 'user' , profile: userProfile , status: StatusEnum.Active).save( failOnError: true) ;
def plainUser = Subscriber.findByParty(userPerson) ?: new Subscriber( party: userPerson, customer: vprocCustomer , status: StatusEnum.Active ).save( failOnError : true )
if ( !plainUser.authorities.contains(userRole)){
SubscriberRole.create plainUser, userRole
}
Category electornicsCat = Category.findByName('Electronics') ?: new Category( name:"Electronics" , description: "Electronics market").save(failOnError: true);
Category realEstateCat = Category.findByName('Real Estate') ?: new Category( name:"Real Estate" , description: "Real Estate market").save(failOnError: true);
SubCategory subcatServices = SubCategory.findByNameAndCategory( 'Services' , electornicsCat ) ?: new SubCategory( name: 'Services', category: electornicsCat).save(failOnError: true);
SubCategory subcatConsumerGoods = SubCategory.findByNameAndCategory( 'Consumer Goods' , electornicsCat ) ?: new SubCategory( name: 'Consumer Goods', category: electornicsCat).save(failOnError: true);
SubCategory subcatFlate= SubCategory.findByNameAndCategory('Flate',realEstateCat) ?: new SubCategory(name: 'Flate', category: realEstateCat).save(failOnError: true)
SubCategory subcatHousing = SubCategory.findByNameAndCategory('House',realEstateCat) ?: new SubCategory(name: 'House', category: realEstateCat).save(failOnError: true)
/*vprocCustomer.addToSubscribers(amdinUser)
vprocCustomer.addToSubscribers(plainUser)
vprocCustomer.save( failOnError : true);*/
}
def destroy = {
}
}
Config.groovy
grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination
grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format
grails.views.default.codec = "none" // none, html, base64
grails.resources.modules = {
'custom-bootstrap' {
dependsOn 'bootstrap'
resource url:[dir: 'less', file: 'custom-bootstrap.less'], attrs:[rel: "stylesheet/less", type:'css']
}
}
// set per-environment serverURL stem for creating absolute links
environments {
development {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
// TODO: grails.serverURL = "http://www.changeme.com"
}
}
// log4j configuration
log4j = {
// Example of changing the log pattern for the default console
// appender:
//
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
error 'grails.app'
/* root {
error 'stdout'
info 'stdout'
warn 'stdout'
debug 'stdout'
additivity = true
}*/
}
// Added by the Spring Security Core plugin:
/*grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.vproc.member.Person'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.vproc.member.PersonRole'
grails.plugins.springsecurity.authority.className = 'com.vproc.member.Role'*/
grails.plugin.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
grails.plugin.springsecurity.interceptUrlMap = [
'/login/selectOrg' : [],
'/enquiry2/**': ['ROLE_USER', 'ROLE_COMPANY_ADMIN'],
'/subscriber/**': ['ROLE_USER', 'ROLE_COMPANY_ADMIN'],
'/contact/*': ['ROLE_USER', 'ROLE_COMPANY_ADMIN'],
'/**': ['IS_AUTHENTICATED_ANONYMOUSLY']
]
// Added by the Spring Security Core plugin:
grails.attachmentable.poster.evaluator = { getPrincipal() }
// twitter boot strap
grails.plugins.twitterbootstrap.fixtaglib = true grails.plugins.twitterbootstrap.defaultBundle = 'bundle_bootstrap' grails.plugin.springsecurity.securityConfigType = "Annotation" grails.plugin.springsecurity.password.algorithm='bcrypt'
BuildConfig.groovy
plugins {
build ':tomcat:7.0.47'
runtime ':hibernate:3.6.10.4'
runtime ":jquery:1.10.2"
compile ":class-diagram:0.5.2"
compile ':spring-security-core:2.0-RC2'
runtime ':resources:1.2'
runtime ":prototype:1.0"
compile ":webxml:1.4.1"
runtime ":cached-resources:1.0"
runtime ":zipped-resources:1.0"
compile ":cache-headers:1.1.5"
compile ":attachmentable:0.3.0"
compile ":avatar:0.6.3"
runtime ':spring-security-acl:2.0-RC1'
compile ":cloud-bees:0.6.2"
compile ":jquery-datatables:1.7.5"
compile ":jquery-validation:1.9"
compile ":jquery-validation-ui:1.4.7"
compile ":twitter-bootstrap:2.3.2"
compile ":lesscss-resources:1.3.3"
compile ":fields:1.3"
compile ":scaffolding:2.0.1"
compile ":jquery-ui:1.10.3"
compile ":spring-security-ui:1.0-RC1"
compile ":mail:1.0.1"
compile ":famfamfam:1.0.1"
compile ":burning-image:0.5.1"
}
}
Note: With previous versions of spring security core, I was able to login with users created from bootstrap. But now I facing access denied issue. Any take on this !
I tried with following solution suggested by @burt-beckwith from grails mailing thread and worked for me like charm and which is following.
grails.plugin.springsecurity.rejectIfNoRule = false
grails.plugin.springsecurity.fii.rejectPublicInvocations = false
grails.plugin.springsecurity.securityConfigType = 'InterceptUrlMap'
grails.plugin.springsecurity.interceptUrlMap = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll'],
'/login/**': ['permitAll'],
'/logout/**': ['permitAll']
]
I made only one change that differs from thread because what thread says, did not work for me. SO I made some changes, which is following:
grails.plugin.springsecurity.fii.rejectPublicInvocations = false
A big thanks to @burt-beckwith.
the new update of the security plugin uses a pessimistic approach for url locking, meaning that it locks the access to all the urls by default unless explicitly specified. So what might be happening in your case that after successful authentication, your default success url might be locked by the new version of the plugin. There are three solutions to this :
1) Use @burt-beckwith solution and change the rejectPublicInvocations parameter under config.groovy
grails.plugin.springsecurity.fii.rejectPublicInvocations = false
2) Unblock your default success url eg:
'/user/' : ['ROLE_ADMIN']**
or
'/homepage/' : ['permitAll']**
3) Explicitly define permission in your success controller or action eg:
Controller: @Secured(['ROLE_ADMIN','ROLE_USER'])
}
Action:
@Secured(['permitAll'])
}
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With