0

Context

I am currently working on a .net Core 3.1 API that has an authentication method that checks if a HTTP request is send from a specific IP addresses. The requesters IP Address should match with ones that are stored in the database or localhost otherwise the client is denied.

Code

I Have the following code:

Controller

 public async Task<IActionResult> AuthenticatePlanbord([FromBody] AuthPlanbordRequest request)
        {
            if (request.AuthType == AuthType.Planbord)
            {
                // Validate the IP address of the client to check if the request is made from the server of the planbord.
                var ip = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
                var AuthResponse = await _authService.AuthenticatePlanbordAsync(ip, request.DatabaseName, request.UserId);
                if (AuthResponse == null) return Unauthorized(new ServerResponse(false, "Unauthorized", HttpStatusCode.Unauthorized));
                return Ok(new ServerResponse(TokenGenerator.GenerateJsonWebToken(AuthResponse)));
            }
            return BadRequest(new ServerResponse(false, _localizer["AuthTypeNotSupported"], HttpStatusCode.BadRequest));
        }

Authentication service

public async Task<AuthEntityPlanbord> AuthenticatePlanbordAsync(string ip, string databaseName, Guid userId = default)
        {
            _unitOfWork.Init();
            // Check if the request does not originate from localhost
            if (ip != "::1")
            {
                var Ip = await _unitOfWork.Connection.ExecuteScalarAsync<string>("SELECT IpAdres FROM PlanbordAutorisaties WITH(NOLOCK) WHERE IpAdres = @Ip ", new { Ip = ip }, _unitOfWork.Transaction);
                if (string.IsNullOrEmpty(Ip)) return null;
            }
            var userData = await _unitOfWork.AuthRepository.AuthenticatePlanbordAsync(userId);
            userData.IPAdress = ip;
            userData.DatabaseName = databaseName;
            return userData;
        }

Problem & Question

To fully test if the logic works I would like to write a integration test that sends a HTTP request from a different IP address than localhost. Would this be possible in .net Core? Or Should I just rely on Unit tests only?

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 1
    It would be possible with a proxy server in any programming language that supports web requests with proxy servers. I'm not sure it would be advantageous to integration test it with an actual request though. – ProgrammingLlama Oct 08 '20 at 09:00
  • Thanks for the quick reply @John I will look into proxy servers then. But I think sending actual HTTP requests will be advantageous for testing. – Joep Verhoeven Oct 08 '20 at 09:08

2 Answers2

2

The easy way (which works in any language), is to use a service like reqbin or similar to simulate a request. Being an online service it will have a different IP.

You can find other similar services doing that. This one in particular has also an API examples available. So if you want to integrate it to your unit tests or someting like that, you will just have to simulate a POST request to their api, with the parameters pointing to your endpoint so you can simulate an external request from an IP not whitelisted.

Liquid Core
  • 1
  • 6
  • 27
  • 52
  • Thanks for the quick reply @Liquid Core. But I am afraid this solution would not work in my situation as I want to run my integration tests on a locally hosted build of the API and [reqbin](https://reqbin.com/) would not be able to reach my Endpoint. But this solution would have worked in a CI/CD build server or an IIS testing service. But the company I work for doesn't posses those. – Joep Verhoeven Oct 08 '20 at 09:15
  • @JoepVerhoeven maybe this? https://stackoverflow.com/questions/39689858/how-to-use-httpclient-to-send-a-request-from-a-specific-ip-address-c-sharp – Liquid Core Oct 08 '20 at 09:31
  • I will look into it. Thanks for the suggestion! – Joep Verhoeven Oct 08 '20 at 09:36
  • @JoepVerhoeven Ok if it solves mark the answer else get back here and I will try find more – Liquid Core Oct 08 '20 at 10:00
  • well your solution is indeed a good one, it still does not answer the question; if it is possible to send a HTTP request from a .net Core application with a different sender IP Address? But I do really appreciate the help. – Joep Verhoeven Oct 08 '20 at 10:07
0

Yes, if this is an API call you can create a request using HTTP client.

You can set HTTP client to use a proxy in the handler.

var httpclienthandler = new HttpClientHandler
            {
                // Set creds in here too if your proxy needs auth
                Proxy = new WebProxy("proxyIp")
            };
var httpClient = new HttpClient(httpclienthandler);

If this is a website action, you can set your browser to use a proxy, or simply connect to a VPN?

Dave Morrison
  • 190
  • 2
  • 13