5

I have an application developed in .net vb and SQLServer, I want to restrict files js to be available to logged in users, but otherwise return a 403 error or similar. For example a user should be able to media/js/controller/myController.js only if they're logged in.

I know how to control the actual displaying of the files aspx, ashx and ascx if they're not logged in, but not how to block access to the js file if they visit the link directly in their browser, for example http://www.myapp.com/media/js/controller/myController.js. It's show my code javascript.

How can I achieve this?

UPDATE

It's my authentication mode in my web.config

<!--<authentication mode="Windows"/>-->
<authentication mode="Forms">
  <forms name="AuthCookie" path="/" loginUrl="login.aspx" protection="All" timeout="2000">
    <credentials passwordFormat="Clear" />
  </forms>
</authentication>
<authorization>
  <!--<allow roles="***" />
  <deny users="*" />-->
  <deny users="?" />
  <allow users="*" />
</authorization>
CMedina
  • 4,034
  • 3
  • 24
  • 39
  • The Quick answer is, you can't. The end users browser needs to access the files in order to render your site on his/her side, without access to the .js files they simply won't be able to render the site as you intended. There MIGHT be a chance to accomplish this using some .htaccess magic, but I'm not sure I'd go down that path if it was some important site. – JaggenSWE May 31 '16 at 07:33
  • @JaggenSWE Is correct, I understand that the browser needs access to js files to be able to work, but I meant to restrict access while you have not logged (block access to a folder perhaps) – CMedina May 31 '16 at 15:00
  • You can go with .htaccess 'valid user', otherwise you'll need to generate this js file as any other restricted page from backend. – faster Jun 03 '16 at 08:02
  • I see that you're using IIS. Is [this](http://stackoverflow.com/questions/2903292/how-do-i-protect-static-files-with-asp-net-form-auhentication-on-iis-7-5) any use? – Peter Brittain Jun 03 '16 at 22:24
  • @CMedina what type of authentication are you using? – Jaqen H'ghar Jun 05 '16 at 13:13
  • @JaqenH'ghar ``, It's my line in my web.config – CMedina Jun 06 '16 at 14:10

4 Answers4

5

I'm not sure why you care to restrict your JavaScript files but use this to serve the files via the controller.

public class ScriptsController : Controller
{
    //option 1. Have one method for all the files.
    [LoggedIn]
    public ActionResult Get(string fileName)
    {
        return File(Server.MapPath("~/media/js/" + fileName + ".js"), "text/javascript");
    }
    //option 2:  have a method for each file 
    [LoggedIn]
    public ActionResult main()
    {
        return File(Server.MapPath("~/media/js/main.js"), "text/javascript");
    }
}

In the route config

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {

        routes.MapRoute(
              "JSFiles",
              "{controller}/{fileName}",
              new { controller = "Scripts", action = "Get" }
              );
    }
}

If you put this method in your "ScriptsController", the url would be something like http://www.myapp.com/Scripts/Get/main where main is the name of the javascript controller.

In order to prevent the direct download, you can set that in the web config or put the files in a non served location on the server. Either way. Web config would probably be better for the long term.

web config way

<location path="media">
    <system.web>
        <authorization>
            <deny users="*"/>
        </authorization>
    </system.web>
</location>

You should also add validation to prevent the user from serving files other than the js files you want to serve (like the web config, etc.)

Bryan Euton
  • 919
  • 5
  • 12
  • It's a good solution, unfortunately I do not work with controller and path, the role of controller makes it a ashx file. – CMedina Jun 08 '16 at 15:16
4

If I understand it right, all you want to do is to redirect user to login page, if user types the URL and goes to the page directly. While asp.net pages provide options to disable that, same is not available for js files. E.g. if a user types xyz.com\adminsection\admin.aspx in the url bar, it should redirect to xyz.com\login.aspx. And same should happen if user types xyz.com\adminsection\JS\admin.js.

In that case, you don't have to do any code change. This is just a small config setting. Just add following code to the web.config file

