Add request interceptors to specific calls - retrofit

I'm currently trying to figure out which options does retrofit offer to add an interceptor only to specific calls.
Background & use cases
I'm currently using retrofit 1.9
The use case is pretty simple. Imagine a user who needs to login and get a session token. There is a call.
/**
* Call the backend and request a session token
*/
#POST("auht_endpoint")
Observable<Session> login(...);
All other calls will require a token from the above session in the form of a request header. In other words, all subsequent calls will have a header which provides the session token to the backend.
My question
Is there a simple way of adding this header only to specific calls through interceptors?
What I've tried so far
Obviously the easiest approach was to add the #Header annotation to the specific calls and providing the token as a parameter
I guess one can inspect the url in the request inside the interceptor. Not very flexible.
Create different rest adapters with different interceptors. I heard you should avoid creating several instances of the rest adapter for performance reasons.
Additional info
I'm not committed to interceptors, I would use other solutions
I've said I'm using retrofit 1.9, but I'd be also interested in a way to do it with retrofit 2.x

Please note this is not an answer, comment box was too small.
I've recently had this problem and I came up to the same possible solutions as you.
First of all I put aside double adapters - thats a last resort.
#Header field seems ok, bacause you explicitly define that this specific request needs authorization. However it's kinda boring to use.
Url inspection in interceptor looks "ugly", but I've decided to go with that. I mean if all requests from a one specific endpoint need that authorization header then what's the problem?
I had two other ideas:
Somehow dynamically replace/modify okHttpClient which is used with Retrofit. After some tests I figured that it's not possible.
Maybe create some custom annotation #AddAuthorizationHeader to the call definition, which will do everything for you, but I guess it wouldn't be possible either.
And in this matter Retrofit 2.x doesn't bring anything new.

Related

Verify CORS origin in .net 6 when DI is needed

Our service allows the customers to enter their own domain to access the service, after setting the proper DNS records. Their domain/subdomain is pointed to our front end server which makes it more personalized for their users.
Since any customer can change their domain at any time, or even add new ones, we need to make a database call to verify the origin-header.
I've been trying to simply NOT handle cors as usual (app.UseCors() etc.), but instead using filters to resolve the "header-situation". I gave up on this approach because I realized that it just won't work (no endpoint with "OPTIONS" allowed). It also feels dirty, even if it would have worked.
I tried implementing ICorsPolicyProvider creating a custom CORS attribute but this seems to be a dead end since I can't find a way to inject the services I need to verify the origin.
Is there a way to verify the Origin-header while having access to needed services?
The solution is to implement ICorsService. The default implementation (CorsService) is easy to understand and is a good starting point.
In your services configuration, replace the call
services.AddCors();
with:
services.AddTransient<ICorsService, YourImplementationOfICorsService>()
.AddTransient<ICorsPolicyProvider, DefaultCorsPolicyProvider>();
Everything else is the same. The only drawback of this solution is that no scoped dependencies may be injected into your ICorsService implementation.

Adding custom validation logic to dart:io HttpClient

I am trying to create an HttpClient that can validate an SSL certificate after every TLS handshake and before any other data is fetched/sent.
So the flow would look like this:
Create an HttpClient
Execute a request
The client connects to the host via HTTPS
After the TLS handshake was done, the client now knows the certificate
Pass the certificate to a callback. Execute actual request when callback succeeds, abort the request otherwise
In case the callback was successful, proceed as usual (e.g. pass the response etc.)
I was looking into SecurityContext already. The problem is that it only validates against a fixed set of certificates, but I want to validate the certificate dynamically based on the certificate that was sent by the host.
Also, I saw that there is a badCertificateCallback method in HttpClient, but this does not serve my usecase well as I want to validate every certificate, not just the invalid/bad ones.
I was wondering whether I could theoretically create a class that uses HttpClient as a superclass and therefore modify it's behaviour, but I am wondering whether there is a more elegant way that doesn't break that easily when the implementation of HttpClient changes.
Another idea of mine is to set a SecurityContext that rejects every single certificate by default. I could then use the badCerificateCallback to do the checks normally done by SecurityContext (check against a list of trusted certificates) and add my own validation on top of that. Is anyone aware of any drawbacks this might have? I got a little bit uncertain when reading about the limitations regarding iOS.
Has anyone here done similar things before and could give me a hint? :)
Thanks in advance!
For your usecase, it is better that you have your own version of BetterHttpClient.
However, instead of BetterHttpClient inheriting from HttpClient, you can use composition. Compose HttpClient inside BetterHttpClient. This will give you more control over what you want to use/update from the existing implementation and also this will be better guarded against any changes that HttpClient will go through

How to access dependency injection container in Symfony 4 without actual injection?

