spring cloud gateway, can you exclude paths (do a global !=) - spring-boot-actuator

I'm hoping someone can provide some ideas here. I'm playing around with some of the sample apps for the spring cloud gateway and going through the docs but I'm not seeing any way to route to self or do a global ignore. The idea here is that there are some paths that ALWAYS need to point to self, like for the actuator, and other that may need a global block (maybe for security reasons like you've found a severe vulnerability and need to disable access to a specific resource). Right now from what I can tell there is no way to do this, but I hope I'm wrong!
I've set up the app with the actuator running on port 8081 and the server on 8080.
I've got two simple rules:
- id: local_test_1
uri: http://localhost:80
order: 9000
predicates:
- Path=/echo
# =====================================
- id: local_test_2
uri: ${test.uri}
order: 10000
predicates:
- Path=/**
But the universal /** makes sure that any call to localhost:8081/actuator/* also gets routed to the uri. How can I exempt the management port from routing rules so the server itself will deal with the request?
I thought a default filter like - Path!=${management.server.port}/* might work, but it seems that != isn't supported.

I ran into this same problem when using a default route, but also needing to serve a custom post-logout page from the classpath. The default route would handle the request instead of the gateway itself. Without the default route the logout.html was served correctly.
I ended up moving the default route to a Java bean and used the fluent API like this:
#Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("default", r -> r
.order(Ordered.LOWEST_PRECEDENCE)
.path("/**")
.and().not(p -> p.path("/logout.html", "/logout.css"))
.uri("http://localhost:8080")
)
.build();
}
If someone knows of a way to do negation in the .yml configuration files that would be ideal, but I have yet to find an example of that in any docs.

You can use no://op as value for uri:.
The only disadvantage, that I see, is that any endpoint, which is not supposed to be found (like /actuator/foo) would still return 200 OK.

- id: local_test_1
uri: http://localhost:80
order: 9000
predicates:
- Path=/echo
# =====================================
- id: local_test_2
uri: ${test.uri}
order: 10000
predicates:
- Path=/**
Try add two space before - Path, the problem may be you config is not working.

maybe you can use - Path=/** and - setStatus=404 for its filter and for actuator route - Path=/actuator/** and - setStatus=ACCEPTED don't forget to uri: no://op for both

Related

Symfony login via link into different firewall

I have two firewalls in my Symfony (5.4) application.
What I want is to create a login link for another firewall (where the login_link is configured) while logged in into the other firewall.
Currently the system doesn’t allow that (No Symfony\Bundle\SecurityBundle\LoginLink\LoginLinkHandler found for this firewall. Did you forget to add a "login_link" key under your "admin_area" firewall?)
Is there a way to tell the login link creator to create the link for a specific firewall? (I didn’t see it in the implementation so I don’t really know).
UPDATE 2022-06-10: Beginning with Symfony 6.1, just use the new Autowire-Attribute like this:
public function myLoginLinkAction(
User $myUser,
#[Autowire(service: 'security.authenticator.login_link_handler.my_other_firewall')] LoginLinkHandlerInterface $myOtherFirewallLoginLinkHandler,
): Response
{
// …
$loginLinkDetails = $myOtherFirewallLoginLinkHandler->createLoginLink($myUser);
// …
}
For older Symfony versions:
The solution is to inject the concrete link handler service for my other firewall using an alias defined in security.yaml (where the other firewall that we want to build login links for is named "my_other_firewall"):
services:
# define a concrete alias for the login link handler of the
# my_other_firewall firewall to avoid the FirewallAwareLoginLinkHandler
# that always uses the current request's firewall
Symfony\Component\Security\Http\LoginLink\LoginLinkHandlerInterface $myOtherFirewallLoginLinkHandler: '#security.authenticator.login_link_handler.my_other_firewall'
Then, when I inject the LoginLinkHandlerInterface to my login link building controller, I use the defined parameter name $myOtherFirewallLoginLinkHandler and get the correct LoginLinkHandler injected instead of the FirewallAwareLoginLinkHandler that only exists to use the LoginLinkHandler defined for the firewall of the current request.
This solves the problem the documented way to use concrete implementations, when more than one implements a certain interface.

Symfony and API Platform: custom URL for default implementation of CRUD operations

I am trying to set up an API. I would like to use the default implementation of CRUD operations for GET requests and override the operations for POST, PUT and DELETE. That works actually very well already.
But my problem now is, that I would like to change the URL of the default implementation, so it fits to the URLs of my custom operations.
My Code looks something like that:
#ApiResource(
itemOperations={
"get",
"put"={
"path"="/my/very/important/URL/{id}",
"schemes"={"https"},
}
}
)
And I would now like to make the GET operation available through /my/very/important/URL too, without implementing the GET operation.
I found a workaround for what I actually wanted to do: adding a route prefix at the entity.
* #ApiResource(
* routePrefix="/my/very/important/URL"
* )
But unfortunately I can still not prevent API Platform from using the plural of my entity name as URL.
If I have an entity Publication, than API Platform exposes my API with the URL /my/very/important/URL/publications. I still don't know how to fix that.
According to the API Platform documentation:
"The URL, the method and the default status code (among other options) can be configured per operation. In the next example, both GET and POST operations are registered with custom URLs. Those will override the URLs generated by default. In addition to that, we require the id parameter in the URL of the GET operation to be an integer, and we configure the status code generated after successful POST request to be 301:"
https://api-platform.com/docs/core/operations/#configuring-operations
Here we have the example:
# api/config/api_platform/resources.yaml
App\Entity\Book:
collectionOperations:
post:
path: '/grimoire'
status: 301
itemOperations:
get:
method: 'GET'
path: '/grimoire/{id}'
requirements:
id: '\d+'
defaults:
color: 'brown'
host: '{subdomain}.api-platform.com'
schemes: ['https']
options:
my_option: 'my_option_value'
I hope it helps.

Openstack swift, which url to use in my use case?

I'll be using swift as like S3, where it will host number of files for my site.
I've set my container as public, and so
Here is the URL for a file.
https://provider/v1/auth_1293kdfj/folder/file.mp4
There are two problems:
Is it correct in using above format uri in public setting? It feels kinda dangerous because it has the auth_bit.
If I visit https://provider/v1/auth_1293kdfj/folder/ it lists all files/bojects in container folder. I wish to turn this off, how would I do so? Should I make my container private and assign temp url to ALL objects?
Thanks for your help!
1 - Yes. It's correct. Probably your authentication server is protected behind a firewall. This is just the project id. However if you are really worried about security you can configure your webserver to hide this info.
2 - Probably your container has the following acl:
.r:*,.rlistings
If you set by yourself (what I believe is the most common) you should change it just to:
.r:*

how to set up a multi-domain multi-language in symfony2

I am working on a project that is on expansion and needs to support multi-domain and multi-language.
I find that the way the standard routing is managed does not cover in an efficient way the project needs.
I found this: https://github.com/alexandresalome/multisite-bundle
It's find it good but I see the following drawbacks:
1) The bundle has not really much movement
2) The routing is set up at Controller/annotation level instead of yml file, what makes project hard to maintain.
Do you know any bundle/strategy based on symfony2 for this need? thanks a lot !!!
That doesn't solve the problem.
This is my scenario:
I have a parameter where I set up several hosts: landing_hosts, separated by “|”
I have some landings, that are only valid for those hosts, routing: landings
When a request comes, I can’t see any way to dynamically set the current host for the default => hosts entry.
I am forced to specify one, that is %domain%. This works this way because there is a cached file appDevUrlGenerator.php that is created at first time website is visited or ran the command app/cache cache:clear.
If I visit a landing page as host2, the urls and paths created inside twig templates will follow the hosts1 instead hosts2, and this is not valid.
// parameters.yml
parameters:
landing_hosts: host1|host2
main_host: host1
// routing.yml
landings:
host: "{hosts}"
path: /
defaults: { _controller: FrontendBundle:Landings:index }
requirements:
hosts: %landing_hosts%
defaults:
hosts: %main_host%

Grails - SSL and Spring security core

I would like to have my application running exclusively with SSL turned on.
I am using the Spring Security core plugin.
This is how I attempt to do it in Config.groovy:
grails.plugins.springsecurity.portMapper.httpPort = 8080
grails.plugins.springsecurity.portMapper.httpsPort = 8443
grails.plugins.springsecurity.secureChannel.definition = [ '/**' : 'REQUIRES_SECURE_CHANNEL']
I was expecting this to cause redirects every time I would try to access a Url using HTTP.
However, I am never redirected, and can navigate through both HTTP and HTTPS. I may add I am starting my application using grails run-app -https
Am I getting this all wrong ?
Any suggestion is most welcome.
Do you have a custom filterchain declared in your config?
you might need to add 'channelProcessingFilter' to your chain in that case
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/security-filter-chain.html
You can also try using the forceHttps option
grails.plugins.springsecurity.auth.forceHttps = true
You don't have any wildcards, so the definition is literally matching the root URL (/), but nothing below it (/foo). What you want is:
grails.plugins.springsecurity.secureChannel.definition = [ '/**' : 'REQUIRES_SECURE_CHANNEL']
^^
(You can clearly see the wildcards in the documentation :-)
Finally, if your server is behind a load balancer or other firewall that hides the protocol, check that same page for instructions on checking the header.

Resources