我有一个带有表单身份验证的asp.net Web应用程序,并且根据活动目录检查用户(凭据),用户名实际上是来自AD的samAccountName属性。 现在我需要让用户能够访问位于文件共享上的一些文件,其中每个用户都有自己的文件夹。
第一个概念证明就是这样:
IIS中的appPool配置为在某个域用户下运行,并且该用户获得了对文件共享和所有用户文件夹的R / W访问权限
当用户登录到Web应用程序时,只有路径“\\ myFileServer \ username”中文件夹的内容对他可见。同样,在上传文件时,它们会存储到“\\ myFileServer \ username”。
虽然这有效,但似乎根本不安全。第一个问题是运行应用程序池的用户可以访问所有用户的文件夹。更令人担忧的是,只有用户名才能确定您有权访问哪个文件夹。
所以我的问题是这样做的正确/更好的方法是什么?我正在阅读有关冒充用户的内容,但如果我理解正确的话,我不会再这样做了吗?我没有Windows身份验证,因为必须可以从Internet访问Web应用程序。
答案 0 :(得分:1)
我建议不要在用户帐户下运行该应用程序,而是创建一个特定于应用程序的帐户,在该帐户下使用正确的R / W权限运行该应用程序,并将提供这些权限的人员与开发团队分开。
在应用程序的身份验证中:收到GET / POST请求后,您可以验证当前用户读取/写入数据的路径,并将此与用户有权读取/写入的路径交叉引用。如果这些不正确,请返回401 NOT AUTHORIZED响应,否则,继续执行此操作。
如果您的端点受到正确保护,并且应用程序在其自己的帐户下运行,我认为设置本身没有任何损害。然而,这仍然为开发人员提供了一种通过应用程序间接访问其他用户文件的方法。根据这些检查的严格程度,您可以添加其他控件(例如,只允许应用程序从生产服务器进行连接,并且只允许以受控方式进行服务器传输)。
答案 1 :(得分:1)
从问题描述中我认为Custom HttpHandlers
是您的正确选择。你没有提到你的文件夹中会出现什么类型的文件,为简洁起见,我将通过假设它将有PDF文件来回答。
正如您所提到的,您的应用程序将拥有不同的用户,因此您需要使用.NET内置身份验证管理器和角色提供程序。通过简单的安全框架设置,我们将一个PDF文件放在Web应用程序中,位于受web.config保护的文件夹后面。然后创建一个自定义HTTP处理程序,将静态文档的访问权限限制为只允许那些应该被允许的用户查看它。
示例HTTP处理程序:
public class FileProtectionHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
switch (context.Request.HttpMethod)
{
case "GET":
{
// Is the user logged-in?
if (!context.User.Identity.IsAuthenticated)
{
FormsAuthentication.RedirectToLoginPage();
return;
}
string requestedFile =
context.Server.MapPath(context.Request.FilePath);
// Verify the user has access to the User role.
if (context.User.IsInRole("User"))
{
SendContentTypeAndFile(context, requestedFile);
}
else
{
// Deny access, redirect to error page or back to login
//page.
context.Response.Redirect("~/User/AccessDenied.aspx");
}
break;
}
}
}
方法 SendContentTypeAndFile :
private HttpContext SendContentTypeAndFile(HttpContext context, String strFile)
{
context.Response.ContentType = GetContentType(strFile);
context.Response.TransmitFile(strFile);
context.Response.End();
return context;
}
private string GetContentType(string filename)
{
// used to set the encoding for the reponse stream
string res = null;
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
switch (fileinfo.Extension.Remove(0, 1).ToLower())
{
case "pdf":
{
res = "application/pdf";
break;
}
}
return res;
}
return null;
}
最后一步是你需要在webconfig中配置这个HTTP Handler, 并且您可以看到更多信息here
以下是完整的Source Code
答案 2 :(得分:0)
您的架构(和假设)似乎对低/中安全级别有好处,但如果您的数据性质非常敏感(医疗等),我对安全性的最大担忧就是控制用户会话。
如果您正在使用表单身份验证,那么您将经过身份验证的身份存储在Cookie或令牌中(或者如果您使用粘性会话,那么您将发送会话ID,但对于这种情况,它是相同的)。如果用户B具有对用户A工作的机器的物理访问,则会出现问题。如果用户A离开它的工作场所(一段时间或永远)并且他没有明确地关闭它在你的网络应用程序中的会话,那么他的身份就会被遗忘,至少在他的cookie /令牌到期之前,用户B可以使用它因为ASP.NET的身份系统没有执行SignOut。如果您使用令牌进行授权,问题会更严重,因为在身份系统的所有臭名昭着的Microsoft实现中,您负责提供一种方法来使这些令牌无效(并使用户退出时从客户端计算机中消失)因为它们会在到期之前保持有效。这可以解决(但对于高安全性要求并不完全如此不令人满意)发布短期生活刷新令牌,但这是另一个故事,我不知道这是否是你的情况。如果您使用cookie,那么当用户A签出时,它的cookie将被无效并从请求/响应中移除,因此可以减轻此问题。无论如何,您应该确保您的用户在您的网络应用中关闭他们的会话或/和配置短暂的生命或短暂的滑动过期的cookie。
其他安全问题可能与CSRF有关,你可以阻止使用ASP.NET的Antiforgery Token基础设施,但是这些攻击方法与专家用户相距甚远(我对此一无所知)您的用户的性质以及您的应用程序是否在互联网上公开,或者只能在Intranet上访问),但如果您担心此类专门攻击并且拥有如此敏感的数据,那么您可能应该使用比表单身份验证更复杂的内容(两个因素,生物统计等)