Custom Authorization for all requests to sub

I have a ASP.NET 4.0 website which contains a sub-folder with multimedia files like JPG, PNG, MP4, MP3, etc.

Currently, any user with the full link to the files is able to access the multimedia files without any restriction. I want to find the currently logged in user who is making the request and after checking their permissions from DB allow/disallow them to access the file requested.

I have tried implementing a Custom HttpModule for this purpose but I am not able to find the current user making the request. Below is my code:

public class CustomHttpModule : IHttpModule
{
    private const string URL_TO_LOOK_FOR = "/MultiMediaFiles/";

    public CustomHttpModule()
    { }

    public void Init(HttpApplication app)
    {
        app.AuthenticateRequest += CustomAuthenticateRequest;
        //app.EndRequest += CustomAuthenticateRequest;
    }

    void CustomAuthenticateRequest(object source, EventArgs e)
    {
        HttpApplication app = (HttpApplication)source;
        HttpContext context = app.Context;
        Uri url = context.Request.Url;
        if (url.AbsolutePath.StartsWith(URL_TO_LOOK_FOR, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.Response;
            response.Clear();
            response.Write("app.Context.User :");
            if (context.User == null || context.User.Identity == null || context.User.Identity.Name == null)
            {
                response.Write("No user");
            }
            else
            {
                response.Write(context.User.Identity.Name);
            }

            response.End();
            response.Flush();
            response.Close();
        }
    }

    public void Dispose()
    { }
}

I tried attaching to events: BeginRequest , AuthenticateRequest , PostAuthenticateRequest and even EndRequest , but in each case context.User is always null even after I have logged in to my website.

EDIT: I am using the FormsAuthentication and my web.config contains:

<system.web>
    <authentication mode="Forms">
        <forms name="MyWebFORMAUTH" timeout="60" 
               loginUrl="~/web/logon/default.aspx" cookieless="UseCookies" 
               defaultUrl="~/web/logon/default.aspx" 
               slidingExpiration="true" />
    </authentication>
</system.web>
<system.webServer>
    <modules>
      <add name="CustomHttpModule" type="CustomHttpModule"/>
    </modules>
<system.webServer>

NOTE: I cannot modify the links to multimedia files.

Please HELP.


UPDATE:

You would also need to tell ASP.NET that you don't want to execute static content handler for certain file types in certain directory.

Here is the updated version of web.config file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <httpRuntime />
        <authentication mode="Forms">
            <forms name="MyWebFORMAUTH" timeout="60"
                   loginUrl="~/web/logon/default.aspx" cookieless="UseCookies"
                   defaultUrl="~/web/logon/default.aspx"
                   slidingExpiration="true" />
        </authentication>
    </system.web>
    <system.webServer>
        <modules>
            <add name="CustomHttpModule" type="CustomHttpModule" />
        </modules>
        <defaultDocument>
            <files>
                <clear />
                <add value="Default.aspx" />
            </files>
        </defaultDocument>
    </system.webServer>
    <location path="MultiMediaFiles">
        <system.webServer>
            <handlers>
                <!-- This line tells ASP.NET to skip the processing of PNG files
                     by default static content handler. -->
                <add name="SkipStaticPng" path="*.png" verb="GET"
                     type="System.Web.Handlers.TransferRequestHandler"
                     preCondition="integratedMode,runtimeVersionv4.0" />
            </handlers>
        </system.webServer>
    </location>
</configuration>

Your code should work. Here is the example:

Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebForm" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Test</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Label ID="CurrentUserLabel" runat="server" />
        <br />
        <asp:Button ID="LoginButton" runat="server" OnClick="LoginButton_Click" Text="Login" />
    </form>
</body>
</html>

Default.aspx.cs:

using System;
using System.Security.Principal;
using System.Web.Security;

public partial class WebForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            PopulateCurrentUserName();
    }

    protected void LoginButton_Click(object sender, EventArgs e)
    {
        FormsAuthentication.SetAuthCookie("test_user", false);
        Response.Redirect(Request.Url.AbsoluteUri);
    }

    private void PopulateCurrentUserName()
    {
        IPrincipal user = Request.RequestContext.HttpContext.User;
        if (user != null && user.Identity != null && !String.IsNullOrEmpty(user.Identity.Name))
            CurrentUserLabel.Text = user.Identity.Name;
        else
            CurrentUserLabel.Text = "(null)";
    }
}

CustomHttpModule.cs:

using System;
using System.Web;

public class CustomHttpModule : IHttpModule
{
    private const string URL_TO_LOOK_FOR = "/MultiMediaFiles/";

    public CustomHttpModule()
    {
    }

    public void Init(HttpApplication app)
    {
        app.AuthenticateRequest += CustomAuthenticateRequest;
    }

    void CustomAuthenticateRequest(object source, EventArgs e)
    {
        HttpApplication app = (HttpApplication)source;
        HttpContext context = app.Context;
        Uri url = context.Request.Url;
        if (url.AbsolutePath.StartsWith(URL_TO_LOOK_FOR, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.Response;
            response.Clear();
            response.Write("app.Context.User :");
            if (context.User == null || context.User.Identity == null || context.User.Identity.Name == null)
            {
                response.Write("No user");
            }
            else
            {
                response.Write(context.User.Identity.Name);
            }

            response.End();
            response.Flush();
            response.Close();
        }
    }

    public void Dispose()
    {
    }
}

web.config:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0"/>
        <httpRuntime/>
        <authentication mode="Forms">
            <forms name="MyWebFORMAUTH" timeout="60"
                   loginUrl="~/web/logon/default.aspx" cookieless="UseCookies"
                   defaultUrl="~/web/logon/default.aspx"
                   slidingExpiration="true" />
        </authentication>
    </system.web>
    <system.webServer>
        <modules>
            <add name="CustomHttpModule" type="CustomHttpModule"/>
        </modules>
        <defaultDocument>
            <files>
                <clear/>
                <add value="Default.aspx"/>
            </files>
        </defaultDocument>
    </system.webServer>
</configuration>

And here is the test scenario:

  • Clear the cookies in your browser.
  • Navigate to the start page (let's say it is http://localhost).
  • You will see that current user is (null).
  • Open http://localhost/MultiMediaFiles/ in the second tab.
  • You will see the "app.Context.User :No user" message.
  • Switch back to the previous tab and click "Login" button.
  • You will see that current user now is "test_user".
  • Switch to the second tab and refresh the page.
  • If everything is correct then the "app.Context.User :test_user" message should be displayed.
  • 链接地址: http://www.djcxy.com/p/22242.html

    上一篇: HTTP状态代码进行身份验证但未经授权?

    下一篇: 针对所有请求的自定义授权