C# read customHeaders value from web.config - asp.net

I have requirement where I need to read customHeaders value in WCF. Below is sample config file of my application. I need to find programmatically value of "Access-Control-Allow-Origin" key. Please help in achieving the same.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff"/>
<add name="Access-Control-Allow-Origin" value="http://localhost:4200"/>
<add name="Access-Control-Request-Method" value="POST,GET,PUT,DELETE,OPTIONS"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type"/>
<add name="Access-Control-Allow-Credentials" value="true"/>
</customHeaders>
</httpProtocol>
I tried below but it is not working.
Configuration config = serverManager.GetWebConfiguration("Web.Config");
ConfigurationSection httpProtocolSection = config.GetSection("system.webServer/httpProtocol");
ConfigurationElementCollection customHeadersCollection = httpProtocolSection.GetCollection("customHeaders");
foreach(var element in customHeadersCollection)
{
Response.Write(element.Attributes[0].Name);
}

I found this example from Microsoft to read these values.
https://learn.microsoft.com/en-us/iis/configuration/system.webserver/httpprotocol/customheaders/#sample-code
You need a reference to Microsoft.Web.Administration.dll to access these classes.
using (ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetWebConfiguration("Default Web Site");
ConfigurationSection httpProtocolSection = config.GetSection("system.webServer/httpProtocol");
ConfigurationElementCollection customHeadersCollection = httpProtocolSection.GetCollection("customHeaders");
// what you want is in customerHeadersCollection
}

Related

DocumentDB Trace listener

I'm trying register DocumentDB tracing with an existing listener. The code snippet below properly traces a single message to my expected listener but not the actual traces generated by the DocumentDB C# client. Am I missing something?
Snippet from Global.asax:
private static TraceSource DocDBSource;
private static TraceListener ExistingListener = new .....;
public void RegisterDocDBListener() {
DocDBSource = new TraceSource("DocDBTrace");
DocDBSource.Switch.Level = SourceLevels.Information;
DocDBSource.Listeners.Add(ExistingListener);
DocDBSource.TraceInformation("DocDB tracing initialized");
}
According to your description, I have checked the DefaultTrace from DocumentDB client library for .NET as follows:
For Client-side Logging with the .NET DocumentDB Client Library, you could configure the system.diagnostics configuration as follows to collect and persist documentdb log messages to a text file as follows:
<system.diagnostics>
<sources>
<source name="DocDBTrace">
<listeners>
<!--ConsoleTraceListener-->
<add name="configConsoleListener" type="System.Diagnostics.ConsoleTraceListener"/>
<!--TextWriterTraceListener-->
<add name="myListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="TextWriterOutput.log" />
</listeners>
</source>
</sources>
<switches>
<add name="ClientSwitch" value="Warning"/>
</switches>
</system.diagnostics>
Note: The default Log Level is Information, you could change the ClientSwitch to your expected Log Level (Off, Error, Information, Verbose).
Result
Console Application
Web Application

Nuget Server - Private Repository - Change Package Path location Dynamically by routing Url

We are working in private repository for our own private nuget packages in ASP.NET Project . We are in a position to change the nuget feed for every customer. But nuget packages are located in a location which is specified in Web.Config.
Is there a possibility to change the location dynamically through routing(URL) ? i have refferd this blog http://blog.maartenballiauw.be/post/2011/05/09/Using-dynamic-WCF-service-routes.aspx even though the packages url refers the path given in the webconfig file
public static void MapNugetRoutes(RouteCollection routes)
{
var factory = new DataServiceHostFactory();
var serviceRoute = new ServiceRoute("nuget/packages/getpackages/{platform}", factory, typeof(Packages));
serviceRoute.Defaults = new RouteValueDictionary { { "serviceType", "odata" } };
serviceRoute.Constraints = new RouteValueDictionary { { "serviceType", "odata" } };
routes.Add("nuget", serviceRoute);
}
<appSettings>
<add key="requireApiKey" value="true" />
<add key="apiKey" value="" />
<add key="packagesPath" value="~/NugetPackages/" />
<add key="enableSimpleMembership" value="false" />
<add key="" />
</appSettings>
the "NugetPackages" is my local repositary address , i need to access the repositary privately , like there are several folders inside that above location, i need dynamically access that folders NugetPackages/folder1, NugetPackages/folder2 like this, Is it possible?
thanks in advance..

