Reputation: 910
I have a WCF service which uses Windows Authentication to view Service Contract and a specfic method in a service is configured to be accessed only by a specific user UserX.
[PrincipalPermission(SecurityAction.Demand,Name="xxx\\UserA")]
In the client side, I need to access the above service method. If I am using a Web Reference -> I add the following
client = new WebRefLocal.Service1();
client.Credentials = new System.Net.NetworkCredential("UserA", "xxxxxx", "test");
But the above cannot be achieved in WCF Service Reference as Client Credentials are read-only. One best way I can achieve the above is Impersonation https://msdn.microsoft.com/en-us/library/ff649252.aspx.
My question here is
Upvotes: 2
Views: 6003
Reputation: 3239
I've done something like this - hope it helps:
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);
Used with a BasicHttpBinding
with following security settings:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
Upvotes: 2
Reputation: 2530
One method you can use is to make use of ChannelFactory
when calling the WCF service.
The following code was taken from one of my MVCprojects, hence it has some
ModelState` validation code, I'm sure you can modify it to suit your needs.
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;
}
Upvotes: 0