IIS Url Rewrite maps from custom provider? - iis

Is it possible to access a dictionary or something of a certain rewrite map from your rewrite custom provider?
Something like...{Provider:key,mapname}
which in code does something like {Mapname:key}
?

When you inherit from IRewriteProvider, in your Initialize() method you will get a Dictionary with all the settings:
public void Initialize(IDictionary<string, string> settings, IRewriteContext rewriteContext)
{
...
}
which comes from the following config section:
<system.webServer>
<rewrite>
<providers>
<provider name="MyCustomRewriteProvider" type="MyCustomRewriteProvider.....">
<settings>
<!--add key="keyName" value="keyValue" /-->
</settings>
</provider>
</providers>
</rewrite>
...
</system.webServer>
You can refer to this article for detailed information on how to create a custom URL Rewrite provider:
Developing a Custom Rewrite Provider for URL Rewrite Module

Related

ServiceStack OrmLite with multiple APIs (private and public)

We have a .net Core 3.1 MVC web application running with ServiceStack Ormlite 5.12. Currently we have a 'public' Open API for users who wish to access data programmatically. We use the following in our AppHost:
public class AppHost : AppHostBase
{
public AppHost(IServiceProvider services, IWebHostEnvironment env)
: base("My API", typeof(MyAPIService).Assembly)
{
_appServices = services;
_env = env;
}
public override void Configure(Container container)
{
SetConfig(new HostConfig
{
...
HandlerFactoryPath = "/myapipath"
});
Plugins.Add(new OpenApiFeature
{
...
});
}
}
And in our Web.config:
<configuration>
<location path="myapipath">
<system.web>
<httpHandlers>
<add path="servicestack*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>
</system.web>
<!-- Required for IIS7 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add path="servicestack*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
</location>
</configuration>
We have MyApp.ServiceModel and MyApp.ServiceInterface projects that are accessed from the https://{baseurl}/myapipath endpoint. This all works well so far.
We wish to keep the existing OpenAPI unchanged so that users don't need to change anything when updating to a new version. But we also want to add another API for use with an angular application, either by adding a separate endpoint for a 2nd API, or by filtering out what is visible in swagger with our existing API. Is it possible to add a 2nd API plugin with a different path that is separate from the existing API?
There can be only one ServiceStack Open API Plugin registered which lists all publicly accessible APIs within an AppHost.
If you want to visually differentiate APIs you can Group related APIs with Tags:
[Tag("angular")]
public class MyRequest { ... }
Alternatively you can choose to Exclude Services from Metadata Pages with:
[ExcludeMetadata]
public class MyRequestDto { ... }

Adding a JSON file for domain verification

