How do you configure Spring Security Rest Plugin for Grails 3.x (currently I'm using Grails 3.1.0 RC2).
The plugin page says to "Add compile :spring-security-rest:${version} to your BuildConfig.groovy," but BuildConfig.groovy has been removed from Grails 3.x
edit: the docs on the plugin page have been updated
SO I got this working. First off, the documentation located [here][1] is much more up to date. You need to add the following to build.gradle
build.gradle
dependencies {
//Other dependencies
compile "org.grails.plugins:spring-security-rest:2.0.0.M2"
}
Next, you need to run Spring Security quickstart
grails s2-quickstart com.yourapp Person Role
Finally, you need to configure the filter chain but adding the following into your application.groovy.
application.groovy
grails.plugin.springsecurity.filterChain.chainMap = [
//Stateless chain
[
pattern: '/api/**',
filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'
],
//Traditional chain
[
pattern: '/**',
filters: 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'
]
]
Alternatives:
I decided to move the configuration to application.yml, so I'm not using two different configuration syntaxes.
Alternative config #1:
using application.yml with standard default settings
grails:
# other config values
plugin.springsecurity:
userLookup.userDomainClassName: 'com.company.product.Person'
userLookup.authorityJoinClassName: 'com.company.product.PersonRole'
authority.className: 'com.company.product.Role'
controllerAnnotations.staticRules:
- {pattern: '/', access: ['permitAll']}
- {pattern: '/error', access: ['permitAll']}
- {pattern: '/index', access: ['permitAll']}
- {pattern: '/index.gsp', access: ['permitAll']}
- {pattern: '/shutdown', access: ['permitAll']}
- {pattern: '/assets/**', access: ['permitAll']}
- {pattern: '/**/js/**', access: ['permitAll']}
- {pattern: '/**/css/**', access: ['permitAll']}
- {pattern: '/**/images/**', access: ['permitAll']}
- {pattern: '/**/favicon.ico', access: ['permitAll']}
filterChain.chainMap:
- {pattern: '/assets/**', filters: 'none'}
- {pattern: '/**/js/**', filters: 'none'}
- {pattern: '/**/css/**', filters: 'none'}
- {pattern: '/**/images/**', filters: 'none'}
- {pattern: '/**/favicon.ico', filters: 'none'}
#Stateless chain
- {pattern: '/api/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'}
#Traditional chain
- {pattern: '/**', filters: 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'}
I also (this is totally optional)
removed all of the generated config that pertains to serving GSPs since my app is just an API
configured the plugin to persist the authorization token using GORM
replaced the default bearer tokens config with the X-Auth-Token config
so I ended up with this
Alternative config #2:
using application.yml with API only (No GSPs) with GORM token storage and X-Auth-Tokens instead of Bearer Tokens
grails:
# other config values
plugin.springsecurity:
userLookup.userDomainClassName: 'com.company.product.Person'
userLookup.authorityJoinClassName: 'com.company.product.PersonRole'
authority.className: 'com.company.product.Role'
filterChain.chainMap:
#Stateless chain
- {pattern: '/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'}
rest.token:
storage.gorm.tokenDomainClassName: 'com.company.product.AuthenticationToken'
validation:
useBearerToken: false
headerName: 'X-Auth-Token'
Related
While trying to configure and create an admin user for rabbitmq with a JSON file. The users are created. But I am getting the following error while logging in with valid credentials from the web management console.
2022-07-22 08:15:56.342071+00:00 [warning] <0.847.0> HTTP access denied: user 'admin' - invalid credentials
My configurations and docker files are as follows.
rabbitmq.config
[
{rabbit, [
{loopback_users, [admin]}
]},
{rabbitmq_management, [
{load_definitions, "/etc/rabbitmq/definitions.json"}
]}
].
definitions.json
{
"users": [
{
"name": "guest",
"password_hash": "abcd",
"hashing_algorithm": "rabbit_password_hashing_sha256",
"tags": ""
},
{
"name": "admin",
"password_hash": "admin123",
"hashing_algorithm": "rabbit_password_hashing_sha256",
"tags": "administrator"
}
],
"vhosts": [
{
"name": "/"
}
],
"permissions": [
{
"user": "admin",
"vhost": "/",
"configure": ".*",
"write": ".*",
"read": ".*"
}
],
}
FROM rabbitmq:3.9-management
COPY conf/rabbitmq.config /etc/rabbitmq/
COPY conf/definitions.json /etc/rabbitmq/
RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json
CMD ["rabbitmq-server"]
I also tried to log in with rabbitmqctl
>>rabbitmqctl authenticate_user admin admin123
Authenticating user "admin" ...
Error:
Error: failed to authenticate user "admin"
user 'admin' - invalid credentials
When the password is changed with rabbitmqctl change_password admin admin123 everything seems to work fine.
The only warning in the log on rabbitmq startup is
2022-07-22 08:15:30.218099+00:00 [warning] <0.652.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_persistent": rebuilding indices from scratch
Could someone please tell me the possible cause and solution? If I've missed out anything, over- or under-emphasized a specific point, please let me know in the comments. Thank you so much in advance for your time.
Your definitions file must contain the HASH of the password, not the password itself. Generally what I do is set a user's password via change_password like you have, then export the current definitions. You'll notice that they contain the hashed password.
You can also generate the hash yourself. See this:
How to generate password_hash for RabbitMQ Management HTTP API
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
I deployed an envoy as a side car to manage oauth2. Everything work fine for all the resources and the client is redirected to the OIDC in order to authenticate.
Here is a part of my conf (managed in a Helm chart):
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
access_log:
- name: envoy.access_loggers.file
typed_config:
"#type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /dev/stdout
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: my-service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: my-service
http_filters:
- name: envoy.filters.http.oauth2
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
config:
token_endpoint:
cluster: {{ .Values.back.envoy.oidc.name }}
uri: https://{{ .Values.back.envoy.oidc.address }}/oidc/token
timeout: 5s
authorization_endpoint: https://{{ .Values.back.envoy.oidc.address }}/oidc/authorize
redirect_uri: "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oidc/callback"
redirect_path_matcher:
path:
exact: /oidc/callback
signout_path:
path:
exact: /oidc/signout
credentials:
client_id: {{ required "back.envoy.oidc.client_id is required" .Values.back.envoy.oidc.client_id }}
token_secret:
name: token
sds_config:
resource_api_version: V3
path: "/etc/envoy/token-secret.yaml"
hmac_secret:
name: hmac
sds_config:
resource_api_version: V3
path: "/etc/envoy/hmac-secret.yaml"
forward_bearer_token: true
# (Optional): defaults to 'user' scope if not provided
auth_scopes:
- user
- openid
- email
- homelan_devices_read
- homelan_topology_read
- homelan_devices_write
# (Optional): set resource parameter for Authorization request
#resources:
#- oauth2-resource
#- http://example.com
- name: envoy.filters.http.router
typed_config: {}
Now I'd like that some of the exposed resources don't need to be authenticated.
I see in the doc the Oauth filter doc "Leave this empty to disable OAuth2 for a specific route, using per filter config." (see https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/oauth2/v3/oauth.proto#envoy-v3-api-msg-extensions-filters-http-oauth2-v3-oauth2config)
This phrase make me think that it may be possible.
I tried to manage it changing my conf throught virtual_hosts this way :
virtual_hosts:
- name: no-oauth
domains: ["*"]
typed_per_filter_config:
envoy.filters.http.oauth2:
"#type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
routes:
- match:
prefix: "/api/v1/myResource1"
route:
cluster: my-service
- name: my-service
domains: ["*"]
routes:
- match:
prefix: "/api/v1/myResource2"
route:
cluster: my-service
I have the error : [critical][main] [source/server/server.cc:117] error initializing configuration '/etc/envoy/envoy.yaml': The filter envoy.filters.http.oauth2 doesn't support virtual host-specific configurations
Any idea ? Did someone implement Envoy OAuth2 filter with disabled routes ?
After looking at my envoy logs, I realized that path is know as header ":path".
The pass_through_matcher math the header.
Then only adding:
pass_through_matcher:
- name: ":path"
prefix_match: "/healthz"
- name: ":path"
prefix_match: "/api/v1/myResource1"
in my conf without the lua filter (see my previous answer) it works.
For information, I found a workaround:
I added a LUA filter before my OAuth2 one:
- name: envoy.filters.http.lua
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
function envoy_on_request(request_handle)
request_handle:headers():add("X-Path", request_handle:headers():get(":path"))
end
In order to add the path in a header.
Then I can use this element of conf Oauth2:
pass_through_matcher
(repeated config.route.v3.HeaderMatcher) Any request that matches any of the provided matchers will be passed through without OAuth validation.
So I add this to my OAuth2 filter:
pass_through_matcher:
- name: "X-path"
prefix_match: "/healthz"
- name: "X-path"
prefix_match: "/api/v1/myResource1"
Then my /api/v1/myResource1 requests (and healthz also) don't need authentication (are disable from the OAuth2) while my /api/v1/myResource2 requests need it.
I still have got the unanswered question:
What do the OAuth filter doc means with :"Leave this empty to disable OAuth2 for a specific route, using per filter config."
I need to handle GLTF and HDR files in my Vue/Three.js application. This doesn't work out of the box with Vite. With Webpack I can set this in the Webpack config
module.exports = {
module: {
rules: [
{
test: /\.(gltf)$/i,
use: [
{
loader: 'url-loader',
},
],
},
],
},
};
Is there a way to do the same in Vite?
Seems like Vite can handle this out of the box. The problem was the cors settings of the server the files were on.
I'm implementing Universal Links on iOS 9+ and am trying to add the apple-app-site-association file to my Firebase Hosting root:
https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/
If your app runs in iOS 9 and later and you use HTTPS to serve the file, you can create a plain text file that uses the application/json MIME type and you don’t need to sign it.
How can I set the MIME type to "application/json"? It looks like the documentation does not list this as a possible content type.
Google Firebase Hosting has been updated to include this content type. Just add the declaration to your app config firebase.json.
Update your firebase hosting config file "firebase.json" like this; you can provide the content-type, response code as well.
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
"hosting": {
"public": "dist/my_app",
"ignore": [
"firebase.json",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
},
{
"source": "/.well-known/assetlinks.json",
"destination": "/.well-known/assetlinks.json",
"content-type": "application/json",
"code":200
}
]
}
}
For some reason my staticRules are not applied.
Adding the "org.grails.plugins:spring-security-core:3.0.0.M1" plugin and executing
grails s2-quickstart com.testapp User Role
successfully created the Role User and UserRole Domains.
Also an application.groovy file with some settings was created.
But I am using an application.yml file to configure my app.
So I moved the properties to my application.yml and deleted the .groovy file.
For some reason the staticRules are not applied. Maybe there is a syntax error.
---
grails:
plugin:
springsecurity:
userLookup:
userDomainClassName: 'User'
authorityJoinClassName: 'UserRole'
authority:
className: 'Role'
apf:
postOnly: false
password:
algorithm: 'bcrypt'
controllerAnnotations:
staticRules:
/: permitAll
/error: permitAll
/index: permitAll
/index.gsp: permitAll
/shutdown: permitAll
/assets/**: permitAll
/**/js/**: permitAll
/**/css/**: permitAll
/**/images/**: permitAll
/**/favicon.ico: permitAll
mime:
disable:
accept:
header:
userAgents:
...
I have tried multiple variants like
'/': 'permitAll'
/: 'permitAll'
But everytime I open localhost:8080/ i am prompted to login!
The new Spring security configuration in YML looks like this:
---
grails:
plugin:
springsecurity:
userLookup.userDomainClassName: 'org...User'
userLookup.authorityJoinClassName: 'org...UserRole'
authority.className: 'org...Role'
controllerAnnotations.staticRules:
- pattern: '/'
access: ['permitAll']
- pattern: '/index'
access: ['permitAll']
- pattern: '/index.gsp'
access: ['permitAll']
- pattern: '/error'
access: ['permitAll']
- pattern: '/user/denied'
access: ['permitAll']
- pattern: '/assets/**'
access: ['permitAll']
- pattern: '/**/js/**'
access: ['permitAll']
- pattern: '/**/css/**'
access: ['permitAll']
- pattern: '/**/images/**'
access: ['permitAll']
- pattern: '/**/favicon.ico'
access: ['permitAll']
For testing purposes (to ensure that this configuration works) permit all on top of all static rules, but be sure to remove it later:
- pattern: '/**'
access: ['permitAll']