如何从代码中模拟Web服务文件(asmx)?

时间:2010-01-27 13:07:31

标签: c# web-services impersonation

直到最近,我在web.config中使用了"<impersonate >"标记,然后是正确的凭据。

现在我正在尝试添加另一个asmx文件,该文件将模拟其他帐户,并尝试通过代码执行此操作。

问题是 -

如何从asmx文件(webservice)中的代码模拟(在每个请求中)? (我正在使用C#)

我想代码应该在asmx类的ctor中,但我不确定它应该是什么。 我通过很多例子搜索过,但没有找到一个能够满足我想要的代码。

提前谢谢!

2 个答案:

答案 0 :(得分:0)

如果您在web.config中将模拟设置为ON,则可以通过以下方式指定其他凭据:

new System.Net.NetworkCredential("username", "password", "domain");

我还找到了一篇好文章How to impersonate a user given her token 它显示了如何将不同的WindowsIdentity附加到给定的线程

答案 1 :(得分:0)

请参阅示例代码,了解如何执行此操作:

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

[assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
        String lpszUsername, 
        String lpszDomain, 
        String lpszPassword, 
        int dwLogonType, 
        int dwLogonProvider,
        ref IntPtr phToken);

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

    // Test harness.
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        IntPtr tokenHandle = new IntPtr(0);
        try
        {
            string userName, domainName;
            // Get the user token for the specified user, domain, and password using the 
            // unmanaged LogonUser method.  
            // The local machine name can be used for the domain name to impersonate a user on this machine.
            Console.Write("Enter the name of the domain on which to log on: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            tokenHandle = IntPtr.Zero;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(
                userName, 
                domainName, 
                Console.ReadLine(),
                3,
                LOGON32_PROVIDER_DEFAULT,
                ref tokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }

            Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
            Console.WriteLine("Value of Windows NT token: " + tokenHandle);

            // Check the identity.
            Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
            // Use the token handle returned by LogonUser.

            WindowsIdentity newId = new WindowsIdentity(tokenHandle);

            using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
            {
                // Check the identity. Here you shoul place code that will be executed on belaf of other login.
                Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
                GC.KeepAlive(impersonatedUser);
            }

            // Check the identity.
            Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);

            // Free the tokens.
            if (tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }

    }
}