Micrometer metrics for Spring WebClient's OAuth2 flows - spring

I'm using Spring's WebClient in a non-reactive application to make requests to a third-party service that uses OAuth2 client credentials for its security.
I would like to have http.client.requests related metrics for the OAuth2 requests that are made, however (as best I can tell) this isn't happening because DefaultClientCredentialsTokenResponseClient creates its own instance of RestTemplate using the constructor, instead of leveraging an injected RestTemplateBuilder, which would handle the instrumentation automatically.
Is there a way to have these metrics surfaced by Micrometer?

Related

Filter Chains support in Spring Cloud Function

Does Spring Cloud Function provide some kind of functionality similar to Spring Security Filter Chains ?
One particular use case is to implement CORS with AWS Lambda API Gateway in proxy integration mode. According to the AWS docs, it's function responsibility to add CORS headers to the response.
It might be more useful to do this at the integration layer and not in the business logic.
I'm using Spring Cloud Function with AWS adapter and Spring Boot.
I've browsed through the code (3.1.3 at the time of writing) but didn't find something alike.
There's one old issue showing CorsFilter registration (with Azure provider) but I doubt it really worked as Spring Cloud Function does not utilize Servlet environment.

Bypass spring security for service-to-service calls

I have multiple Spring boot micro-services deployed to kubernetes. Im also using Spring Gateway & Eureka Discovery.
Those micro-services are secured with Spring Security and require JWT token for access to the endpoints. Im using #PreAuthorize methods etc.
It all works fine when I'm accessing those endpoints from frontend application that is sending JWT token in request,
but, I can't bypass that security in service-to-service communication via FeignClient.
Ideally, my micro-services wouldn't need token at all to call other micro-service's methods via FeignClient. But I still need that security when endpoints are accessed from frontend or when requests are coming from Spring Api Gateway.
Do you know some elegant solution to this problem?
I was thinking about adding another pair of endpoints that don't have security annotations (#PreAuthorize) and somehow disable access to those endpoints on Spring Api Gateway, so they cannot be accessed from outside, but only directlly by one of the micro-services.

Is it possible to disable Spring Cloud Sleuth header propagation based on destination URL?

We're using Brave's ExtraFieldPropagation feature to propagate custom fields (e.g. an internal-only request identifier) between services as HTTP headers.
Some of our services make requests to external services using a RestTemplate or Feign client in the course of processing a request. Since Sleuth enhances all RestTemplate beans and Feign clients with the propagation feature, this means that external services receive the internal-only headers, which I'd like to avoid.
I know of two workarounds that allow me to avoid this behavior, both of which are flawed:
Instantiate a client object manually as opposed to using a #Bean so that Sleuth does not add an interceptor. The downside I see here is that developers have to remember to follow this pattern to avoid leaking information, and this is difficult to enforce.
Add an interceptor that removes these headers from outgoing requests. The downsides here are that a) I need separate interceptors for RestTemplate and Feign clients (not a huge deal); b) it looks like Feign client interceptors do not have a way to influence order of execution (see javadoc here), so I can't guarantee that the new interceptor will run last / after the Sleuth one.
Is there a way to customize Sleuth (e.g. via some kind of injector bean) such that, prior to injecting headers in an outgoing HTTP request, I can reason about the destination of the request? I saw documentation regarding custom injector beans, but it appears those no longer exist in spring boot >= 2. I can't seem to find an equivalent construct in Brave.
You can unsample a given URL which means that the headers will be propagated but not sent to Zipkin. You can't disable instrumentation for only some of the URLs cause we're instrumenting all of the components that are registered as beans.

Camel Rest api consumer using SpringOAuthResttemplate

I have to invoke a couple of rest web service from my spring boot application. I am planning to use the Camel to configure the flow and other EIP use cases. Some of the endpoints are using oAuth2 authentication. I am planning to use the Spring oAuthResttempalte. All the examples on the internet are either using restlet, CXF or camel-http.
Camel Rest Consmer
I am not able to find a single example with just spring resttemplate. Did anyone implement Camel Rest consumer using Spring Resttemplate?
Some of the Examples on the internet use a jetty server to consume a rest endpoint. Why do you need a jetty server for simple rest consumer?
Did anyone implement Camel Rest consumer using Spring Resttemplate?
I'm not aware of that and it's unlikely to found something in that direction because Camel already have bult-in components to consume rest endpoints.
Some of the Examples on the internet use a jetty server to consume a rest endpoint. Why do you need a jetty server for simple rest consumer?
I believe that jetty was used as a consumer not a producer endpoint. So you won't need the "server". Or maybe you saw an example using jetty acting as a server to serve an OAuth endpoint?
If you excuse my approach, I'd suggest to remain with Camel HTTP/Rest capabilities to consume REST APIs using OAuth. I've found this example on Gist:
from("direct:authService").tracing()
.setHeader(Exchange.HTTP_PATH)
.simple("<auth service context>/oauth2/token")
.setHeader("CamelHttpMethod")
.simple("POST")
.setHeader("Content-Type")
.simple("application/x-www-form-urlencoded")
.setHeader("Accept")
.simple("application/json")
.setBody()
.constant("grant_type=client_credentials&client_id=<client id>&client_secret=<client sec>")
.to("https4://<remote auth service url>")
.convertBodyTo(String.class)
.log("response from API: " + body())
.choice()
.when().simple("${header.CamelHttpResponseCode} == 200")
.unmarshal().json(JsonLibrary.Jackson, AccessResponseToken.class)
.setHeader("jwt").simple("${body.access_token}")
.to("direct:<some direct route>")
.otherwise()
.log("Not Authenticated!!!");
If you want to stick into OAuthRestTemplate you may implement a Processor or a bean to wrap those calls and return to your route the authorization token.

Spring Boot / Spring Cloud / Spring Security: How to correctly obtain an OAuth2 Access Token in a scheduled task

I have a background task (method with #Scheduled annotation) which calls a resource server using ribbon/feign.
The background task is running on the authorization server.
The resource server requires calls to be authenticated (and to present a certain set of authorities)
So what would be the correct way of obtaining an access token for the calls made by the scheduled task?
My current solution is to manually generate an access token in a custom feign RequestInterceptor and then set the Authorization Header for each request performed by feign.
I tried my luck using the #EnableOAuth2Client annotation and was hoping to build an OAuth2ClientContext from there which I could just inject into the feign interceptor (or have that work entirely taken care of by the OAuth2FeignRequestInterceptor from the spring-cloud-security jar) but from what I've gathered by looking at the tutorial for the clientContext to be built one has to register a web filter in the security chain. That obviously won't work for my situation where there isn't really any web request being processed as my call using feign originates from a scheduled task..
Unfortunately this topic is not covered by any of the (otherwise commendable) spring docs / examples - as far as I have seen - so I was hoping to find the answer here on SO =)
Regards

Resources