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:
上一篇: HTTP状态代码进行身份验证但未经授权?
下一篇: 针对所有请求的自定义授权