简体   繁体   English

用户通过身份验证后,文件上传失败。 使用IIS7集成模式

[英]File upload fails when user is authenticated. Using IIS7 Integrated mode

These are the user identities my website tells me that it uses: 这些是我的网站告诉我的用户身份,它使用:

Logged on: NT AUTHORITY\\NETWORK SERVICE (Can not write any files at all) 登录: NT AUTHORITY \\ NETWORK SERVICE (完全无法写入任何文件)
and
Not logged on: WSW32\\IUSR_77 (Can write files to any folder) 未登录: WSW32 \\ IUSR_77 (可以将文件写入任何文件夹)

I have a ASP.NET 4.0 website on a shared hosting IIS7 web server running in Integrated mode with 32-bit applications support enabled and MSSQL 2008. Using classic mode is not an option since I need to secure some static files and I use Routing. 我在共享主机IIS7 Web服务器上有一个ASP.NET 4.0网站,该服务器以集成模式运行,并启用了32位应用程序支持并支持MSSQL2008。使用经典模式不是一种选择,因为我需要保护一些静态文件并且使用路由。

In my web.config file I have set the following: 在我的web.config文件中,进行了以下设置:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

My hosting company says that Impersonation is enabled by default on machine level, so this is not something I can change. 我的托管公司说,默认情况下,在计算机级别启用了模拟功能,因此我无法更改。

I asked their support and they referred me to this article: http://www.codinghub.net/2010/08/differences-between-integrated-mode-and.html 我请求他们的支持,他们向我推荐了这篇文章: http : //www.codinghub.net/2010/08/differences-between-integrated-mode-and.html

Citing this part: 引用此部分:

Different windows identity in Forms authentication 表单身份验证中的不同Windows身份

When Forms Authentication is used by an application and anonymous access is allowed, the Integrated mode identity differs from the Classic mode identity in the following ways: 当应用程序使用表单身份验证并允许匿名访问时,集成模式身份与经典模式身份在以下方面有所不同:

 * ServerVariables["LOGON_USER"] is filled. * Request.LogognUserIdentity uses the credentials of the [NT AUTHORITY\\NETWORK SERVICE] account instead of the [NT AUTHORITY\\INTERNET USER] account. 

This behavior occurs because authentication is performed in a single stage in Integrated mode. 出现此现象的原因在于身份验证是在集成模式下的单个阶段中执行的。 Conversely, in Classic mode, authentication occurs first with IIS 7.0 using anonymous access, and then with ASP.NET using Forms authentication. 相反,在经典模式下,首先使用匿名访问的IIS 7.0进行身份验证,然后使用窗体身份验证的ASP.NET进行身份验证。 Thus, the result of the authentication is always a single user-- the Forms authentication user. 因此,身份验证的结果始终是一个用户-Forms身份验证用户。 AUTH_USER/LOGON_USER returns this same user because the Forms authentication user credentials are synchronized between IIS 7.0 and ASP.NET. AUTH_USER / LOGON_USER返回同一用户,因为Forms身份验证用户凭据在IIS 7.0和ASP.NET之间同步。

A side effect is that LOGON_USER, HttpRequest.LogonUserIdentity, and impersonation no longer can access the Anonymous user credentials that IIS 7.0 would have authenticated by using Classic mode. 副作用是LOGON_USER,HttpRequest.LogonUserIdentity和模拟不再可以访问IIS 7.0通过使用经典模式已通过身份验证的匿名用户凭据。

How do I set up my website so that it can use the proper identity with the proper permissions? 如何设置我的网站,以便它可以使用具有适当权限的适当身份?

I've looked high and low for any answers regarding this specific problem, but found nil so far... 我一直在寻找有关此特定问题的任何答案,但到目前为止却没有发现...

I hope you can help! 希望您能提供帮助!

[ Bump ] [ 凹凸 ]

So I finally found a solution to my problem. 因此,我终于找到了解决问题的方法。

Using this KB article "How to implement impersonation in an ASP.NET application / Impersonate a Specific User in Code" I found a way to impersonate my shared hosting FTP user . 通过使用这篇知识库文章“如何在ASP.NET应用程序中实现模拟/用代码模拟特定用户”,我找到了一种模拟共享的托管FTP用户的方法

This way I would gain the privileges of the said user and not compromise the security of the server by lowering the security on the NT AUTHORITY\\NETWORK SERVICE user. 这样,我将获得所述用户的特权,而不会通过降低NT AUTHORITY \\ NETWORK SERVICE用户的安全性来损害服务器的安全性。

This is the code that I used: 这是我使用的代码:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Configuration;

namespace App_Code
{
    public class Impersonation : IDisposable
    {
        private WindowsImpersonationContext _impersonationContext;

        #region Win32 API Declarations
        private const int Logon32LogonInteractive = 2; //This parameter causes LogonUser to create a primary token.
        private const int Logon32ProviderDefault = 0;

        [DllImport("advapi32.dll")]
        private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(IntPtr handle);
        #endregion

        public bool ImpersonateDefaultFtpUser()
        {
            return ImpersonateFtpUser(ConfigurationManager.AppSettings["ftpUsername"], ConfigurationManager.AppSettings["ftpDomain"], ConfigurationManager.AppSettings["ftpPassword"]);
        }

        public bool ImpersonateFtpUser(string userName, string domain, string password)
        {
            WindowsIdentity tempWindowsIdentity;
            var token = IntPtr.Zero;
            var tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, Logon32LogonInteractive, Logon32ProviderDefault, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        _impersonationContext = tempWindowsIdentity.Impersonate();

                        if (_impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }

            if (token != IntPtr.Zero)
                CloseHandle(token);

            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);

            return false;
        }

        public void UndoImpersonation()
        {
            if (_impersonationContext != null)
                _impersonationContext.Undo();
        }

        /// <summary>
        /// Constructor. Impersonates the default ftp user. Impersonation lasts until
        /// the instance is disposed.
        /// </summary>
        public Impersonation()
        {
            ImpersonateDefaultFtpUser();
        }

        /// <summary>
        /// Constructor. Impersonates the requested user. Impersonation lasts until
        /// the instance is disposed.
        /// </summary>
        public Impersonation(string userName, string domain, string password)
        {
            ImpersonateFtpUser(userName, domain, password);
        }

        #region IDisposable Pattern

        /// <summary>
        /// Revert to original user and cleanup.
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing) return;

            // Revert to original user identity
            UndoImpersonation();

            if (_impersonationContext != null)
                _impersonationContext.Dispose();
        }

        /// <summary>
        /// Explicit dispose.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Destructor
        /// </summary>
        ~Impersonation()
        {
            Dispose(false);
        }

        #endregion
    }
}

您可以授予用户Networkservice对有关目录的写权限吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM