mvc 5 controlling authorization for entire controller or entire view folder - asp.net-mvc-5

I have a mvc 5 application with a product controller and a corresponding view folder for all product related views. I'd like to make this entire thing only accessible to user with username "admin" instead of manually assigning a tag [Authorize(Users = "admin")] on top of every controller method. I tried to add a new web.config in Product views folder with the following content, but didnt work.
<configuration>
<system.web>
<authorization>
<allow users="admin"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
Is this possible to achieve at all if yes how?
thanks in advance

The AuthorizeAttribute can be added both on a specific method and on the controller class. The second will affect every action method in that controller.
[Authorize(Users = "admin")]
public class AdminController
{
public ActionResult Index() { ... }
}
If you want to use Web.config you must remember that IIS will load the Web.config file based on the URL without any knowledge of Views. So if the URL is http://server/Products/Something then you must place your configuration file in a folder called Products in the application root. Alternatively you can use <location path="/Products"> in your root Web.config file.

Related

How Can I have IIS properly serve .webmanifest files on my web site?

The Favicon Generator assembles a package for webmasters to use in order to have icons available for many different devices. The page comes with a file called site.manifest which is linked to via the following tag in the web page's document <head>:
<link rel="manifest" href="site.webmanifest">
According to Mozilla: "The web app manifest provides information about an application (such as name, author, icon, and description) in a JSON text file. The purpose of the manifest is to install web applications to the homescreen of a device, providing users with quicker access and a richer experience."
Unfortunately if you are using Microsoft's Internet Information Services (IIS), you'll get a 404.3 error if you try and access the site.webmanifest file.
The exact error message is as follows: "The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map."
How can I properly serve site.webmanifest files in IIS?
By default, IIS does not serve any files that does not have a MIME map associated with it in its (IIS) core settings.
To address this challenge, you will need to map the .webmanifest file extension to its appropriate MIME type.
To accomplish this, open IIS and follow the steps below;
On the left hand side, select either your web site or the entire server in the "Connections" menu.
If you select the server, your MIME mapping will apply to every web site on the server.
If you select a web site, it will only apply to a single web site.
Next, select "MIME Types" from the IIS menu:
Once there, click "add..." from the right hand menu.
In the dialog box that opens specify .webmanifest in the file name extension box application/manifest+json in the MIME type box.
Click "OK".
Congratulations; you've just defined the MIME type for .webmanifest on IIS.
For Azure I added this as the web.config
<?xml version="1.0"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
</staticContent>
</system.webServer>
</configuration>
For those using ASP.NET Core (I am using 2.1) you can configure the MIME types that can be served in the application Startup.cs file as per the static files docs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".webmanifest"] = "application/manifest+json";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
app.UseMvc();
}
Easier solution is to rename your manifest file to site.webmanifest.json and link as
<link rel="manifest" href="site.webmanifest.json">
IIS should already have a MIME Type for .json files
This is also helpful if deploying to Azure where its not so easy to change the IIS settings.
Adding to #Ben's answer: if you have a SPA you should put StaticFileOptions code into the UseSpaStaticFiles() call:
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".webmanifest"] = "application/manifest+json";
app.UseSpaStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
I found that the IIS server had ".json" listed in the Request Filtering feature saying it was not allowed.
Removing that allowed the file to be served.

IIS Multiple Websites access with name

