Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audit info parameters - WebAPI #467

Closed
babinecm opened this issue Apr 30, 2015 · 14 comments
Closed

Audit info parameters - WebAPI #467

babinecm opened this issue Apr 30, 2015 · 14 comments
Labels
Milestone

Comments

@babinecm
Copy link

Hi,
I have custom WebAPI on the remote server. On every request there is a warning in the log file.

WARN|Abp.Auditing.WebAuditInfoProvider|System.Net.Sockets.SocketException (0x80004005): No such host is known at System.Net.Dns.GetAddrInfo(String name) at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6) at System.Net.Dns.GetHostAddresses(String hostNameOrAddress) at Abp.Auditing.WebAuditInfoProvider.GetClientIpAddress(HttpContext httpContext) at Abp.Auditing.WebAuditInfoProvider.Fill(AuditInfo auditInfo)

What's the problem?

@hikalkan
Copy link
Member

That means we can not get IP address of the client. I don't know the exact reason for you situation. This is a warning, system works without logging IP address of the user. You may disable this log in log4net.config if you want. But it's better to find the reason why GetHostAddresses can not get IP address of the client. Do you have an idea? Maybe it's related to your server or client configurations.

@babinecm
Copy link
Author

Server is located on Microsoft Azure. Maybe there is some restriction. On localhost, there is no problem.
I'll try to test on another server (not Azure) and I'll give a feedback.

@babinecm
Copy link
Author

babinecm commented May 4, 2015

I've tested this on another server and everything worked fine. I suppose there is some issue on Microsoft Azure. So, I'm closing this issue.

@babinecm babinecm closed this as completed May 4, 2015
@automys
Copy link

automys commented Apr 13, 2016

Would ask that this be reopened, since it is remains a problem when running on Azure. The calls to Dns.GetHostAddresses will throw SocketException when resolution fails or is unavailable, which causes this exception to fill logs with noise. I don't see why the resolution can't be wrapped in a try block to save the logs from these warnings, or at least provide a configuration to disable warnings if resolution fails?

If not, how can this behavior be overridden effectively?

@hikalkan hikalkan added this to the ABP v0.8.5 milestone Apr 13, 2016
@hikalkan hikalkan reopened this Apr 13, 2016
@hikalkan
Copy link
Member

OK, we will catch the exception.

@automys
Copy link

automys commented Apr 13, 2016

Thanks! I'm not sure whether this call has an associated timeout that might be in play, but would want to also make sure this is done in a non-blocking/async way. Do audited web service calls have to wait for the audit code to finish or is that asychronous?

@hikalkan
Copy link
Member

As I remember, auditing was sync. I will check it while implementing this. Thanks.

@PAA81
Copy link

PAA81 commented Apr 15, 2016

I got the same problem on Azure. After a remote debugging session i can see that
httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] --> 13.48.149.50:1112
httpContext.Request.ServerVariables["REMOTE_ADDR"] --> 13.48.149.50
httpContext.Request.UserHostAddress; --> 13.48.149.50

So maybe the solution is to take the httpContext.Request.UserHostAddress value by default ?
i don't understand the need of use Dns.GetHostAddresses because it seems that we can take the ip address simply before ?

Thanks

@tamys
Copy link

tamys commented Apr 27, 2016

I got the same issue on Azure too. All my audited services in AuditLogs table have nulls ClientIpAddress and ClientName. Is there any chance of setting as fallback ClientIpAddress the HttpContext.Request.UserHostAddress or maybe, as it is a string, something like "PossibleIP:214.55.0.2" to indicate that might be a proxy ip.

@hikalkan
Copy link
Member

hikalkan commented May 6, 2016

I cached exceptions for Dns.GetHostAddresses call. New code is like that:

protected virtual string GetClientIpAddress(HttpContext httpContext)
{
    var clientIp = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ??
                    httpContext.Request.ServerVariables["REMOTE_ADDR"];

    try
    {
        foreach (var hostAddress in Dns.GetHostAddresses(clientIp))
        {
            if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return hostAddress.ToString();
            }
        }

        foreach (var hostAddress in Dns.GetHostAddresses(Dns.GetHostName()))
        {
            if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return hostAddress.ToString();
            }
        }
    }
    catch (Exception ex)
    {
        Logger.Debug(ex.ToString());
    }

    return clientIp;
}

As you see, I did it virtual. So, you can create a new class inherits from WebAuditInfoProvider and override GetClientIpAddress to change code for your application. Then you can replace IAuditInfoProvider service with your own implementation (#983 (comment)).

@hikalkan hikalkan closed this as completed May 6, 2016
@tamys
Copy link

tamys commented May 6, 2016

thanks @hikalkan this upgrade will help us a lot. Waiting for the nuget release ;)

@automys
Copy link

automys commented May 19, 2016

@hikalkan, thank you for adding this. Can you provide an example of how to override the class so that the app uses my new implementation? It appears my new class is not getting used by the DI container.

@tamys
Copy link

tamys commented May 19, 2016

Hi @automys, the following worked on me to replace the build in service

  class AzureGetIPFix: WebAuditInfoProvider
    {
        protected override string GetClientIpAddress(System.Web.HttpContext httpContext)
        {
            try
            {
                var ip = base.GetClientIpAddress(httpContext);
                if (!String.IsNullOrEmpty(ip)) return ip;
                else return "Possible IP: " + httpContext.Request.UserHostAddress;
            }
            catch { return "Unable to get ClientIP"; }
        }
    }

And in your preinitialize webmodule

           Configuration.ReplaceService(typeof(Abp.Auditing.IAuditInfoProvider), () =>
            {
                IocManager.Register<Abp.Auditing.IAuditInfoProvider, engine4.Extensions.AzureGetIPFix>(Abp.Dependency.DependencyLifeStyle.Transient);
            });

@automys
Copy link

automys commented May 19, 2016

Thanks @tamys, this works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants