ASP.Net Core 2.2 wwwroot static content hosted on S3 and CloudFront - asp.net-core

I am using ASP.Net Core 2.2 and would like to host wwwroot static content on AWS S3 served by CloudFront. Haven't found anything on Google so posted the question here. I am familiar with AWS S3 and Cloudfront. I only need to find out how / what to change in ASP.Net Core razor application. Any advice and insight is appreciated.

I solved it by using rewrite rules in my server (IIS).
In order to do that you add a new IIS Url Rewrite module rule under system.webServer section in web.config.
Also, if you host your app in Apache/Nginx, there is a possibility to configure redirect rule based on configuration file with server-specific syntax.
Following is a sample rule, it redirects all resources starting with "media" to CloudFront distribution.
<rewrite>
<rules>
<rule name="Media to CDN" patternSyntax="Wildcard" stopProcessing="true">
<match url="media/*" />
<action type="Redirect" url="https://<my_cloudfront_id>.cloudfront.net/media/{R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>

Related

How to properly configure IIS URL Rewrite

I am running IIS 8.5 on Win 2012 R2. I have a website under which I have hosted multiple .Net Core 3.1 WebAPIs, each running under its own non-managed app pools.
wwww.myrootsite.com -> this is site binding on the Website in IIS
|-> API.Employees -> Separate app running on non-managed AppPool1
|-> API.Departments -> Separate app running on non-managed AppPool2
Within API.Employees, lets say I have 2 controllers mapping to /api/employees and api/teams.
Currently, for UI, the endpoint looks like this.
https://wwww.myrootsite.com/API.Employees/api/employees
https://wwww.myrootsite.com/API.Employees/api/teams
I want URLs to look like this.
https://wwww.myrootsite.com/api/employees
https://wwww.myrootsite.com/api/teams
I already have ARR 3.0 and URL Rewrite 2.0 modules installed on the server.
So I tried creating an inbound rule for api/teams. This is what I have currently configured.
<rewrite>
<rules>
<rule name="API.Employees.Teams Rewrite" stopProcessing="true">
<match url="^api/teams?(.*)" />
<action type="Rewrite" url="API.Employees/{R:0}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
However, when I try to access the URL https://wwww.myrootsite.com/api/teams?id=100, I get 500 internal server error. I am not able to get further details of what is causing the 500 error. Can anyone kindly point out, what am I doing wrong and how do I get further details of the error?
Thanks!

Redirect Response always redirects to the same domain

I'm writing a suite of ASP.NET Core web applications that occasionally have to redirect to one another. When testing locally, everything works fine. However, when I publish them on our staging server, the redirects always "stay" in the same host. For example, if I am on http://app1.test/ and redirect to http://app2.test/somepath, what I actually get in the Location HTTP header i http://app1.test/somepath: any URL I specify is transformed so that it "stays" in the current host name.
This doesn't happen locally, however. I've deployed the apps as Kestrel processes, and they are exposed via IIS working as a reverse proxy. May this be the cause? What should I do to fix the issue?
UPDATE
Here is the full web.config for the reverse proxy of app1.test:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:5000/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
<system.web>
<sessionState mode="InProc" />
<customErrors mode="RemoteOnly" />
</system.web>
</configuration>
app2.test's web.config is virtually the same (apart, of course, for the port numbers).
UPDATE 2
I'll try to explain better. I noticed that the target site doesn't really matter, so I'll keep things simpler: I have an action in my application that I want to redirect the user to Google. This is the action, in the Home controller:
public IActionResult ToGoogle()
{
return Redirect("https://www.google.com?q=Hi");
}
If I launch the web app locally and request http://localhost:1234/Home/ToGoogle, everything is fine: the response is a 302 Found, with the correct URL (www.google.com etc.) in the Location header.
Once I publish the app to the staging server (Kestrel app on port 5000, behind an IIS reverse proxy with the rewrite rule posted above), this is what happens instead:
What is the cause of that?
I found the solution myself. It was indeed a problem with reverse proxy.
IIS has an option to rewrite the host in response headers. The solution is described in this answer (there are addenda in other answers to that same question if your version of IIS or Windows Server is not the one specified).

URL Rewrite on Windows 2016 (IIS 10) with .Net Core to point to CDN

