I'm developing an ASP.Net Core web application where I need to create a kind of "authentication proxy" to another (external) web service.
What I mean by authentication proxy is that I will receive requests through a specific path of my web app and will have to check the headers of those requests for an authentication token that I'll have issued earlier, and then redirect all the requests with the same request string / content to an external web API which my app will authenticate with through HTTP Basic auth.
Here's the whole process in pseudo-code
/extapi
and adds the auth-token in the HTTP headerHere's what I have for now. It seems to be working fine, but I'm wondering if it's really the way this should be done or if there isn't a more elegant or better solution to this? Could that solution create issues in the long run for scaling the application?
[HttpGet] public async Task GetStatement() { //TODO check for token presence and reject if issue var queryString = Request.QueryString; var response = await _httpClient.GetAsync(queryString.Value); var content = await response.Content.ReadAsStringAsync(); Response.StatusCode = (int)response.StatusCode; Response.ContentType = response.Content.Headers.ContentType.ToString(); Response.ContentLength = response.Content.Headers.ContentLength; await Response.WriteAsync(content); } [HttpPost] public async Task PostStatement() { using (var streamContent = new StreamContent(Request.Body)) { //TODO check for token presence and reject if issue var response = await _httpClient.PostAsync(string.Empty, streamContent); var content = await response.Content.ReadAsStringAsync(); Response.StatusCode = (int)response.StatusCode; Response.ContentType = response.Content.Headers.ContentType?.ToString(); Response.ContentLength = response.Content.Headers.ContentLength; await Response.WriteAsync(content); } }
_httpClient
being a HttpClient
class instantiated somewhere else and being a singleton and with a BaseAddress
of http://someexternalapp.com/api/
Also, is there a simpler approach for the token creation / token check than doing it manually?
A reverse proxy is a special type of proxy server that hides the target server to the client. The client requests a resource to the proxy server which retrieves it from another server and provides it to the client. In this case, the client has no idea that the resource comes from another server.
ForwardedHeaders. Identifies which forwarders should be processed. See the ForwardedHeaders Enum for the list of fields that apply. Typical values assigned to this property are ForwardedHeaders.
A proxy server handles client requests for resources. A proxy can return a requested resource from its cache or forward the request to the server where the resource resides. Proxies can improve network performance by reducing the number of requests sent to remote servers.
If anyone is interested, I took the Microsoft.AspNetCore.Proxy code and made it a little better with middleware.
Check it out here: https://github.com/twitchax/AspNetCore.Proxy. NuGet here: https://www.nuget.org/packages/AspNetCore.Proxy/. Microsoft archived the other one mentioned in this post, and I plan on responding to any issues on this project.
Basically, it makes reverse proxying another web server a lot easier by allowing you to use attributes on methods that take a route with args and compute the proxied address.
[ProxyRoute("api/searchgoogle/{query}")] public static Task<string> SearchGoogleProxy(string query) { // Get the proxied address. return Task.FromResult($"https://www.google.com/search?q={query}"); }
I ended up implementing a proxy middleware inspired by a project in Asp.Net's GitHub.
It basically implements a middleware that reads the request received, creates a copy from it and sends it back to a configured service, reads the response from the service and sends it back to the caller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With