spring security core secure custom url - spring

I am using grails 2.3.9 and spring-security-core:2.0-RC3 and using staticRules for security.
I have following security configurations in Config file:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.mkb.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.mkb.UserRole'
grails.plugin.springsecurity.authority.className = 'com.mkb.Role'
grails.plugin.springsecurity.useSwitchUserFilter = true
grails.plugin.springsecurity.logout.postOnly = false
grails.plugin.springsecurity.adh.errorPage = null
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll'],
'/controllerC/**': ['ROLE_USER'],
'/**': ['permitAll']
]
there security configurations works fine.
Now I have following URL mappings
"/test/controllerA/$action?/$id?(.${format})?"(controller: 'controllerA')
"/test/controllerB/$action?/$id?(.${format})?"(controller: 'controllerB')
and I required to set the security for the URLs that have /test/, ie., URLs myDomain.com/test/controllerA/** and myDomain.com/test/controllerB/** are accessible to users that have ROLE_ABC role.
I have tried with
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll'],
'/test/**': ['ROLE_ABC'],
'/**': ['permitAll']
]
but this did not work, any user can access the controllers.
How I define the security?
NOTE:- I cannot use #Secured annotations. I need securities in Config only

You would have to explicitly specify the controllers in static rules as below:
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
...
'/controllerA/**': ['ROLE_ABC'],
'/controllerB/**': ['ROLE_ABC'],
....
]
I think this is exactly how you already have for controllerC as
'/controllerC/**': ['ROLE_USER'],
Refer this answer for details. As the doc suggests, this is also applicable for controller from plugins where #Secured cannot be used if source code is unreachable.

You can use the below code if any user can access the controllers.
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
...
'/test/**': ['permitAll'],
...
]
And for particular user you can use Spring security annotations
Add the below line before the class name.
#Secured(['ROLE_ABC'])
you need to import
import org.springframework.security.access.annotation.Secured

I suggest you can use Filters in Grails : http://grails.org/doc/latest/guide/theWebLayer.html#filters
An example :
class SecurityFilters {
def filters = {
loginCheck(controller: '*', action: '*') {
before = {
if (!session.user && !actionName.equals('login')) {
redirect(action: 'login')
return false
}
}
}
}
}

Related

spring security encode password with bcrypt algorithm

i get something strange... in spring security for encode password..
i am trying to change my password and save it to database..but i always get error because defferent string..
like this..
in controller ..
println "password = "+oldPass
println "password 1 = "+springSecurityService.encodePassword('password')
println "password 2 = "+springSecurityService.encodePassword('password')
println "password = "+springSecurityService.encodePassword(oldPass)
and this ooutput
its strange...everytime i encodePassword, i will get different result.
i am using grails 3.0.5 and use bcrypt algorithm
grails.plugin.springsecurity.password.algorithm = 'bcrypt'
i put this line in application.groovy
like this
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.akiong.security.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.akiong.security.UserRole'
grails.plugin.springsecurity.authority.className = 'com.akiong.security.Role'
grails.plugin.springsecurity.requestMap.className = 'com.akiong.security.RequestMap'
grails.plugin.springsecurity.securityConfigType = 'Requestmap'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/error': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/shutdown': ['permitAll'],
'/assets/**': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll']
]
grails.plugin.springsecurity.password.algorithm = 'bcrypt'
but when i create an user account with bootstrap and save it to database..
then i login ...it run with correctly..
It's a feature. bcrypt uses a random salt, so each time it generates a different hash even for same password.
If you want to check if entered password is valid, you need to use passwordEncoder.isPasswordvalid for Grails, like:
assert passwordEncoder.isPasswordValid(
'$2a$10$Qb7ENpWOSsFUS2UvwT1BRefZhn55roXPgUI8fjJRm6c/nR3JIQP8a',
'password', null)
assert passwordEncoder.isPasswordValid(
'$2a$10$sC3.yrmNn2VLS2Aer359rei/DxoLlwFq7s6ndAHm10ncyQpIr3MfO',
'password', null)
or for plain Spring Security passwordEncoder.matches:
assert passwordEncoder.matches('password',
'$2a$10$Qb7ENpWOSsFUS2UvwT1BRefZhn55roXPgUI8fjJRm6c/nR3JIQP8a')
assert passwordEncoder.matches('password',
'$2a$10$sC3.yrmNn2VLS2Aer359rei/DxoLlwFq7s6ndAHm10ncyQpIr3MfO')
To autowire passwordEncoder bean just define it as a property of your class:
def passwordEncoder

Grails + Spring Security Rest + How to login

I have created as sample rest application using grails and added a security using spring security rest plugin. I am trying to test it using rest client POSTMAN but getting 404 to '$MYAPP/api/login' and 401 '$MYAPP/api/login/' to when I sent post request with username and password as json in raw data.
I have followed all the blogs and stackoverflow but non of the things worked for me. Here is my code.
In Config.groovy
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.example.api.auth.APIUser'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.example.api.auth.APIUserRole'
grails.plugin.springsecurity.authority.className = 'com.example.api.auth.Role'
grails.plugin.springsecurity.securityConfigType = 'InterceptUrlMap'
grails.plugin.springsecurity.interceptUrlMap = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/assets/**': ['permitAll'],
'/partials/**': ['permitAll'],
'/api/**': ['permitAll'],
'/**': ['isFullyAuthenticated()']
]
grails.plugin.springsecurity.filterChain.chainMap = [
'/api*//**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter', // Stateless chain
'*//**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
grails.plugin.springsecurity.rest.login.active=true
grails.plugin.springsecurity.rest.login.endpointUrl = '/api/login'
grails.plugin.springsecurity.rememberMe.persistent = false
grails.plugin.springsecurity.rest.login.useJsonCredentials = true
grails.plugin.springsecurity.rest.login.useRequestParamsCredentials = false
grails.plugin.springsecurity.rest.login.failureStatusCode = 401
grails.plugin.springsecurity.rest.login.usernamePropertyName = 'username'
grails.plugin.springsecurity.rest.login.passwordPropertyName = 'password'
grails.plugin.springsecurity.rest.token.storage.useGorm = true
grails.plugin.springsecurity.rest.token.storage.gorm.tokenDomainClassName = 'com.example.api.auth.AuthenticationToken'
grails.plugin.springsecurity.rest.token.storage.gorm.tokenValuePropertyName = 'token'
grails.plugin.springsecurity.rest.token.storage.gorm.usernamePropertyName = 'username'
grails.plugin.springsecurity.rest.token.storage.gorm.passwordPropertyName = 'password'
grails.plugin.springsecurity.rest.logout.endpointUrl = '/api/logout'
grails.plugin.springsecurity.rest.token.validation.headerName = 'X-Auth-Token'
grails.plugin.springsecurity.rest.token.validation.useBearerToken = false
In BuildConfig.groovy
// security
compile ":spring-security-core:2.0-RC4"
compile ":spring-security-rest:1.4.0.RC5", {
excludes ('cors','spring-security-core')
}
Please provide feedback if something is wrong in my configuration or the way of testing using POSTMAN.
This is my final config.groovy code which works.
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'example.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'example.UserRole'
grails.plugin.springsecurity.authority.className = 'example.Role'
grails.plugin.springsecurity.interceptUrlMap = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/assets/**': ['permitAll'],
'/partials/**': ['permitAll'],
'/api/**': ['isFullyAuthenticated()'],
'/**': ['isFullyAuthenticated()']
]
grails.plugin.springsecurity.filterChain.chainMap = [
'/auth/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter, -rememberMeAuthenticationFilter', // Stateless chain
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter', // Stateless chain
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
grails.plugin.springsecurity.rest.login.active=true
grails.plugin.springsecurity.rest.login.endpointUrl='/auth/login'
grails.plugin.springsecurity.rest.login.failureStatusCode=401
grails.plugin.springsecurity.rest.login.useJsonCredentials=true
grails.plugin.springsecurity.rest.login.usernamePropertyName='username'
grails.plugin.springsecurity.rest.login.passwordPropertyName='password'
grails.plugin.springsecurity.rest.logout.endpointUrl='/auth/logout'
grails.plugin.springsecurity.rest.token.storage.useGorm=true
grails.plugin.springsecurity.rest.token.storage.gorm.tokenDomainClassName='example.AuthenticationToken'
grails.plugin.springsecurity.rest.token.storage.gorm.tokenValuePropertyName='tokenValue'
grails.plugin.springsecurity.rest.token.storage.gorm.usernamePropertyName='username'
grails.plugin.springsecurity.rest.token.generation.useSecureRandom=true
//grails.plugin.springsecurity.rest.token.validation.headerName='X-Auth-Token'
grails.plugin.springsecurity.rest.token.generation.useUUID=false
grails.plugin.springsecurity.rest.token.validation.active=true
grails.plugin.springsecurity.rest.token.validation.endpointUrl='/auth/validate'

Grails Spring Security plugin and dbconsole

I use grails 2.4.3 and have installed the official grails security plugin
compile ":spring-security-core:2.0-RC4"
Before installing the plugin, i was able to access the Database console page in using the url
http://localhost:8080/tobu/dbconsole
However, after installing the plugin, i am not able to do so. I get the default login screen when i try to access the above mentioned URl and logging in through any user account shows the "access denied" page. How do i resolve this issue?
grails.project.groupId = appName
grails.mime.disable.accept.header.userAgents = ['Gecko', 'WebKit', 'Presto', 'Trident']
grails.mime.types = [ // the first one is the default format
all: '*/*', // 'all' maps to '*' or the first available format in withFormat
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
form: 'application/x-www-form-urlencoded',
html: ['text/html','application/xhtml+xml'],
js: 'text/javascript',
json: ['application/json', 'text/json'],
multipartForm: 'multipart/form-data',
rss: 'application/rss+xml',
text: 'text/plain',
hal: ['application/hal+json','application/hal+xml'],
xml: ['text/xml', 'application/xml']
]
grails.views.default.codec = "html"
grails.controllers.defaultScope = 'singleton'
grails {
views {
gsp {
encoding = 'UTF-8'
htmlcodec = 'xml' // use xml escaping instead of HTML4 escaping
codecs {
expression = 'html' // escapes values inside ${}
scriptlet = 'html' // escapes output from scriptlets in GSPs
taglib = 'none' // escapes output from taglibs
staticparts = 'none' // escapes output from static template parts
}
}
// escapes all not-encoded output at final stage of outputting
// filteringCodecForContentType.'text/html' = 'html'
}
}
grails.converters.encoding = "UTF-8"
grails.scaffolding.templates.domainSuffix = 'Instance'
grails.json.legacy.builder = false
grails.enable.native2ascii = true
grails.spring.bean.packages = []
grails.web.disable.multipart=false
grails.exceptionresolver.params.exclude = ['password']
grails.hibernate.cache.queries = false
grails.hibernate.osiv.readonly = false
environments {
development {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
// TODO: grails.serverURL = "http://www.changeme.com"
}
}
log4j.main = {
// 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'
}
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'tobu.Actor'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'tobu.ActorRole'
grails.plugin.springsecurity.authority.className = 'tobu.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/dbconsole': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/assets/**': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll']
]
I had to make the following changes to the static rules in the config file.
'/dbconsole/**': ['ROLE_USER'],
2019 UPDATE
I needed to tweak Shashank's answer a bit for it to work for me. I'm using Grails 3.3.9 and spring-security-core 3.2.3.
I had to add this line to the file grails-app/conf/application.groovy
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
//.......
[pattern: '/dbconsole/**', access: ['ROLE_USER']]
]
I wanted to have the dbconsole accessible without my custom authentication made using the Spring Security Core plugin (the dbconsole has its own login page and it's enabled for the dev environment only). Originally, I was trying the following static rule in the grails-app/conf/application.groovy file:
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/dbconsole', access: ['permitAll']],
...which didn't have any effect. I have always been redirected to Spring Security Core's login page.
After reading other answers of this question, I have managed to create a working static rule so http://localhost:8080/dbconsole is not secured by the Spring Security Core plugin anymore:
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/dbconsole/**', access: ['permitAll']],
The trick is to create a static rule for /dbconsole and all sub-paths (when dbconsole is accessed, it redirects to a login page located at dbconsole/login.jsp), that's why the double-stars are needed.

grails spring security rest plugin how to skip url from authentication

I am using spring security rest plugin as well as core in my grails app,i want to have some calls those can be accessed without authentication and for this i am adding #Secured('permitAll') on action but it is not working,it is still asking for token.
I have also tried '/api/getdata': ['permitAll'] in config.groovy,but no result!!!
You need to add the anonymous filter to your filter chain.
If you followed the grails spring security rest configuration tutorial you probably got the following code:
grails.plugin.springsecurity.filterChain.chainMap = [
//Stateless chain
[
pattern: '/**',
filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'
]
]
Note that you have "-anonymousAuthenticationFilter" , which removes this filter from your filter chain.
By removing this part (-anonymousAuthenticationFilter) from your code, this filter will back to your filter chain,
so you can use the #Secured("permitAll") or #Secured(['IS_AUTHENTICATED_ANONYMOUSLY']) again.
My final filter chain map was the following and worked like a charm.
grails.plugin.springsecurity.filterChain.chainMap = [
//Stateless chain
[
pattern: '/**',
filters: 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'
]
]
Add this to you logback.groovy in the development environment when you need to see more details about the authentication process
logger("org.springframework.security", DEBUG, ['STDOUT'], false)
logger("grails.plugin.springsecurity", DEBUG, ['STDOUT'], false)
logger("org.pac4j", DEBUG, ['STDOUT'], false)
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
root(ERROR, ['STDOUT', 'FULL_STACKTRACE'])
The same idea applies if you do not use spring security rest.
Same answer I gave in another post, didn't knew what to do.
use static mapping..
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/user/someaction1': ['permitAll'],
'/user/someaction1': ['permitAll'],
]

Grails spring security defaultTargetUrl going wrong path

Grails 2.4 with Spring security 2 3RC
I have this on my Config.groovy
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll']
]
grails.plugin.springsecurity.successHandler.defaultTargetUrl = "/home/index"
But this keeping me redirecting to
assets/favicon.ico
And my HomeController is like that
#Secured(['ROLE_ADMIN', 'ROLE_USER'])
def index() {
if (SpringSecurityUtils.ifAllGranted('ROLE_ADMIN')) {
redirect controller: 'admin', action: 'index'
return
}
}
And I modify this in my UrlMapping:
"/"(controller: 'home', action:'index')
Why it keeps me sending wrong path?
Update: using another computer, it redirects me to /asset/grails_logo.png
It sounds like you are having a similar problem to the one I experienced upgrading a Grails 1.x application to 2.4.2. When you attempt to access a URL/page that is protected by Spring Security authorization rules and you are not logged in, it redirects you to the login page. Upon successful login, it redirects you to the URL you requested. In this case, your favicon.ico and grails_logo.png are being protected by authorization rules, unintentionally I'm guessing, so it redirects you to the login page. Upon successful login, it redirects you to the favicon.ico or grails_logo.png URL because that is protected URL that was being requested when authorization failed. Change your authorization rules accordingly (may want to do both if you have assets in both locations):
If you are using the Asset Pipeline Plugin, use:
'/assets/**': ['permitAll']
If you are using something like the Resources Plugin, use:
'/css/**': ['permitAll'],
'/js/**': ['permitAll'],
'/images/**': ['permitAll']

Resources