我有一个WCF服务,它使用Windows身份验证来查看服务合同,并且服务中的特定方法配置为只能由特定用户UserX访问。
[PrincipalPermission(SecurityAction.Demand,Name="xxx\\UserA")]
在客户端,我需要访问上述服务方法。如果我使用的是Web参考 - >我添加以下
client = new WebRefLocal.Service1();
client.Credentials = new System.Net.NetworkCredential("UserA", "xxxxxx", "test");
但是在WCF服务参考中无法实现上述目的,因为客户端凭据是只读的。我可以实现上述目标的最佳方式是模拟 https://msdn.microsoft.com/en-us/library/ff649252.aspx。
我的问题是
答案 0 :(得分:2)
我做过类似的事情 - 希望有所帮助:
var credentials = new ClientCredentials();
credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;
credentials.Windows.ClientCredential = new System.Net.NetworkCredential("UserA", "xxxxxx", "test");
client.Endpoint.Behaviors.Remove<ClientCredentials>();
client.Endpoint.Behaviors.Add(credentials);
与BasicHttpBinding
一起使用,具有以下安全设置:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
答案 1 :(得分:1)
您可以使用的一种方法是在调用WCF服务时使用ChannelFactory
。
以下代码取自我的一个MVC projects, hence it has some
ModelState`验证码,我相信您可以根据自己的需要对其进行修改。
protected R ExecuteServiceMethod<I, R>(Func<I, R> serviceCall) {
R result = default(R);
ChannelFactory<I> factory = CreateChannelFactory<I>();
try {
I manager = factory.CreateChannel();
result = serviceCall.Invoke(manager);
} catch (FaultException<ValidationFaultException> faultException) {
faultException.Detail.ValidationErrors.ToList().ForEach(e => ModelState.AddModelError("", e));
} finally {
if (factory.State != CommunicationState.Faulted) factory.Close();
}
return result;
}
private ChannelFactory<I> CreateChannelFactory<I>() {
UserAuthentication user = GetCurrentUserAuthentication();
ChannelFactory<I> factory = new ChannelFactory<I>("Manager");
if (IsAuthenticated) {
factory.Credentials.UserName.UserName = user.UserName;
factory.Credentials.UserName.Password = user.Password;
}
BindingElementCollection elements = factory.Endpoint.Binding.CreateBindingElements();
factory.Endpoint.Binding = new CustomBinding(elements);
SetDataContractSerializerBehavior(factory.Endpoint.Contract);
return factory;
}