We have a simple rest API exposed with Swagger UI. We usually copy-paste the raw definition to editor.swagger.io, and generate a C# client. The generated code works very well - but we work in a Windows AD environment, and we cannot find any way to tell the client to use the current user credentials during the communication. So the IIS hosted rest API throws Unauthorized exception - as it is set to Windows authentication mode.
Is it possible to use the generated client this way? Any option to add to the API definition to generate such a client?
Writing a client manually is easy:
var client = new WebClient();
client.UseDefaultCredentials = true;
...
but we would like to generate it ... but the Configuration contains nothing about credentials ... :(
public static IO.Swagger.Api.IBookingApi GetBookingApiWebApi()
{
var basePath = ConfigurationManager.AppSettings["web.api.url"];
var api = new BookingApi(basePath);
return api;
}
Thanks in advance...
I am hosting a soap webservice via an instance iHost of ServiceHost; authentication is configured as
HttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
iHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode
= UserNamePasswordValidationMode.Custom;
iHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator
= new CustomValidator();
The hosting itself works as desired, however I also would like to access the client credentials from within the hosted service itself. Can this be achieved with the current authentication settings or is it impossible?
Found the answer with the help of a coworker. Username can be accessed via OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name; the question can be seen as a duplicate of this question.
I'm trying to consume a web service provided by another group within our company. The service is written in Java and their JAVA test client functions properly. However, I cannot get a .NET4.0 or .NET 4.5 based WCF client to talk to it. They require https transport and since its JAVA I'm using basicHttpBinding. They also require Username/Password. In JAVA, they are saying the username/password is at the binding level and when looking at a message that was captured from their test code, there is NO evidence of the username or password being sent. I can connect to their service but cannot get authenticated because they are not seeing my username & password. Username and password is being set in code. I am currently testing against their dev server using their self signed cert. Our endpoints are physically 1500 miles apart but connect via internal corporate (secure) network.
I just need to know the proper config settings for "binding", "behavior", and "endpoint" to use at the client. I can post my settings but that would just be misleading as I've tried 100's of them and none give the desired result.
Any help you can give will be useful as long as it doesn't involve any changes on (or knowledge of) the service host side (its probably not even IIS).
Thanks for your thoughts.
Java client code looks like this:
ServiceImplServiceLocator locator = new ServiceImplServiceLocator();
locator.setServiceEndpointAddress( "https://<hostaddr>:8443/Service" );
locator.setServiceWSDDServiceName("Service");
ServiceImpl service = locator.getService();
ServiceSoapBindingStub binding = (ServiceSoapBindingStub) service;
binding.setUsername("Username");
binding.setPassword("Password");
// call web service
Return = binding.ServiceMethod( ... );
I have been given a wdsl for an external system (not .Net-based), and I have used svcutil to create a client/proxy for it. The external unit requires digest authentication for me to talk to it, and supports both http and https.
A couple of questions:
There are no certificates involved. Will using https cause problems in that case?
I know I can specify transport level digest authentication like this:
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
However, how do I go about creating the credentials and using them with my binding/proxy?
I can easily find a lot of information online on creating WCF services, but implementation of clients towards non-.Net based services... not so much.
Thanks for any insight!
i have some code that tries impersonate the callers windows security settings and then connect to another WCF service on a different machine
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
using (callerWindowsIdentity.Impersonate())
{
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
EndpointAddress endpoint = new EndpointAddress(new Uri("net.tcp://serverName:9990/TestService1"));
ChannelFactory<WCFTest.ConsoleHost.IService1> channel = new ChannelFactory<WCFTest.ConsoleHost.IService1>(binding, endpoint);
WCFTest.ConsoleHost.IService1 service = channel.CreateChannel();
return service.PrintMessage(msg);
}
But I get the error:
"the caller was not authenticated by the service"
System.ServiceModel .... The request for security token could not be satisfied because authentication failed ...
The credentials I am trying to impersonate are valide windows credential for the box the service is on.
Any ideas why?
In order to support your scenario, you need to have an understanding of how Protocol Transition and Constrained Delegation work. You will need to configure both Active Directory and your WCF service endpoint(s) to support this. Note the use of the Service Principal Name (SPN). Take a look at the following link and see if they help you. The article has a sample to demonstrate the complete end-to-end configuration required to make this work.
How To: Impersonate the Original Caller in WCF Calling from a Web Application
Agree with marc_s this is the double-hop problem.
You need to get the windows authentication all the way through, therefore:
The request must be made in the context of a windows users
IIS must be configured to use windows authentication
Web.config must be set up for windows authentication with impersonate = true
The user that your application pool is running as, must be allowed to impersonate a user. This is the usual place where the double-hop problem occurs.
There is a right called "Impersonate a client after authentication"
http://blogs.technet.com/askperf/archive/2007/10/16/wmi-troubleshooting-impersonation-rights.aspx
Impersonation from you service to the next is a tricky issue, known as "double-hop" issue.
I don't have a final answer for that (I typically avoid it by using an explicit service account for the service that needs to call another service).
BUT: you should definitely check out the WCF Security Guidance on CodePlex and search for "Impersonation" - there are quite a few articles there that explain all the ins and outs of impersonating an original caller and why it's tricky.
Marc
If you are sure you have the credentials right on both hops, the next thing that could be causing the issue is the lack of the EndpointDnsIdentity being set on the endpoint.
DnsEndpointIdentity identity = new DnsEndpointIdentity("localhost"); // localhost is default. Change if your service uses a different value in the service's config.
Uri uri = new Uri("net.tcp://serverName:9990/TestService1");
endpoint = new EndpointAddress(uri, identity, new AddressHeaderCollection());