grails spring security rest plugin how to skip url from authentication - spring

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'],
]

Related

Configuring Swagger UI for OAuth 2.0 in Spring Boot with Kotlin

I am trying to configure OpenAPI 3 for OAuth 2.0 with a configuration class in Spring Boot with Kotlin.
Even though I set oauth2RedirectUrl in application.yml, when I click authorize in swagger UI to get new token to send a request, redirect url doesn't work as expected and I get the default redirect url called something like that(I believe it's a default redirectUrl): &redirect_uri=http://localhost:8080/oauth2-redirect.html instead of (what i configured in application.yaml)
Access the Swagger-UI at http://localhost:8080/swagger-ui/index.html?queryConfigEnabled=true&url=/v3/api-docs
Then click the authorize button and use the preconfigured values.
The IdentityProviderController prints then the configured values, e.g. redirect_uri.
The redirect_uri looks like http://localhost:8080/swagger-ui/oauth2-redirect.html and the swagger-ui:oauth2RedirectUrl path is missing. Even when it is configured in the application.yaml.
I added the following dependencies:
implementation("org.springdoc:springdoc-openapi-ui:1.6.14")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.14")
implementation("org.springdoc:springdoc-openapi-security:1.6.14")
and this is my application.yml
springdoc:
api-docs:
enabled: true
swagger-ui:
query-config-enabled: true
oauth:
client-id: <clientId>
client-secret: <clientSecret>
use-pkce-with-authorization-code-grant: true
oauth2RedirectUrl: <redirectUrl>
and this here is my configuration class:
#Configuration
#OpenAPIDefinition
#SecurityScheme(
name = "oauth2",
type = SecuritySchemeType.OAUTH2,
flows =
OAuthFlows(
authorizationCode =
OAuthFlow(
authorizationUrl = "<authorizationUrl>",
tokenUrl = "<tokenUrl>",
scopes =
[
OAuthScope(name = "test1"),
OAuthScope(name = "test2"),
OAuthScope(name = "test3")],
)))
open class OpenApiConfiguration {
#Bean
open fun customOpenAPI(): OpenAPI {
return OpenAPI()
.components(Components())
.info(
Info()
.title("ABC Service Rest API")
.description("description...")
.version("1.0.0"))
}
}
What am I missing here?
UPDATE: (17.02.2023)
After I am changing the redirect_uri in chrome with the correct one, then I can reach the Identity proverders' page, so I only need to find a way to set my redirectUrl configuration properly.

Spring Boot Actuator - env endpoint provides response with active_profiles and property_sources

Once I invoke spring actuator endpoint (http://localhost:8080/actuator/env) it provides response in following format which include _ in between,
{
active_profiles: [ ],
property_sources: [
.....
This includes underscore in between, and this is different comparing to our other services. My expected response is without '_' as follows:
activeProfiles: [ ],
propertySources: [
I am not sure why it generates response with '_' can someone please help on this,
Thanks

Grails spring security oauth2 provider request for resource with correct bearer token redirects to login

As the title implies, I have a controller method protected by the oAuth2 plugin, but when I send a request to it including a correct Authorization: Bearer <token> (using Postman), the response I get is the HTML for the login page.
Method in question:
#Secured(["ROLE_USER", "#oauth2.clientHasAnyRole('ROLE_CLIENT', 'ROLE_TRUSTED_CLIENT')"])
def getUserData(){
response.setContentType("application/json")
User u = springSecurityService.currentUser
println u
render u.mseUserInfo
}
Config.groovy:
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.auth.loginFormUrl = '/mse/login'
grails.plugin.springsecurity.userLookup.userDomainClassName = 'cz.improvisio.MSEauthProvider.user.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'cz.improvisio.MSEauthProvider.user.UserRole'
grails.plugin.springsecurity.authority.className = 'cz.improvisio.MSEauthProvider.user.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/oauth/authorize.dispatch':[
"ROLE_USER",
"isFullyAuthenticated()"
],
'/oauth/token.dispatch':[
"ROLE_USER",
"isFullyAuthenticated()"
],
'/mse/login':["permitAll"],
'/mse/':["permitAll"],
'/**':["permitAll"]]
// Added by the Spring Security OAuth2 Provider plugin:
grails.plugin.springsecurity.oauthProvider.clientLookup.className = 'cz.improvisio.MSEauthProvider.user.Client'
grails.plugin.springsecurity.oauthProvider.authorizationCodeLookup.className = 'cz.improvisio.MSEauthProvider.user.AuthCode'
grails.plugin.springsecurity.oauthProvider.accessTokenLookup.className = 'cz.improvisio.MSEauthProvider.user.AccessToken'
grails.plugin.springsecurity.oauthProvider.refreshTokenLookup.className = 'cz.improvisio.MSEauthProvider.user.RefreshToken'
grails.plugin.springsecurity.filterChain.chainMap = [
'/oauth/token': 'JOINED_FILTERS,-oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter',
'/securedOAuth2Resources/**': 'JOINED_FILTERS,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter'
]
This is the client creation from Bootstrap.groovy:
new Client(
clientId: 'testClient',
authorizedGrantTypes: [
'authorization_code',
'refresh_token',
'implicit',
'password',
'client_credentials'
],
authorities: ['ROLE_CLIENT'],
scopes: ['read', 'write'],
redirectUris: ['http://test.com']).save(flush: true)
And one more slightly related question: I couldnt find a way to get the User to whose resources the access token should be linked to, so I assumed Id be able to get it through springSecurityService. Is this the correct way of doing so? Or do I need to pass the userId to the method (and will OpenAM do it?)?
Turns out I didnt have the proper filter chain set up for my action. Changing config to
grails.plugin.springsecurity.filterChain.chainMap = [
'/oauth/token': 'JOINED_FILTERS,-oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter',
'/securedOAuth2Resources/**': 'JOINED_FILTERS,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter',
'/myController/getUserData': 'JOINED_FILTERS,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter'
]
fixed it.

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 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