i have two django websites in CGI in my IIS WebServer that are binded with two different ports: 8080 and 8081, i need to access them with something like: myserver/app1 and myserver/app2.
How i can do this?
Many thanks
Solved using this approach:
In Urls.py i've added a wrapper for all requests with these lines of code:
urlpatterns = [
url(r'^(?i)subDirectory/', include([ #Application Prefix in Webserver
url(r'^(?i)$', app.views.home, name='home'),
url(r'^(?i)home', app.views.home, name='home'),
url(r'^(?i)contact', app.views.contact, name='contact'),]
Then modified the Static_Url property under settings.py:
STATIC_URL = '/subDirectory/static/'
Then in IIS, under the main website i've added a new webapplication with the defaultAppPool and configured like indicated here (Omitting the point n°4): https://azure.microsoft.com/it-it/documentation/articles/virtual-machines-windows-classic-python-django-web-app/
And added a virtual directory (under the application) in order to serve the statics (with caching rule fixed at 7 days) files with the following web config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>
</system.webServer>
</configuration>
With this approach, you'll be able to use a main site and place/serve multiple django applications without become crazy!
Enjoy!

Using img tag in View to display static picture

I'm moving from ASP.NET to MVC and having trouble displaying a simple image. I have a Controller:
Public Class LinkedImageController
Inherits Controller
' GET: LinkedImage
Function Index() As ActionResult
Return View()
End Function
End Class
and a View:
<img src="~/Views/LinkedImage/grey_336x280.gif" alt="Views-LinkedImage" /><!-- Doesn't work -->
<img src="~/Content/LinkedImage/grey_336x280.gif" alt="Content-LinkedImage"/><!-- Works -->
I have copies of the image in the Views/LinkedImage folder and the Content/LinkedImage folder and both are set to copy to the output folder.
As you can see from the comments in the View only the <img... tag that links to the file under the Content folder displays the image correctly.
While this is only a single image where I'm trying to get to is a design for displaying existing html questionnaires within an MVC framework so I have to work out where the various static files can be stored.
I'm new to MVC so I'm assuming that the image in the View folder cannot be displayed because the routing affects it somehow. Is this correct? If not, why does only one image display?
This line in the Web.config of your Views folder blocks direct access to files therein:
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
Best policy is to put your static content in ~/Content (or another folder you create in the application root directory, if you wish) - you don't want to risk giving a malicious user access to the code in your views.

Deny file access but server properly in IIS

I have a js file that includes in the master page.
I want to deny the file access when user type the direct link in the browser address bar.
I've tried the URL filtering IIS,like:
<security>
<requestFiltering>
<denyUrlSequences>
<add sequence="Scripts/Foo/bar.min.js" />
</denyUrlSequences>
</requestFiltering>
</security>
This does work, when i type 'localhost://blah/Scripts/Foo/bar.min.js' I get blocked.
but the page whitch need this js file can not render.
Does anyone have a workaround? Thanks in advance!
I finnaly found this.
and added these sections to web.config:
<security>
<requestFiltering>
<filteringRules>
<filteringRule name="protectjs" scanUrl="true" scanQueryString="true">
<scanHeaders>
<clear />
<add requestHeader="Accept" />
</scanHeaders>
<appliesTo>
<clear />
<add fileExtension=".js" />
</appliesTo>
<denyStrings>
<clear />
<add string="text/html" />
</denyStrings>
</filteringRule>
</filteringRules>
</requestFiltering>
</security>
It works at present, though I know this way is not that reliable.
Not 100% sure but I don’t think there is a way to do this. When browser renders your page it actually sends the same request to the server as the one you do when you manually type in JS file in the browser.
IIS doesn’t have means to distinguish requests you make and the one browser makes in the background while processing your page.
One thing that might work is
adding some kind of ID to your JS file like this Scripts/Foo/bar.min.js?ID=E3CF305B-4444-E011-8FD2-1CC1DEE89A7F
ID is time limited and works only 20 seconds or so after it’s created (enough time for browser to load the page)
creating custom handler that will parse ID and decide if server should return the request or not
So when someone types Scripts/Foo/bar.min.js handler will reject the request but it will also reject request when expired ID is used.
However this is most probably going to be difficult to maintain and also performance intensive for your server.
If you want to hide your JS file why not obfuscate it.
Use HttpModule and Check for HttpContext.Current.Request.UrlReferrer. it will always be null for direct access to the .js file.
public class JSAccessModule : IHttpModule
{
public void Init(System.Web.HttpApplication Appl)
{
Appl.BeginRequest += new System.EventHandler(Rewrite_BeginRequest);
}
public void Rewrite_BeginRequest(object sender, System.EventArgs args)
{
//Block if direct Url is accessed
if (HttpContext.Current.Request.UrlReferrer == null)
{
HttpApplication App = (HttpApplication)sender;
string path = App.Request.Path;
string strExt = System.IO.Path.GetExtension(path);
if (strExt == ".js")
{
HttpContext.Current.Response.Redirect("~/AccessDenied.html");
}
}
}
public void Dispose() { }
}

authenticate file in _layouts folder

I have a public facing website www.abcd.com .. I have added a file "Authenticated.html" in _layouts folder of it. so now when user is going to this url
www.abcd.com/_layouts/authenitcated.html ... one can see all the content in it. I want this particular file to be only shown to authenticated users and asks for authentication. If there is any way i can achieve this?
Here is a couple of alternatives:
Put the following into _layouts/web.config:
<location path="Authenticated.html">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
Or as I'd prefer change your extension from html to aspx and put these two lines at the top:
<%# Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%#page Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase" %>
Alrite I figure it out...go to IIS select the web application you want...go to the file in _layouts folder you want to authenticate ->properties->File Security->uncheck anonymous access...

Resources