Configure an OWIN static file server at a specific route prefix

I'm experimenting with keeping my content in non-default locations (eg in bower_components or /packages/../tools). As part of the experiment I am trying to set up an asp.net mvc 5 application where hitting a certain route allows me to browse files in the undersorejs package directory.
I have the following nuget packages (in addition to the default)
Install-Package underscore.js
Install-Package Microsoft.Owin.StaticFiles
Install-Package Microsoft.Owin.Host.SystemWeb
This is what I have in an OWIN startup class
var fileSystem = new PhysicalFileSystem(
HttpContext.Current.Server.MapPath("~")+"/../packages/underscore.js.1.6.0"
);
var options = new FileServerOptions {EnableDirectoryBrowsing = true, FileSystem = fileSystem};
app.MapWhen(ctx =>
ctx.Request.Uri.AbsolutePath.StartsWith("/__underscore"),
ab => ab.UseFileServer(options)
);
To my understanding and previous experimentation this is pretty straightforward - when the request begins with /__underscore use the simple static file server. However when I head over to /__underscore I get a 404 error.
However, placing breakpoints I can see that the UseFileServer lambda executes once on startup and then never again, while the predicate lambda is called on every request (and returns the correct value).
What am I missing?
You need to specify the RequestPath as well:
var options = new FileServerOptions {
EnableDirectoryBrowsing = true,
FileSystem = fileSystem,
RequestPath = PathString.FromUriComponent("/__underscore")
};
As per your comment:
If you're unable to download files, try to explicitly register OwinHttpHandler in your Web.Config:
<system.webServer>
<handlers>
<add name="Owin" verb="" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb"/>
</handlers>
</system.webServer>
Alternatively, you can set runAllManagedModulesForAllRequests to 'true':
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule" />
</modules>
</system.webServer>

Block IP Addresses In HttpModule

I have taken over a domain that had was running an old version of Community Server. Needless to say the bots are spamming me trying to find holes.
I'd like to block entire IP blocks before System.Web.HttpRequest.ValidateInputIfRequiredByConfig() is fired. I have a IHttpModule that I have tried but I assume it's getting called after because HealthMonitoring is catching the Exceptions. Here is the module:
public class IpBlockerModule : IHttpModule
{
private static readonly string[] Hacks = new[]
{
"60.169.73.",
"60.169.75.",
"61.160.232.",
"61.160.207.",
"92.85.161."
};
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += (Application_BeginRequest);
}
private void Application_BeginRequest(object source, EventArgs e)
{
var context = ((HttpApplication) source).Context;
var ipAddress = context.Request.UserHostAddress;
if (!IsHackIpAddress(ipAddress))
{
context.Response.StatusCode = 403; // (Forbidden)
}
}
private static bool IsHackIpAddress(string ip)
{
if (ip == null) return true;
return Hacks.Any(x => x.StartsWith(ip));
}
}
And the relevent web.config sections:
<system.web>
<httpModules>
<add name="IpBlockerModule" type="MyNameSpace.IpBlockerModule" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" >
<add name="IpBlockerModule" type="MyNameSpace.IpBlockerModule" preCondition="" />
</modules>
</system.webServer>
The reasoning behind this is my inbox is getting spammed from all the
A potentially dangerous Request.Path value was detected from the
client
and
A potentially dangerous Request.Form value was detected from the client
notifications. Is something wrong with my Module, or am I correct in assuming modules don't get fired until after the fact?
As an alternative solution have you considered letting IIS do the work for you? This way the request never makes it to your application. You can do this via the web.config and there's an article detailing the process located here. The following example is copied directly from that article and would be placed inside the <system.webServer> section of your web.config:
<security>
<ipSecurity allowUnlisted="true"> <!-- this line allows everybody, except those listed below -->
<clear/> <!-- removes all upstream restrictions -->
<add ipAddress="83.116.19.53"/> <!-- blocks the specific IP of 83.116.19.53 -->
<add ipAddress="83.116.119.0" subnetMask="255.255.255.0"/> <!--blocks network 83.116.119.0 to 83.116.119.255-->
<add ipAddress="83.116.0.0" subnetMask="255.255.0.0"/> <!--blocks network 83.116.0.0 to 83.116.255.255-->
<add ipAddress="83.0.0.0" subnetMask="255.0.0.0"/> <!--blocks entire /8 network of 83.0.0.0 to 83.255.255.255-->
</ipSecurity>
</security>
You can also add the ability to get and log IP addresses so as to identify and block only the spammy ones.
Here's C# code to get IP addresses
string ipadd;
ipadd = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (ipadd == "" || ipaddress == null)
ipadd = Request.ServerVariables["REMOTE_ADDR"];
I noticed that the link in the answer above is dead, so use this well-detailed article here

