locked
.net core message showing when run in debug on local pc but not on server RRS feed

  • Question

  • User915516305 posted

    Hi,

    using .netcore 2.1 had code below working in 2.2 a few months work back

    have variable badIp

    How can we get message returned to screen when badIp = true

    when have badIp = false then shows data entry as expected

    Below still works on local pc but doesn't show when publish on server no message returned to screen when use chrome.

     badIp = true;
    
                if (badIp) 
                {
                     _logger.LogInformation(
                     " Please contact IT  to add your ip address to list of valid ip addresses. Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(200);
                    string valueString = "Only whitelisted I.P. Addresses may access this application." +
                                            "\r\n" +
                                             "\r\n" +
                                        "Please contact IT team to determine if your IP address can be added for access";
                    context.HttpContext.Response.WriteAsync(valueString);
                    return;
    
                }
    Thursday, February 20, 2020 2:15 PM

Answers

All replies

  • User915516305 posted

    Hi,

    for info this is a razor pages crud and used 

    https://docs.microsoft.com/en-us/aspnet/core/security/ip-safelist?view=aspnetcore-2.1

     looking to display user-friendly message on browser if user attempts with an ip address which not on safelist.

    Thanks

    Thursday, February 20, 2020 3:12 PM
  • User475983607 posted

    Unfortunately, you are showing a snippet if code with no context.  I assume the code returns and continues to process.  Normally, this type of validation is handled in middleware which short circuits the request. 

    Thursday, February 20, 2020 3:13 PM
  • User915516305 posted

    Hi,

    Thanks for reply.

    Used code below from the microsoft website.

    if an ip address which not on safelist code stops as expected but would like a user frindly message to show in the browser.

    Also with regards the logger - assume this writes message to a file - where is the file located?  

     if (badIp)
                {
                    _logger.LogInformation(
                        "Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(401);
                    return;
                }

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Linq;
    using System.Net;
    
    namespace ClientIpAspNetCore
    {
        public class ClientIpCheckPageFilter : IPageFilter
        {
            private readonly ILogger _logger;
            private readonly string _safelist;
    
            public ClientIpCheckPageFilter
                (ILoggerFactory loggerFactory, IConfiguration configuration)
            {
                _logger = loggerFactory.CreateLogger("ClientIdCheckPageFilter");
                _safelist = configuration["AdminSafeList"];
            }
    
            public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
            {
                var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
                _logger.LogInformation(
                    "Remote IpAddress: {RemoteIp}", remoteIp);
    
                string[] ip = _safelist.Split(';');
    
                var badIp = true;
                foreach (var address in ip)
                {
                    if (remoteIp.IsIPv4MappedToIPv6)
                    {
                        remoteIp = remoteIp.MapToIPv4();
                    }
                    var testIp = IPAddress.Parse(address);
                    if (testIp.Equals(remoteIp))
                    {
                        badIp = false;
                        break;
                    }
                }
    
                if (badIp)
                {
                    _logger.LogInformation(
                        "Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(401);
                    return;
                }
            }
    
            public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
            {
            }
    
            public void OnPageHandlerSelected(PageHandlerSelectedContext context)
            {
            }
        }
    }
    This filter is enabled by adding it to the MVC Filters collection.
    
    C#
    
    Copy
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<ClientIpCheckFilter>();
    
        services.AddMvc(options =>
        {
            options.Filters.Add
                (new ClientIpCheckPageFilter
                    (_loggerFactory, Configuration));
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    Thursday, February 20, 2020 3:25 PM
  • User475983607 posted

    Are you saying the Microsoft filter is not working as expected?  Or your version is not working?

    Thursday, February 20, 2020 3:46 PM
  • User915516305 posted

    Hi,

    My version

    It looks to trap the bapdip (i.e. ips which not on safelist and correctly prevents the CRU entry screen being shown.

    However,  I'm wanting a meaningful message to displayed to user and had hoped to use

       context.HttpContext.Response.WriteAsync(valueString); to show this in browser.  However, doesn't appear to show this.

    Also where are logs created by default in .net core razor CRUd apps e.g. logging presumably to some file below but which directory could we find these in when running on server?

    if (badIp)
                {
                     _logger.LogInformation(
                        " Please contact IT  to add you ip address to list of valid ip addresses. Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(200);
                    string valueString = "Please contact IT to determine if your IP address can be added for access";
                    context.HttpContext.Response.WriteAsync(valueString);
                    return;
    
     
                }

    Any thoughts on how we can show message in browser when bad ip address?

    Shows message on browser when run on local pc but just not when published to web server

    Thursday, February 20, 2020 3:52 PM
  • User753101303 posted

    Hi,

    What if you  try

    await context.HttpContext.Response.WriteAsync(valueString);

    You don't have a warning message in the Visual Studio task list ?

    Friday, February 21, 2020 8:56 AM
  • User915516305 posted

    Hi,

    Thanks for reply.

    When I put await in get compilation error message when try build in visual studio code. 


    Filters\ClientIdCheckPageFilter.cs(73,17): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. [D:\RazorPage2.1\RazorPageProj2.csproj]

    Without the await word, code  compiles and runs o.k. on own pc and shows message in browser.

    It doesn't show message when run deployed code on web server

    What does await keyword do - assume awaits reponse and how can we resolve?

    Filters\ClientIdCheckPageFilter.cs(73,17): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. [D:\RazorPage2.1\RazorPageProj2.csproj]

    When run in visual studio code in debug session on my pc 

    info: ClientIdCheckPageFilter[0]
    Remote IpAddress: ::1
    info: ClientIdCheckPageFilter[0]
    Please contact IT to add your ip address to list of valid ip addresses. Forbidden Request from Remote IP address: ::1
    info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
    Executing HttpStatusCodeResult, setting HTTP status code 200
    info: Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker[2]
    Executed action /MULTIPLES/Index in 156.7542ms
    fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
    An unhandled exception has occurred while executing the request.
    System.InvalidOperationException: StatusCode cannot be set because the response has already started.

    Thanks

    Friday, February 21, 2020 9:34 AM
  • User753101303 posted

    Ah missed the later message. You should have full support for async methods so that you could use public async Task OnPageHandlerExecutionAsync as shown at https://www.learnrazorpages.com/razor-pages/filters

    The async method returns immediately a task and so you the response may not be written yet when going to the next statement.

    Not directly related but this kind of things could be likely best handled that the web server using for example maybe https://docs.microsoft.com/en-us/iis/configuration/system.webserver/security/ipsecurity/

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, February 21, 2020 10:40 AM
  • User915516305 posted

    Thanks for update and links.

    Appreciate link on ipsecurity but looking for a user-friendly message if user attempts to access without a whitelisted ip address.

    Tried the asynch but even with valid ip. address whilst compiles doesn't run in visual studio code or when published.

    This just a small CRUD - will the aysynch just run it in background?

    Tried aysnch code below.

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Linq;
    using System.Net;
    using Microsoft.AspNetCore.Http;
    using System.Threading.Tasks;
    
    namespace Razorproj2.ClientIpAspNetCore
    {
        public class ClientIdCheckPageFilter : IAsyncPageFilter
        {
            private const string V = "Only whitelisted I.P. Addresses may access this application." +
                                                    "\r\n" +
                                                     "\r\n";
            private readonly ILogger _logger;
            private readonly string _safelist;
    
            public ClientIdCheckPageFilter
                (ILoggerFactory loggerFactory, IConfiguration configuration)
            {
                _logger = loggerFactory.CreateLogger("ClientIdCheckPageFilter");
                _safelist = configuration["AdminSafeList"];
            }
    
             //public void OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
             public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
            {
                var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
                _logger.LogInformation(
                    "Remote IpAddress: {RemoteIp}", remoteIp);
    
                string[] ip = _safelist.Split(';');
    
                var bytes = remoteIp.GetAddressBytes();
                var badIp = true;
                foreach (var address in ip)
                {
                    var testIp = IPAddress.Parse(address);
                    if (testIp.GetAddressBytes().SequenceEqual(bytes))
                    {
                        badIp = false;
                        break;
                    }
                }
    
                //badIp = false;
    
                if (badIp) 
                {
                     _logger.LogInformation(
                     " Please contact IT  to add your ip address to list of valid ip addresses. Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(200);
                    string valueString = "Only whitelisted I.P. Addresses may access this application." +
                                            "\r\n" +
                                             "\r\n" +
                                        "Please contact IT team to determine if your IP address can be added for access";
                    await context.HttpContext.Response.WriteAsync(valueString);
                    return;
    
                }
            }
    
          
    
            public async Task OnPageHandlerSelectionAsync(
                                                PageHandlerSelectedContext context)
            {
                _logger.LogDebug("Global OnPageHandlerSelectionAsync called.");
                await Task.CompletedTask;
            }
        }
    }

    Is there no way we can just use non-asynch code and get it to display user-friendly message?

    At least the non synch code is working but just not showing us message when attempt to access with invalid ip. address.

     if (badIp) 
                {
                     _logger.LogInformation(
                     " Please contact IT  to add your ip address to list of valid ip addresses. Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(200);
                    string valueString = "Only whitelisted I.P. Addresses may access this application." +
                                            "\r\n" +
                                             "\r\n" +
                                        "Please contact IT team to determine if your IP address can be added for access";
                    await context.HttpContext.Response.WriteAsync(valueString);
                    return;
    
                }

    Monday, February 24, 2020 12:23 PM
  • User915516305 posted

    Hi,

    Thanks for your suggestion re the option to use ip whitelisting via https://docs.microsoft.com/en-us/iis/configuration/system.webserver/security/ipsecurity/

    Have decided to use this as mean can simply add new entries via web server without changing the appsettings.json file directly.

    Out of interest is it possible to adapt below at all without using asynch so that could have used message via browser.

    Don't understand why below doesn't work when deployed but works on visual studio code running in debug mode.

    if (badIp) 
                {
                     _logger.LogInformation(
                     " Please contact IT  to add your ip address to list of valid ip addresses. Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
                    context.Result = new StatusCodeResult(200);
                    string valueString = "Only whitelisted I.P. Addresses may access this application." +
                                            "\r\n" +
                                             "\r\n" +
                                        "Please contact IT team to determine if your IP address can be added for access";
                     context.HttpContext.Response.WriteAsync(valueString);
                    return;
    
                }
    Monday, February 24, 2020 2:47 PM