SpringCloud Gateway redirect based on URL and Method - spring-boot

Springboot : 2.0.4.RELEASE
I am using Swagger documentation to create RouteDefincationLocator to redirect my incoming request to appropriate service in Spring.
Now there are some services who has same URL with different http method name. i.e
POST /v1/orders (This is more restricted then other url)
GET /v1/orders?view=single
Now in Spring cloud gateway I want to apply 2 different set of filter on each URL
i.e.
For : POST /v1/orders
Filters
ValidUser
Has Create Permission
For : GET /v1/orders?view=single
Filters
ValidUser
I have implemented RouteDefinitionLocator, and implemented method
public Flux<RouteDefinition> getRouteDefinitions()
I have also set predicates PredicateDefinition but this is only verifying URL Path and not method
There are lots of consumer of these services, so I can not change the URL
Can someone tell me how can I add different filters based on incomming URL+Method
Thanks in advance.

Related

Regexmatcher / Antmatcher for url with request param

In Spring, you can configure endpoints to be accessible without the need for authentication.
You can do this via WebIgnoring method or via the configure method and using permitAll(). The problem is for my registration form I have following request url:
http://localhost:9090/users?username=
the username is limited to the regex "^[^-\\s][\\w]{1,19}$". Does anyone know how to make that url anonymous for Spring using an antMatcher or a regexMatcher?

Does Spring Boot Support Multiple Content Negotiation Strategies Base On URL Pattern

Our Spring Boot webapp consists of a couple of URL strategies. The /api URL's are for REST services and content negotiation is consistent with best practices (headers or request parameters). The /web URLS are for a legacy Freemarker application which uses URL extensions for mapping content type (.html, .json, etc). A recent change by Spring has caused the problem (https://github.com/spring-projects/spring-framework/issues/24179).
The content negotiation for the two URL's are different and I was wondering if we could define multiple content negotiation strategies...using URL's to select between them.
Yes, content negotiation is possible in the Spring Boot application as you can use Request parameter or header values to return different content-type based on your requirement for example. You can use the same URL pattern and use content-type request parameter to get the desired type and return the content like .html or.json but make sure you are adding marking as #RequestMapping(value = "sign_in", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_HTML_VALUE})

How to make relative redirect to Authorization Endpoint in Spring OAuth?

I configured a service with oauth2Login.
User is redirected to Authorization Endpoint - /oauth2/authorization/{registrationId} when he/she is not authorized.
I would like to customize redirection in a way that it takes into account path prefix, since application is accessible trough prefix /api/myapp/.
From the source code I can see that there is OAuth2AuthorizationRequestRedirectWebFilter during Spring Security setup and this filter is using DefaultServerRedirectStrategy which decides if location is relative or not. Moreover it uses a contextPath which is hard to set when using Spring Boot.
Unfortunately I don't know how to override default behavior to make redirect relative.
I don't need to modify contextPath. Instead I've registered ForwardedHeaderTransformer as a bean.
This transformer is able to retrieve headers set by proxy (X-Forwarded-Prefix) and sets context path for request correctly.

Using Apache Shiro SecurityUtils in a Filter

I'm using a Filter in a Spring Boot web application to log all my user requests to a database. One of the things I'd like to log is the username, but when I try to get the current user using:
SecurityUtils.getSubject().getPrincipal()
I get the following error:
No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
What do I need to do so that my Filter is able to retrieve the current user?
You need to have at least one url defined for your filter mapping:
https://github.com/apache/shiro/blob/1.4.x/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/WebApp.java#L96-L101
And of course the Shiro servlet filter configured (which I'm guessing you already have)
Take a look at the above example.

Securing and permitting access to spring rest controller with ant matcher and method level security side-by-side?

First of all my application is build with spring boot and security.
So I have several rest controllers (resources). One controller provides multiple methods to get/post different kind of data. But I have cases where some methods should be public and others needs authentication.
For example:
GET /api/object/method1 <-- Needs authentication
GET /api/object/method2 <-- Public
POST /api/object/method3 <-- Needs authentication
POST /api/object/method4 <-- Public
What is best practice to secure this resource? I can't secure url with antMatcher with following pattern /api/object/**. Because then the public methods would be secured as well. Also I can't secure by request type (GET, POST).
One option I thought about was using only method level security (eg #Secured etc). This would mean that I need to annotate a lot of methods.
Another thought that comes to mind is dividing resource to 2 parts.
For example creating
ObjectResource.java
ObjectResourcePublic.java
One controller base URL would be /api/public/ and second simply /api/
Then I could use antMatcher for these URLS.
Is my only option to secure every path separtely or every method separetly?
What other options do I have to do this kind of partial securing one resource?
You may use below methods apart from above mentioned methods.
1. Write Interceptor/filter
2. Use Aspect and define advise

Resources