Setting up redirect in web.config file

I'm trying to redirect some unfriendly URLs with more descriptive ones. These URLs end in .aspx?cid=3916 with the last digits being different for each category name page. I want it to instead redirect to Category/CategoryName/3916. I tried this in the web.config file:
<location path="Category.aspx?cid=3916">
<system.webServer>
<httpRedirect enabled="true" destination="http://www.example.com/Category/CategoryName/3916" httpResponseStatus="Permanent" />
</system.webServer>
</location>
but since it didn't end with just the extension, it didn't work. Is there an easy way to get this to work? I'm using IIS 7.5.
Open web.config in the directory where the old pages reside
Then add code for the old location path and new destination as follows:
<configuration>
<location path="services.htm">
<system.webServer>
<httpRedirect enabled="true" destination="http://example.com/services" httpResponseStatus="Permanent" />
</system.webServer>
</location>
<location path="products.htm">
<system.webServer>
<httpRedirect enabled="true" destination="http://example.com/products" httpResponseStatus="Permanent" />
</system.webServer>
</location>
</configuration>
You may add as many location paths as necessary.
You probably want to look at something like URL Rewrite to rewrite URLs to more user friendly ones rather than using a simple httpRedirect. You could then make a rule like this:
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite to Category">
<match url="^Category/([_0-9a-z-]+)/([_0-9a-z-]+)" />
<action type="Rewrite" url="category.aspx?cid={R:2}" />
</rule>
</rules>
</rewrite>
</system.webServer>
In case that you need to add the http redirect in many sites, you could use it as a c# console program:
class Program
{
static int Main(string[] args)
{
if (args.Length < 3)
{
Console.WriteLine("Please enter an argument: for example insert-redirect ./web.config http://stackoverflow.com");
return 1;
}
if (args.Length == 3)
{
if (args[0].ToLower() == "-insert-redirect")
{
var path = args[1];
var value = args[2];
if (InsertRedirect(path, value))
Console.WriteLine("Redirect added.");
return 0;
}
}
Console.WriteLine("Wrong parameters.");
return 1;
}
static bool InsertRedirect(string path, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
// This should find the appSettings node (should be only one):
XmlNode nodeAppSettings = doc.SelectSingleNode("//system.webServer");
var existNode = nodeAppSettings.SelectSingleNode("httpRedirect");
if (existNode != null)
return false;
// Create new <add> node
XmlNode nodeNewKey = doc.CreateElement("httpRedirect");
XmlAttribute attributeEnable = doc.CreateAttribute("enabled");
XmlAttribute attributeDestination = doc.CreateAttribute("destination");
//XmlAttribute attributeResponseStatus = doc.CreateAttribute("httpResponseStatus");
// Assign values to both - the key and the value attributes:
attributeEnable.Value = "true";
attributeDestination.Value = value;
//attributeResponseStatus.Value = "Permanent";
// Add both attributes to the newly created node:
nodeNewKey.Attributes.Append(attributeEnable);
nodeNewKey.Attributes.Append(attributeDestination);
//nodeNewKey.Attributes.Append(attributeResponseStatus);
// Add the node under the
nodeAppSettings.AppendChild(nodeNewKey);
doc.Save(path);
return true;
}
catch (Exception e)
{
Console.WriteLine($"Exception adding redirect: {e.Message}");
return false;
}
}
}

Resources