I am trying to verify my domain through Azure using this Article. However, it keeps saying it cannot verify. I think maybe it's because I am assuming just putting it in my wwwroot is sufficient, but I don't know what else I need to do to have https://{YOUR-DOMAIN-HERE}.com/.well-known/microsoft-identity-association.json open the file itself for verification.
Verification of publisher domain failed. Unable to connect to https://mydomain/.well-known/microsoft-identity-association. [uFNK6]
Many people have faced this issue, you could have a look at this1 and this2 on Github. You may get one-time free support ticket for this issue via
You could send an email to AzCommunity[at]microsoft[dot]com with a
reference to this thread and also your Azure Subscription GUID.
As a workaround, you could add your custom domain to Azure AD. Then verify your custom domain name. After verifying your domain, you could directly select a verified domain or verify a new domain in the Publisher Domain panel without host the file at https://{YOUR-DOMAIN-HERE}.com/.well-known/microsoft-identity-association.json.
Hope this could help you.
I solved this problem by adding a web.config file to the .well-known folder to remove charset=utf8 from the Content-Type response. This appears to be necessary.
Beofre you start you can check with Curl from a PowerShell instance to see if the Content-Type being returned includes the charset and therefore is the source of your problem.
C:> curl https://www.whateveryourdomainis.org/.well-known/microsoft-identity-association.json
The web.config file contents is as follows:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<clear />
<add name="MicrosoftIdentityAssociation" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
</handlers>
<staticContent>
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</configuration>
You need to be aware that this will modify the child folders too and so if you have other sub-folders you may have to take remedial action ie another web.config file putting it back. However, it may be that once you have verified the site, the verification code can be deleted. See [https://learn.microsoft.com/en-us/answers/questions/37272/should-we-continue-to-host-microsoft-identity-asso.html][2]

IIS Client Certificate Mapping Rule not being respected

I am running IIS 8.5 on a Windows Server 2012 R2. I have configured a WebAPI (built on ASP.net) web site to use HTTPS (self-signed) with IIS Client Certificate Mapping for client certificate authentication. I am using the ManyToOneMapping where I have defined one local account to be associated to the client certificate with the incoming request. Furthermore, I have defined a Rule in the mapping so that if the "Subject" field in the certificate contains a certain string then it should allow the request.
Now, when I hit the url in the API application, Firefox prompts me to select the certificate to be used (as expected). And when i select one of the certificates that does not contain that string defined in the mapping Rule, the browser is still served with the resource. I was expected a forbidden response instead. So, it would appear that the Client Certificate mapping is not working as expected.
As I am new to IIS, I am wondering how I could go about to find out how to troubleshoot this situation. Thanks in advance.
Here is snippet from the applicationhost.config file:
<location path="SimpleApi" overrideMode="Allow">
<system.webServer>
<security>
<authentication>
<iisClientCertificateMappingAuthentication enabled="true" oneToOneCertificateMappingsEnabled="false">
<manyToOneMappings>
<add name="Authorized Access" description="Some long description" userName="SomeUser" password="[enc:AesProvider:removed:enc]">
<rules>
<clear />
<add certificateField="Subject" certificateSubField="OU" matchCriteria="Admin" />
</rules>
</add>
</manyToOneMappings>
<oneToOneMappings />
</iisClientCertificateMappingAuthentication>
</authentication>
</security>
</system.webServer>
</location>
<location path="SimpleApi">
<system.webServer>
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
</security>
</system.webServer>
</location>
The only possibility is you have other authentication mechanism enabled for your website and it is simply falling back to that authentication mechanism.
Check the Authentication module for your website in IIS and disable all other authentication mechanism.

Enabling CORS for Web API in Azure Web Apps

I have deployed a Web API project to Azure Web app. And from a angularjs app I am trying a $http.get request to the API. but it gives a CORS(cross-origin) exception though I have enabled it in my Web API startup config
app.UseCors(CorsOptions.AllowAll);
I want to Enable CORS for Azure Web App, that would solve the problem I believe
EDIT
http://nearestbuyweb.azurewebsites.net/ this is the URL of the Web app. It is trying to access http://nearestbuyapi.azurewebsites.net/api/MenuBar where the exception occurs.
I think it is not possible with Azure Web App. MSDN Question
Please help!
Note: You use CORS settings to let other websites access your site's API. Not to access other site's APIs.
Based on your comments it sounds like you're getting the CORS error when you try to make external requests from your site. That's exactly the behavior CORS is supposed to block.
For the errors to go away you would have to apply the CORS config settings on the site who's API you're trying to access.
In your case you want to make sure you're applying the config changes on the http://nearestbuyapi.azurewebsites.net site. NOT on http://nearestbuyweb.azurewebsites.net/
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
I have CORS in Azure working using this:
WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "PublicApi",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Web.config:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers></system.webServer>
You need to remove the options handler in IIS using web.config.
http://eugeneagafonov.com/post/38312919044/iis-options-cors-aspnet-webapi-en
Sorry Guys,
The issue happens only at my corporate network. Having googled I found that corporate network can be disable CORS requests . Found this here link

Custom provider in the url rewrite module

I am developing on a website which is currently hosted in Azure on a VM. Now I am changing this website to be able to run it as an Azure website.
Now my problem:
I am using the url rewrite module from IIS with the database provider, which works perfectly in the VM. With the database provider users of the website can create their own simple rewrite rules.
But when I upload my website as an Azure Website and I access a url that's specified in the database I get an error:
"The page cannot be displayed because an internal server error has occurred.".
This is the logging configuration I currently use:
<rewrite>
<rules configSource="RewriteInbound_Live.config" />
<outboundRules configSource="RewriteOutbound_Live.config" />
<providers>
<provider name="DB" type="DbProvider, Microsoft.Web.Iis.Rewrite.Providers, Version=7.1.761.0, Culture=neutral, PublicKeyToken=0545b0627da60a5f">
<settings>
<add key="ConnectionString" value="*****" />
<add key="StoredProcedure" value="sp_GetRewrittenUrl" />
<add key="CacheMinutesInterval" value="60" />
</settings>
</provider>
</providers>
</rewrite>
I've turned on web server logging which doesn't give me any information, and I've enabled application logging which also doesn't give me any information.
My question, is it possible to use custom providers for the url rewite module in Azure, of can this be achieved in another way?
I had the same problem: DbProvider not available in azure web app. So I left most of the url rewriting stuff in the web.config untouched and moved the database-based rules to the global.asax file's Application_BeginRequest method.
For redirect rules, just use a Response.Redirect or an adequate Redirect301 implementation. On the other hand, for the rewrites, use HttpContext.Current.RewritePath.
You should add a caching mechanism in order to reduce repetitive queries to the DB:
void Application_BeginRequest(Object sender, EventArgs e)
{
//TODO: Cache sql queries
string requestUrl = Request.FilePath;
using (DBConn conn = new DBConn("GetRedirectUrl"))
{
conn["input"] = requestUrl;
string res = conn.ExecuteScalar()?.ToString();
if (!string.IsNullOrEmpty(res))
{
Response.Redirect301(res);
}
}
//TODO: Cache sql queries
using (DBConn conn = new DBConn("GetRewrittenUrl"))
{
conn["input"] = requestUrl;
string res = conn.ExecuteScalar()?.ToString();
if (!string.IsNullOrEmpty(res))
{
HttpContext.Current.RewritePath(res);
}
}
}

Resources