I have a brand new virtual server running Windows 2016 (IIS 10). I have a website that is built with .NET Core 1.1.
I would like to rewrite all image, js, font, and css references to point to a CDN.
Problem 1, adding this rule:
<rule name="CDN Assets" stopProcessing="true">
<match url="^css/(.+)$|^images/(.+)$|^fonts/(.+)$|^js/(.+)$" ignoreCase="true" />
<action type="Rewrite" url="https://cdn.example.net/{R:0}" appendQueryString="true" />
</rule>
... results in a 404 for every request. For example a request to https://example.net/images/en-us/logo.png even though the image exists both in the real folder under and at https://cdn.example.net/images/en-us/logo.png
Is this possibly caused by .NET Core or by HTTP2 (which is introduced in IIS 10). Or do I need some sort of outbound rule also?
Problem 2, adding an outbound rule like:
<rule name="Outbound CDN: images" preCondition="IsHtml">
<match filterByTags="A, Img, Link" pattern="^/images/(.+)$" />
<action type="Rewrite" value="//cdn.example.net{R:0}" />
</rule>
<preConditions>
<preCondition name="IsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html"/>
</preCondition>
</preConditions>
Causes the page response to become complete mangled unreadable garbage. Is this because of the response is sent over HTTPS?
UPDATE (2016/03/16 8:01PM MST)
Using #EricB suggestion I have tried implementing it via the Microsoft.ASPNetCore.Rewrite package to no avail.
I have this in my Startup.cs and just the local images are being loaded:
string CDNroot = Configuration["URLs:CDN"].Trim();
RewriteOptions rewriteOptions = new RewriteOptions()
.AddRewrite(#"^(css|images|fonts|js)(.+)$", CDNroot + "/$1$2", skipRemainingRules: true);
app.UseRewriter(rewriteOptions);
If I change this to:
string CDNroot = Configuration["URLs:CDN"].Trim();
RewriteOptions rewriteOptions = new RewriteOptions()
.AddRedirect(#"^(css|images|fonts|js)(.+)$", CDNroot + "/$1$2");
app.UseRewriter(rewriteOptions);
... and request an image URL it is correctly redirected to the CDN URL. But you wouldn't want a redirect, as that is adding an extra 30x response to every asset request. I am stumped why Redirect works, but Rewrite doesn't.

Hide Azure Blob Url

I have a large amount of files stored in a public Azure blob container, all of which are referenced directly via the HTML in my ASP.NET MVC web application. As an example a path to one of the images in blob storage looks like so:
//<my-storage-account-name>.blob.core.windows.net/public/logo.png
I want to avoid displaying my storage account name in my HTML source code so rather than:
<img src="//<my-storage-account-name>.blob.core.windows.net/public/logo.png"/>
I'd prefer to use this:
<img src="/images/logo.png"/>
I want to avoid setting up an MVC route and using the blob API to load the file into the response stream so thought a web.config solution might be the simplest solution, i.e.
<rule name="Image Redirect" stopProcessing="true">
<match url="^images/(.*)$" ignoreCase="false" />
<action type="Redirect" url="//<my-storage-account-name>.blob.core.windows.net/public/{R:1}" redirectType="Permanent" />
</rule>
QUESTION: Is this the most efficient method given that any page could be loading 30+ images at a time? Or should I just use the public blob URL despite my concerns for performance gains?
I found a Microsoft Hands-on Lab where they recommend the web.config URL rewrite rule option:
Hands on Lab: Maintainable Azure Websites: Managing Change and Scale (July 16, 2014)
(Code Snippet - WebSitesInProduction - Ex4 - UrlRewriteRule)
<system.webServer>
<rewrite>
<rules>
<rule name="redirect-images" stopProcessing="true">
<match url="img/(.*)"/>
<action type="Redirect" url="http://[YOUR-STORAGE-ACCOUNT].blob.core.windows.net/images/{R:1}"></action>
</rule>
</rules>
</rewrite>
"Note: URL rewriting is the process of intercepting an incoming Web request and redirecting the request to a different resource. The URL rewriting rules tells the rewriting engine when a request needs to be redirected, and where should they be redirected. A rewriting rule is composed of two strings: the pattern to look for in the requested URL (usually, using regular expressions), and the string to replace the pattern with, if found. For more information, see URL Rewriting in ASP.NET."

https://www.mydomain.com and https://mydomain.com go to different pages

Web Server: IIS 6.0 (ASP.Net 4.0)
I host two sites: one is the main web site and the other is the store site. Each are separate web sites in IIS. Each share the same wildcard SSL certificate. The store site uses a Host Header (store.mydomain.com) to direct traffic to it.
I want it so any URL used without the sub-domain "store" directs the user to the main web site, not the store web site.
The problem I'm experiencing is that the following URL always directs users to the default.aspx page on the store web site:
https://www.mydomain.com
Yet, these URLs correctly go to the main page on the main web site:
http://mydomain.com
http://www.mydomain.com
https://mydomain.com
What's up with the https://www that directs users to different page?
I have added a rewrite rule in the web.config file for both sites but it doesn't have any effect:
<rewrite>
<rules>
<rule name="Consistent Domain" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{HTTP_HOST}" pattern="^mydomain.com$" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="http://www.mydomain.com/{R:1}" />
</rule>
</rules>
</rewrite>
First, are you sure this is IIS6? The URLRewrite feature is part of IIS7 and would have no effect under IIS6 if present. If this is IIS6 that may well be the answer to your question.
That aside, it is difficult to answer this based on the data given. It is possible that the bindings of the sites is incorrect and resulting in the traffic going to a site you don't expect.