I've got a project written in Symfony 4 (can update to the latest version if needed). In it I have a situation similar to this:
There is a controller which sends requests to an external system. It goes through records in the DB and sends a request for every row. To do that there is an MagicApiConnector class which connects to the external system, and for every request there is a XxxRequest class (like FooRequest, BarRequest, etc).
So, something like this general:
foreach ( $allRows as $row ) {
$request = new FooRequest($row['a'], $row['b']);
$connector->send($request);
}
Now in order to do all the parameter filling magic, the requests need to access a service which is defined in Symfony's DI. The controller itself neither knows nor cares about this service, but the requests need it.
How can my request classes access this service? I don't want to set it as a dependency of the controller - I could, but it kinda seems awkward, as the controller really doesn't care about it and would only pass it through. It's an implementation detail of the request, and I feel like it shouldn't burden the users of the request with this boilerplate requirement.
Then again, sometimes you need to make a sacrifice in the name of the greater good, so perhaps this is one of those cases? It feels like I'm "going against the grain" and haven't grasped some ideological concept.
Added: OK, the full gory details, no simplification.
This all is happening in the context of two homebrew systems. Let's call them OldApp and NewApp. Both are APIs and NewApp is calling into the OldApp. The APIs are simple REST/JSON style. OldApp is not built on Symfony (mostly even doesn't use a framework), the NewApp is. My question is about NewApp.
The authentication for OldApp APIs comes in three different flavors and might get more in the future if needed (it's not yet dead!) Different API calls use different authentication methods; sometimes even the same API call can be used with different methods (depending on who is calling it). All these authentication methods are also homebrew. One uses POST fields, another uses custom HTTP headers, don't remember about the third.
Now, NewApp is being called by an Android app which is distributed to many users. Android app actually uses both NewApp and OldApp. When it calls NewApp it passes along extra HTTP headers with authentication data for OldApp (method 1). Thus NewApp can impersonate the Android app user for OldApp. In addition, NewApp also needs to use a special command of OldApp that users themselves cannot call (a question of privilege). Therefore it uses a different authentication mechanism (method 2) for that command. The parameters for that command are stored in local configuration (environment variables).
Before me, a colleague had created the scheme of a APIConnector and APICommand where you get the connector as a dependency and create command instances as needed. The connector actually performs the HTTP request; the commands tell it what POST fields and what headers to send. I wish to keep this scheme.
But now how do the different authentication mechanisms fit into this? Each command should be able to pass what it needs to the connector; and the mechanisms should be reusable for multiple commands. But one needs access to the incoming request, the other needs access to configuration parameters. And neither is instantiated through DI. How to do this elegantly?
This sounds like a job for factories.
function action(MyRequestFactory $requestFactory)
{
foreach ( $allRows as $row ) {
$request = $requestFactory->createFoo($row['a'], $row['b']);
$connector->send($request);
}
The factory itself as a service and injected into the controller as part of the normal Symfony design. Whatever additional services that are needed will be injected into the factory. The factory in turn can provide whatever services the individual requests might happen to need as it creates the request.

When and how to use POST, PUT, and Delete method in Web API

I am new to Web API and the tutorial I was watching uses Fiddler to sniff and send request.
My question is how to use the post, put and delete methods without using fiddler and where are these usually used in the when creating in software development? Fiddler allows you to compose a request body how about the browser though?
I don't seem to understand why you are only able to use these on a sniffing tool. I understand that I am most probably speaking out of ignorance.
(This answer is not specific to ASP.NET)
To avoid any confusion, I'm assuming you understand this much about RESTful webservices:
If you are creating a new entity, use POST.
If you are reading an entity, use GET.
If you are updating an entity, use PUT.
If you are deleting an entity, use DELETE.
As you noticed, only the GET and POST methods can be used in plain web forms. AJAX, however, supports using any HTTP method. Therefore, to use the PUT and DELETE methods, send your data to the server using JavaScript methods such as XMLHttpRequest, the newer Fetch API or a convenient wrapper like jQuery's $.ajax. (There are many tutorials for whichever you pick.) For example, if you have a form of updated values, replace your input button with a button element that has a JavaScript click event handler. The same principle applies to a delete link, swap the href for a click event handler that makes an AJAX request to your server.
If you simply want to create requests using some tool, then you can use tools like Fiddler, Postman, curl, etc. - as you have stated, Fiddler can also be used to monitor as well as create requests.
If you want to go beyond that,
you have HttpClient, WebClient to build requests on your own, and for testing.
If you want to get "full control" then look into HttpWebRequest.
VS debugging tools will allow you to inspect the full flow - from request to response - using things like breakpoints, watch, etc.
See previous/other answers if you want to build/create requests client-side (Javascript / XMLHttpRequest)
Hth.

Is it correct aspnetcore way? Service & Dependency Injection

so i want to create some service that accesses external API, and i want to cache common requests from the API inside of that service, it depends on 3 other services, but i want to give it its own instance of cache, MemoryDistributedCache might later be changed for something else
services.AddSingleton<ISomeApi, SomeApi>(provider => new SomeApi(
Configuration.Get<Options>(),
new MemoryDistributedCache(new MemoryCache(new MemoryCacheOptions())),
provider.GetService<ILogger<SomeApi>>()
));
now from my Controllers i can access the api via DI, it works nicely but im not sure if its some sort of an anti-pattern or if there are better ways of doing it
i mean the real problem is separating the internal cache, requesting
IDistributedMemory from one service would give me the same object as if i request it from another service, they must be separated
This sounds like something you could use a proxy or decorator pattern for. The basic problem is that you have a service that does some data access, and another service responsible for caching the results of the first service. I realize you're not using a repository per se, but nonetheless the CachedRepository pattern should work for your needs. See here:
http://ardalis.com/introducing-the-cachedrepository-pattern
and
http://ardalis.com/building-a-cachedrepository-via-strategy-pattern
You can write your cached implementation such that it takes in the actual SomeApi type in its constructor if you don't need that part of the design to be flexible.

Resources