如何的WindowsIdentity转换为的NetworkCredential? [英] How to convert WindowsIdentity to a NetworkCredential?

查看:264
本文介绍了如何的WindowsIdentity转换为的NetworkCredential?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们如何将一个的WindowsIdentity 的NetworkCredential ?我测试我的WCF服务,以验证匿名来电者将被阻止。要做到这一点,我想做的事情是这样的:

How do we convert a WindowsIdentity to a NetworkCredential? I am testing my WCF service to verify that anonymous callers are blocked. To do this I want to do something like:

myProxy.ClientCredentials.Windows.ClientCredential = foo(WindowsIdentity.GetAnonymous());

其中,是一个能转换的WindowsIdentity 的NetworkCredential

推荐答案

回答我的问题:
这是不可能的转换的WindowsIdentity 的NetworkCredential 。为了测试是否匿名来电者被阻挡,冒充当前线程与href="http://www.nullsession.net/2009/what-is-a-null-session/" rel="nofollow">空会话令牌的,然后进行调用WCF服务。注:请不要使用<一个href="http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.getanonymous.aspx"相对=nofollow> WindowsIdentity.GetAnonymous 。这种方法是没有用的(想这是不正确的实施,从来没有得到纠正)。 code冒充当前线程与空会话令牌(没有错误处理完成后):

Answering my own question:
It is not possible to convert a WindowsIdentity to a NetworkCredential. To test if anonymous callers are blocked, impersonate current thread with a null session token, and then make call to WCF service. Note: do not use WindowsIdentity.GetAnonymous. This method is useless (guess it was incorrectly implemented, and never been corrected). Code to impersonate current thread with null session token (no error handling is done):

    public static class Helper
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        private static extern IntPtr GetCurrentThread();

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        private static extern bool ImpersonateAnonymousToken(IntPtr handle);

        public static void ImpersonateAnonymousUser()
        {            
            ImpersonateAnonymousToken(GetCurrentThread());
        }
    }

        static string ToString(IIdentity identity)
        {
            return string.Format("{0} {1} {2}", identity.Name, identity.IsAuthenticated, identity.AuthenticationType); 
        }

        static void Main(string[] args)
        {            
            Console.WriteLine(ToString(WindowsIdentity.GetCurrent()));
            Helper.ImpersonateAnonymousUser();
            Console.WriteLine(ToString(WindowsIdentity.GetCurrent()));
        }

输出:

my machine\me True NTLM
NT AUTHORITY\ANONYMOUS LOGON False

在应对埃德蒙的意见,制定 proxy.ClientCredentials.Windows.ClientCredential 不会做什么缩进 - 使请求作为匿名用户。这是我的完整的测试code和它的输出:

In response to Edmund's comment, setting proxy.ClientCredentials.Windows.ClientCredential to null will not do what is indented - make request as an anonymous user. Here is my complete test code and its output:

服务code:

public class Service1 : IService1
    {
        // note that if client is not authenticated, this code will never get a chance to execute
        // exception will happen before that
        // therefore there is no need to decorate this method with a
        // [PrincipalPermission(SecurityAction.Demand, Authenticated=true)] attribute        
        public string GetData()
        {
            try
            {
                var identity = Thread.CurrentPrincipal.Identity;
                return string.Concat(identity.Name, ",", identity.IsAuthenticated, ",", identity.AuthenticationType);
            }
            catch (Exception e)
            {
                return string.Concat(e.Message, "\\r\\n", e.StackTrace);
            }
        }
    }

服务配置:

<services>      
      <service name="WcfService1.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="http://mymachine/Service1/" />            
          </baseAddresses>                    
        </host>
        <endpoint address="Service1"
                  binding ="customBinding"
                  bindingConfiguration="myHttpBinding"
                  contract="WcfService1.IService1">          
        </endpoint>          
      </service>
    </services>
    <bindings>      
      <customBinding>
        <binding name="myHttpBinding">
            <reliableSession/>          
            <binaryMessageEncoding />          
            <httpTransport maxBufferSize="2147483647"
                           maxReceivedMessageSize="2147483647"
                           authenticationScheme="IntegratedWindowsAuthentication" />
          </binding>
      </customBinding>
    </bindings>

客户端code:

Client code:

static void MakeRequest()
        {
            try
            {
                using (var svc = new Service1Client())
                {
                    Console.WriteLine(svc.GetData());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        }

        static void Test3()
        {            
            Console.WriteLine("using {0}", ToString(WindowsIdentity.GetCurrent()));
            MakeRequest();
            Console.WriteLine();

            Console.WriteLine("setting svc.ClientCredentials.Windows.ClientCredential to null...");
            try
            {
                using (var svc = new Service1Client())
                {
                    svc.ClientCredentials.Windows.ClientCredential = null; 
                    Console.WriteLine(svc.GetData());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
            Console.WriteLine();

            ImpersonateAnonymousUser();
            Console.WriteLine("using {0}", ToString(WindowsIdentity.GetCurrent()));
            MakeRequest();
            Console.WriteLine();
        }

客户端配置:

Client config:

<bindings>
            <customBinding>
                <binding name="CustomBinding_IService1">
                    <reliableSession />
                    <binaryMessageEncoding />
                    <httpTransport authenticationScheme="Negotiate" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="mymachine/Service1/Service1.svc/Service1"
                binding="customBinding" bindingConfiguration="CustomBinding_IService1"
                contract="ServiceReference1.IService1" name="CustomBinding_IService1">
                <identity>
                    <servicePrincipalName value="host/mymachine" />
                </identity>
            </endpoint>
        </client>
      <behaviors>
        <endpointBehaviors>
          <!-- this setting protects the client by prohibiting the service to assume identity of client
          via imperonation and/or delegation and then doing bad things -->
          <behavior name="ImpersonationBehavior">
            <clientCredentials>
              <windows allowedImpersonationLevel="Identification"/>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>

输出:

using mymachine\me True Negotiate
mymachine\me,True,Negotiate

setting svc.ClientCredentials.Windows.ClientCredential to null...
mymachine\me,True,Negotiate

using NT AUTHORITY\ANONYMOUS LOGON False
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be
 used for communication because it is in the Faulted state.

Server stack trace:
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta, Int32 type)
   at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.
Close(TimeSpan timeout)
   at System.ServiceModel.ClientBase`1.Close()
   at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()
   at TestClient.Program.MakeRequest()

这篇关于如何的WindowsIdentity转换为的NetworkCredential?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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