通过模拟打开网络文件 [英] Open network file with impersonation

查看:64
本文介绍了通过模拟打开网络文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已成功模拟网络帐户并访问我的网络应用程序中的网络共享。我需要做的是允许用户选择一个可用文件并为它们弹出 - 或者理想情况下,使用标准的打开对话框来允许它们打开或保存文件。当我将Response.Write与文件路径一起使用时,它可以在我的机器上运行,因为我已经映射了该共享路径。它不适用于未映射共享的其他客户端计算机。我可以访问服务器上的文件并向用户提供列表,但如何将文件提供给客户端?是否有一个简单的Response.Write替代方法,或者我是否必须转到另一条路径(例如将文件复制到我的应用程序路径并打开副本)?

解决方案

你混淆了,你混合的东西。

让我们说,你正在建立一个网络应用程序,涉及至少两方:一个客户端,一个Web浏览器和一个Web服务器 - 我们假设你正在使用IIS。据我所知,你有第三方:文件服务器。

现在,您可以设置IIS,模拟运行客户端浏览器的用户(使用NTLM或基本身份验证 - 具体情况取决于您所在的Windows网络)。但是模拟允许工作线程仅访问Web服务器上的本地资源,但不允许它访问第三方服务器(文件服务器)上的资源(文件)。要做到这一点,你需要委托(详见差异: http://msdn.microsoft.com/en -us / library / ff647248.aspx [ ^ ])。但NTLM不支持这一点,基本身份验证也不能默认为您提供此功能。

您有几个获得令牌( http:// msdn。 microsoft.com/en-us/library/ff647404.aspx#paght000023_delegation [ ^ ]):

  • 使用Kerberos身份验证和委派。 如果使用Kerberos对用户进行身份验证,则可以使用模拟原始呼叫者和暂时模拟原始呼叫者部分中描述的技术模拟原始呼叫者,并使用Kerberos委派来获取对网络的访问权限资源。为此:

    如果您的应用程序在网络服务帐户下运行,则需要在Active Directory中配置您的计算机帐户以进行委派信任。

    如果您的应用程序运行在自定义域帐户下,您需要将Active Directory中的域帐户配置为受信任以进行委派。您还必须在Active Directory中注册服务主体名称,以将域帐户与Web服务器上的HTTP服务相关联。

    如果使用域帐户运行Web应用程序或下游服务访问时,还必须确保在Active Directory中为这些帐户创建适当的服务主体名称(SPN)。
  • 调用LogonUser并请求交互式登录会话。交互式登录会话具有允许您对网络服务器进行身份验证的网络凭据。如果无法使用Kerberos身份验证对用户进行身份验证,并且无法使用协议转换,请使用此方法。

    请注意,您必须同时访问用户名和密码才能调用LogonUser。您只能使用令牌通过单跳访问网络资源,而Kerberos委派允许模拟身份跨多个层流。
  • 使用协议转换。使用此方法,您可以使用非Kerberos身份验证机制对用户进行身份验证,然后使用新的WindowsIdentity构造函数为服务器上的用户获取Windows令牌。如果无法使用Kerberos身份验证对用户进行身份验证,请使用此方法,例如,因为他们通过Internet连接到您的应用程序,但您的用户确实拥有Windows域帐户。要使用此方法获取委托级令牌,您必须在Windows 2003域中的Windows Server 2003上运行,并且需要将Active Directory中的计算机或进程帐户配置为受信任的委派和协议转换。
  • 使用基本身份验证和模拟。 使用基本身份验证,用户的用户名和密码在服务器上以明文形式提供。当IIS使用基本身份验证对调用方进行身份验证时,它会创建包含这些凭据的令牌。令牌可用于网络访问。因此,如果您将应用程序配置为使用< identity>模拟原始调用方。通过使用WindowsIdentity.Impersonate以编程方式进行元素或模拟,您可以在模拟时访问网络资源。

    如果您不能使用Kerberos身份验证和委派,则使用基本身份验证,并且您无法使用LogonUser或协议转换。例如,如果您将IIS配置为使用集成Windows身份验证,则它将尽可能使用Kerberos身份验证,但默认为NTLM身份验证 - 这不允许访问具有模拟身份的网络资源。如果由于未在Windows 2003域中的Windows Server 2003上运行而无法使用新的WindowsIdentity构造函数,并且您无法访问用户密码来调用LogonUser,则基本身份验证可提供解决方案。但是,使用基本身份验证时,用户的凭据将以明文形式通过网络。因此,您应该确保所有网络连接都使用SSL或IPSEC保护。


结束于此:

< pre lang =vb> Dim userpass()作为 String = My.Settings.FileAccessUP.Split(
使用 impUser 作为 System.Security.Principal.WindowsImpersonationContext = LocalUtilities.impersonateValidUser(userpass( 0 ),userpass( 1 ))
Dim endResponse as Boolean
尝试
如果 lbFiles.SelectedValue IsNot Nothing 然后
Dim b()作为 字节
使用 fs As IO.FileStream = IO.File.OpenRead(lbFiles.SelectedValue)
ReDim b(fs.Length - 1
fs.Read(b, 0 ,b.Length)
结束 使用

Response.AddHeader( Content-Type application / pdf
Response.AddHeader( Content-Disposition attachment; filename = Report.pdf
Response.OutputStream.Write(b, 0 ,b .Length)' 这个工作
' Response.BinaryWrite(b)'和这个工作
' Response.TransmitFile(lbFiles.SelectedValue.Replace(\,\\))'这在本地工作,但在服务器上由于某种原因得到句柄无效错误
endResponse = True ' 需要这个,或PDF已损坏
结束 如果
Catch ex As 异常
投掷
最后
LocalUtilities.undoImpersonation(impUser)
结束 尝试
如果 endResponse 然后响应。结束()
结束 使用


我们在其中一个解决方案中实现了这一点。也许你的情况类似,所以想要交叉检查。



我们有一个网络应用程序,需要识别其用户,所以我们打开了Windows身份验证。但是,用户需要在网络共享上获取理想密码保护的文件。现在,您无法对共享上的Everyone提供读取权限(根据企业安全性的要求)。理想情况下,您将获得一个服务帐户授予对此网络共享的读访问权限,以及一些具有写访问权限的管理员用户进行修改。



解决方案1:使用COM Interop和LogOnUser / LogOnUserA用于模拟File-Get请求的服务帐户的API。

这会将程序集标记为COMVisible并具有其他含义。此外,代码非常复杂且调试密集。



解决方案2:创建一个单独的Web服务,该服务在服务帐户的上下文中运行。此Web服务可以是ASMX或WCF。 web服务将接受FileID(存储在某个数据库中以识别每个文件)并执行读取操作,返回文本(File.ReadAllLines)或实际流(WCF transferMode = Streaming)

好​​东西是这是所有.NET,没有COM问题,因此易于理解和维护。你可以在其他一些应用程序中使用它。



我为我的情况选择了第二个,并希望它也适合你。 :)

I'm successfully impersonating a network account and accessing a network share in my web application. What I need to do is allow the user to select one of the available files and pop it open for them--or ideally, use the standard open dialog to allow them to open or save the file. When I use Response.Write with the filepath, it works on my machine, because I have that share path mapped. It does not work on a different client machine where the share is not mapped. I can access the files on the server and provide a list to the users, but how do I get the files to the client? Is there a simple alternative to Response.Write, or do I have to go another route (like copying to file into my application path and opening the copy)?

解决方案

You confused, you are mixing thing.
Let's state, that you are building a web application, that involves at lest two parties: a client, that is a web browser and a web server - let's assume you are using IIS. As I understood, you have a third party: a file server.
Now, you can set up IIS, to impersonate the user running the client browser (using NTLM or basic authentication - the exact scenario depends on the windows network you are in). But impersonation allows the working thread to access only local resources on the web server, but does not allow it to access resources (files) on the third party server (file server). To do that you need delegation (see the differences in detail: http://msdn.microsoft.com/en-us/library/ff647248.aspx[^]). But NTLM is not supporting this, neither is Basic authentication capable of giving you this by default.
You have several to get a token (http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_delegation[^]):
  • Use Kerberos authentication and delegation. If you use Kerberos to authenticate your users, you can impersonate the original caller by using the techniques described in the sections "Impersonating the Original Caller" and "Impersonating the Original Caller Temporarily" and use Kerberos delegation to gain access to network resources. To do so:
    If your application runs under the Network Service account, you need to configure your computer account in Active Directory to be trusted for delegation.
    If your application runs under a custom domain account, you need to configure your domain account in Active Directory to be trusted for delegation. You must also register a service principal name in Active Directory to associate the domain account with the HTTP service on your Web server.
    If you use domain accounts to run your Web application or the downstream service that you are accessing, you must also ensure that appropriate service principal names (SPNs) are created in Active Directory for those accounts.
  • Call LogonUser and request an Interactive logon session. An interactive logon session has network credentials that allow you to authenticate against network servers. Use this approach when you cannot use Kerberos authentication to authenticate your users, and when you cannot use protocol transition.
    Note that you must have access to both the user name and password to call LogonUser. You can only use the token to access network resources over a single hop, whereas Kerberos delegation allows the impersonated identity to flow across multiple tiers.
  • Use protocol transition. With this approach, you use a non-Kerberos authentication mechanism to authenticate your users, and then use the new WindowsIdentity constructor to obtain a Windows token for the user on the server. Use this approach when you cannot use Kerberos authentication to authenticate your users, for example because they connect to your application over the Internet, but your users do have Windows domain accounts. To get a delegate-level token with this approach, you must be running on a Windows Server 2003 in a Windows 2003 domain and you need to configure your computer or process account in Active Directory as trusted for delegation and protocol transition.
  • Use basic authentication and impersonation. With basic authentication, the user name and password of the user are available in clear text on the server. When IIS authenticates a caller by using basic authentication, it creates a token that contains these credentials. The token can be used for network access. As result, if you configure your application to impersonate the original caller by using the <identity> element or impersonate programmatically by using WindowsIdentity.Impersonate, you can access network resources while impersonating.
    Use basic authentication if you cannot use Kerberos authentication and delegation, and you cannot use LogonUser or protocol transition. For example, if you configure IIS to use integrated Windows authentication, it will use Kerberos authentication if possible, but otherwise default to NTLM authentication—which does not allow access to network resources with an impersonated identity. If you cannot use the new WindowsIdentity constructor because you are not running on a Windows Server 2003 in a Windows 2003 domain, and you do not have access to the users password to call LogonUser, then basic authentication provides a solution. However, with basic authentication, the user's credentials pass through the network in clear text. Therefore, you should be sure that all network connections are secured with SSL or IPSEC.


Ended up with this:

Dim userpass() As String = My.Settings.FileAccessUP.Split("~")
Using impUser As System.Security.Principal.WindowsImpersonationContext = LocalUtilities.impersonateValidUser(userpass(0), userpass(1))
    Dim endResponse as Boolean
    Try
        If lbFiles.SelectedValue IsNot Nothing Then
            Dim b() As Byte
            Using fs As IO.FileStream = IO.File.OpenRead(lbFiles.SelectedValue)
                ReDim b(fs.Length - 1)
                fs.Read(b, 0, b.Length)
            End Using

            Response.AddHeader("Content-Type", "application/pdf")
            Response.AddHeader("Content-Disposition", "attachment;filename=Report.pdf")
            Response.OutputStream.Write(b, 0, b.Length)  'this works
            'Response.BinaryWrite(b)  'and this works
            'Response.TransmitFile(lbFiles.SelectedValue.Replace("\", "\\"))  'this works locally, but on the server gets a "handle is invalid" error for some reason
            endResponse = True  'need this, or PDF is corrupt
        End If
    Catch ex As Exception
        Throw
    Finally
        LocalUtilities.undoImpersonation(impUser)
    End Try
    If endResponse Then Response.End()
End Using


We have implemented this in one of our solutions. Maybe your situation is similar so want to cross check.

We have a web-app which needs to identify its users, so we have windows authentication turned on. However users will need to get files on a network share which is ideally password protected. Now you cannot give read access to 'Everyone' on the share (as required by enterprise security). Ideally you will have a Service Account granted read access to this network share and some admin user having Write access for modification.

Solution 1: Use COM Interop and LogOnUser/LogOnUserA APIs to impersonate the service account for the File-Get request.
This will mark the assembly as COMVisible and have other implications. Also the code is quite complicated and debugging intensive.

Solution 2: Create a separate webservice which runs under the context of the service account. This webservice can be either ASMX or WCF. The webservice will take in the FileID (stored in some database to identify each file) and perform read operations, returning either text (File.ReadAllLines) or actual Stream (WCF transferMode=Streaming)
Good thing is that this is all .NET and no COM issues, hence easily understandable and maintainable. And you can use this in some other application as well.

I chose the second one for my case and hope it works out for you as well. :)


这篇关于通过模拟打开网络文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