<location path="YourJSFolderHere (e.g. adminsection\JS)">
  <system.web>
    <authorization>
        <deny users="?" />
    </authorization>
  </system.web>
</location>

You will have to add this for every folder in question.

Do note, that this works fine if user is not logged in. But if user is logged in and then types xyz.com\adminsection\JS\admin.js, it will allow user to download the js file.

jitendragarg
  • 945
  • 1
  • 14
  • 54
  • I tried it myself. It works, for non-authenticated users. – jitendragarg Jun 08 '16 at 15:05
  • I tried it and get the error ` path attribute must be a relative virtual path. It cannot contain any of '?' ':' '\' '*' '"' '<' '>' or '|'.` My route of js files is: `static/xyz/js` – CMedina Jun 08 '16 at 15:20
  • I think you are using the wrong path. simply use `..\static\xyz\js`, the same way you use it in aspx file. – jitendragarg Jun 09 '16 at 11:24
3

JS files are considered static content and .NET does not handle them by default.

From MSDN:

By default, IIS processes static content itself - like HTML pages and CSS and image files - and only hands off requests to the ASP.NET runtime when a page with an extension of .aspx, .asmx, or .ashx is requested.

You can manually set the configuration to handle .js files. Keep in mind that it will add a bit overhead, because they will go through .NET's pipeline.

Add to your web.config:

<compilation>
  <buildProviders>
    <remove extension=".js" />
    <add extension=".js" type="System.Web.Compilation.PageBuildProvider" />
  </buildProviders>
</compilation>

And:

<system.webServer>
  <handlers>
    <add name="JS" path="*.js" verb="GET, HEAD, POST, DEBUG" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
  </handlers>
</system.webServer>

Now, because your web.config already has a global rule to deny unauthenticated users from .NET resources, these settings will restrict all the JS files too.

Therefore you should open the path to the public js files that you don't want to block from unauthenticated users:

<location path="public-js-folder-path">
  <system.web>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</location>

Hope it helps. If you have any questions please tell me.

Jaqen H'ghar
  • 16,186
  • 8
  • 49
  • 52
  • I tried it and get the error ` path attribute must be a relative virtual path. It cannot contain any of '?' ':' '\' '*' '"' '<' '>' or '|'.` My route of js files is: `static/xyz/js` – CMedina Jun 08 '16 at 15:22
  • @CMedina what is the location path that you put? – Jaqen H'ghar Jun 08 '16 at 15:26
  • my route js files is `static/xyz/js` – CMedina Jun 08 '16 at 15:29
  • @CMedina you put the path `` and it gives you this error? Also which IIS version are you using please? Also keep in mind that you need to put in the path the location of the JS files you want to be public and not restricted (The two first code snippets will handle the blocking and the third code snippet is to open public JS files) – Jaqen H'ghar Jun 08 '16 at 15:45
  • Yes, and add the two pieces of code, I work with version 7 of IIS – CMedina Jun 08 '16 at 16:07
  • Delete the `location` code part from the web.config and just put the `buildProviders` and `handlers` from the answer. does it block unauthorized users from all the JS files in your project and redirect them to login? – Jaqen H'ghar Jun 08 '16 at 16:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114146/discussion-between-jaqen-hghar-and-cmedina). – Jaqen H'ghar Jun 08 '16 at 16:53
2

You can serve up javascript just like you serve up any other content from any server side scripting language. As long as you set the appropriate headers the web browser will be quite happy with the result.

I run production code where logged-in visitors are pointed in the html by a <script> tag to a php url.

The php code then :

  • verifies if the user is indeed logged in
  • sends out a header Content-Type: application/javascript
  • and then just outputs the source code of the javascript

That's it.

Should be not that different in .NET.

Alternatively: where you output the html, you could also output the javascript inline. And hence no advantage of the browser caching the js.

See also here for .NET code: How do you output raw javascript in asp.net

Community
  • 1
  • 1