windows - 带有 Windows 身份验证的 WCF 服务不会拒绝不受信任的用户
问题描述
我正在 WPF 应用程序和 Windows 服务 throw WCF 之间开发“自动连接”模式。我想只允许受信任的域用户连接到特定的 WCF 服务,而不需要 Windows 凭据(用户已经登录了他的 Windows 会话)。该服务接下来会将用户登录到应用程序。
我创建了一个 WCF 服务,其安全模式为 «Transport»,Transport.ClientCredentialType 为 «Windows»(客户端和服务器上的绑定相同)。在同一应用程序中运行其他 WCF 服务,安全模式设置为“无”。
当我在 LocalService 帐户下的域机器上运行 windows 服务,并在域用户帐户下的另一台机器上运行客户端时,我可以在 OperationContext 对象中获取服务器端的用户 Windows 身份 « DOMAIN\user »。我看到使用了 Kerberos,并且我认为存在某种模拟,这没关系。
但是,当我在不知道域用户的工作组机器(域外)上运行 Windows 服务时,OperationContext WindowsIdentity 设置为« MACHINE_NAME\Administrator »(在服务器上创建的本地会话)。服务调用没有错误,也没有异常,我不知道为什么。WindowsIdentity 对象的 IsAuthenticated 属性始终设置为 true。
我已经用“消息”的安全模式进行了测试。
我想知道是否有可能告诉 WCF 拒绝所有未经真正身份验证的连接?
更新:这里有一些可能有帮助的信息:
- 客户端应用程序是 WPF 应用程序
- Server 是一个经典的 Windows 服务,运行在 LOCAL SERVICE 下
- 绑定是 net.tcp
- 客户端代理类是通过 svcutil.exe 生成的
- 一切由代码完成,无需配置文件
- 下面是创建 ServiceClient 的代码:
public static TClient Create<TClient, TChannel>(params IContractBehavior[] behaviors)
where TChannel : class
where TClient : ClientBase<TChannel>
{
var typeOfClient = typeof(TClient);
var ctor = typeOfClient.GetConstructor(new[] { _bindingType, _endpointAddressType });
if (ctor == null)
{
throw new Exception($"{typeOfClient} has no constructor taking 2 parameters ({_bindingType},{_endpointAddressType})");
}
var address = getClientBaseEndPointAddress(typeof(TChannel));
var binding = getBinding<TClient>(address.Uri.Scheme);
var clt = (TClient)ctor.Invoke(new object[] { binding, address });
foreach (var behavior in behaviors)
{
clt.ChannelFactory.Endpoint.Contract.Behaviors.Add(behavior);
}
manageDataContractResolver<TClient, TChannel>(clt);
clt.setOperationTimeout(binding.SendTimeout);
return clt;
}
- getBinding 方法由客户端和服务器应用程序共享:
var ret = new NetTcpBinding
{
MaxBufferSize = bc.MessageSize,
MaxBufferPoolSize = bc.MessageSize,
...
};
// Secured or not
if (secured)
{
ret.Name = "Default_Secured_Binding";
ret.Security.Mode = SecurityMode.Transport;
ret.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
}
else
{
ret.Security.Mode = SecurityMode.None;
ret.Name = "Default_Binding";
}
- 据此:Understanding WCF Windows Authentication or this The server has denied the client credentials, WCF as Windows Service
我认为 WCF 会拒绝任何未经完全身份验证的请求,但我无法收到任何“身份验证错误”。
如果您需要更多信息,请与我们联系。
解决方案
如果客户端没有提供windows凭据作为客户端windows凭据,则将使用当前计算机用户的凭据进行身份验证。认证的条件是这个凭证可以登录到服务器(windows用户)
客户端如何调用服务、客户端代理类或ChannelFactory?这是在客户端设置凭据的方法。
ServiceReference2.Service1Client client = new ServiceReference2.Service1Client();
//if we don't set up this, The computer user credentials that are currently running the program will be sent to the server.
client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
client.ClientCredentials.Windows.ClientCredential.Password = "123456";
前提是服务器端配置如下,
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding">
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="mybinding">
<security mode="Transport">
<transport clientCredentialType="Windows"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
请发布您完整的服务器配置和客户端配置(system.servicecmodel部分)以供调用,我会尝试定位问题。
如果有什么我可以帮忙的,请随时告诉我。
推荐阅读
- c - 在 C 中传递可变数量参数的更紧凑的方法
- java - 如何从java执行R脚本文件
- javascript - 首次提交表单时为空值
- python - 未找到带有参数 '('cars',)' 的 'product_list' 的反向
- javascript - Intellisense 和自动完成功能在 Visual Studio 代码中不起作用
- forms - 单击选项卡时如何在 TabbedPage 中加载数据?
- php - 如何做出更快的搜索结果?
- sql - 如何使用 sql 查询获取输出列
- python - 当模块名称与包名称相同时,为什么 doctest 不起作用?
- abap - ALV 网格未刷新