如何的WindowsIdentity转换为的NetworkCredential? [英] How to convert WindowsIdentity to a 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 $的方法C $ C>
推荐答案
回答我的问题:
这是不可能的转换的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屋!