WCF service authentication using iisexpress transport security and basic authentication always returning 401 - wcf

I have a WCF service configured to use Transport security and basic authentication.
The service is hosted in iiexpress withing vs2010.
I am able to connect from my client code but always receive:
"The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm=realm'."
And this has an inner exception of:
"The remote server returned an error: (401) Unauthorized."
Similar to Can not call web service with basic authentication using WCF although my client code already has the settings set out in the answer.
I also followed HTTP Basic Authentication against Non-Windows Accounts in IIS/ASP.NET (Part 3 - Adding WCF Support) and the previous blog to set up a Module and the IAuthorizationPolicy classes.
IISExpress is configed in classic mode with anonymous and windows authentication disabled and SSL enabled.
Client Config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NotificationHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/NotificationService.svc"
binding="basicHttpBinding" bindingConfiguration="NotificationHttpBinding"
contract="NotificationPortType" name="BasicHttpBinding_NotificationPortType" />
</client>
</system.serviceModel>
Service Config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="Notification.NotificationService" behaviorConfiguration="NotificationServiceBehavior">
<endpoint binding="basicHttpBinding" contract="NotificationPortType" bindingConfiguration="NotificationHttpBinding" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="NotificationServiceBehavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceAuthorization>
<authorizationPolicies>
<add policyType="Notification.HttpContextIdentityPolicy, Notification" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="NotificationHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.web>
<httpModules>
<add name="CustomBasicAuthentication" type="Notification.CustomBasicAuthenticationModule, Notification"/>
</httpModules>
<membership defaultProvider="SampleProvider">
<providers>
<add name="SampleProvider" type="Notification.HardcodedSecurityProviders, Notification" />
</providers>
</membership>
</system.web>
Client Code is nothing major:
static void Main(string[] args)
{
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; };
NotificationPortTypeClient client = new NotificationPortTypeClient("BasicHttpBinding_NotificationPortType");
client.ClientCredentials.UserName.UserName = "Test";
client.ClientCredentials.UserName.Password = "PWD";
client.sendNotification(new NotificationRequest());
}
Alternatively
If someone can show me an alternative of how to use IIS6 to host a service WCF which using basic http authentication while requiring SSL (https) I'll be happy with that!
UPDATE
Seems this was my culprit all along:
Avoid http 401 round trip
However, I found that my modules fired fine (in integrated mode) but I was then presented with a service error telling me that basic integration is required but not enabled on the host.
Opened up iisexpress applicationhost.config file and sure enough I found:
<section name="basicAuthentication" overrideModeDefault="Deny" />
followed by
<basicAuthentication enabled="false" />
further down
I've changed these to <section name="basicAuthentication" overrideModeDefault="Allow" />
and tried to enable in my web.config...no dice :(

You need to use WSHttpBinding.
There is a complete sample here.

Related

XAMARIN, WCF with Custom User Name/Password and Principal

I am developing a WCF service that will provide data to a Xamarin client. I am trying to utilize custom user name/password and custom principle so I can attach usable information for the service to the identity. After many tries I have not been able to get anything but different error messages on the client. I believe the problem is in the WCF configuration, but I can not figure out what the problem is. My web.config code is below. Any help or tips on where to go would be greatly appreciated!
<system.serviceModel>
<diagnostics wmiProviderEnabled="true">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxSizeOfMessageToLog="65535000"
maxMessagesToLog="3000"
/>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior name="Behavior">
<!-- To avoid disclosing metadata information, set the values below
to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="Cert" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName"/>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Service.ServiceAuthenticator,
Service"/>
</serviceCredentials>
<serviceAuthorization
serviceAuthorizationManagerType="Service.CustomAuthorizationManager,
Service" principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="Service.AuthorizationPolicy, Service"/>
</authorizationPolicies>
</serviceAuthorization>
<serviceSecurityAudit
auditLogLocation="Application"
serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="Failure"
suppressAuditFailure="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service" behaviorConfiguration="Behavior">
<endpoint address="" binding="basicHttpBinding"
contract="Service.IService" bindingConfiguration="Secure"/>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="Secure">
<security mode="Transport">
<transport clientCredentialType="Basic"
proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName"
algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value
below to true.
Set to false before deployment to avoid disclosing web app folder
information.
-->
<directoryBrowse enabled="true"/>
<httpErrors errorMode="Detailed" />
</system.webServer>
I'm using the WFC service as a connected service in the main project of the Xamarin solution. The service is being called with the code below:
Service.ServiceClient _client;
_client = new Service.ServiceClient();
_client.ClientCredentials.UserName.UserName =
"username";
_client.ClientCredentials.UserName.Password = "password";
//To allow service to connect even though certificate was not
validated.
ServicePointManager.ServerCertificateValidationCallback =
MyRemoteCertificateValidationCallback;
lci = await _client.WCFTestMethod();
To update the post on the comments below. wsHttpBinding is not supported by Xamarin, so I do have to use basicHttpBinding. I have gotten the checkAccessCore procedure to execute when I set the authentication to Anonymous on the IIS site, but it throws this error "No Identity Found" when the AuthorizationPolicy is executing GetClientIdentity. Is there a way to assign an identity in checkAccessCore?
I was able to get the service to work the way I wanted it to, by making sure the authentication method on IIS was set to Anonymous and in the Evaluate method of the AuthorizationPolicy I created a GenericIdentity and used it (example code below) instead of calling the GetClientIdentity method. The service seems to be working now and is authenticating the user in the checkAccessCore method.
Dim client As IIdentity = New GenericIdentity("User")
Dim cp As CustomPrincipal = New CustomPrincipal(client)
evaluationContext.Properties("Identities") = l
evaluationContext.Properties("Principal") = cp

Pass token from MVC to WCF service

I have a MVC app talking to ACS to get token for authentication. It's a claim based application. This works perfectly fine.
I am trying to call WCF service from MVC once authenticated with same taken so that i can use same claims for authorization.
MVC code is as below
var context = (BootstrapContext)identity.BootstrapContext;
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuerBinding = new WS2007FederationHttpBinding();
EndpointAddress acsEndPoint =
new EndpointAddress("https://ACS namespace/v2/wsfederation");
binding.Security.Message.IssuerAddress = acsEndPoint;
binding.Security.Message.IssuedTokenType = "urn:ietf:params:oauth:token-type:jwt";
ChannelFactory<IService1> factory =
new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost/TestWCF/Service1.svc"));
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;
var proxy = factory.CreateChannelWithIssuedToken(context.SecurityToken);
proxy.GetData(1);
WCF web config is as below
<system.serviceModel>
<services>
<service name="TestWCF.Service1">
<endpoint address="" behaviorConfiguration="webHttpAutoFormat" binding="ws2007FederationHttpBinding" bindingConfiguration="secureHttpBinding" contract="TestWCF.IService1"/>
<endpoint address="soap" binding="basicHttpBinding" contract="TestWCF.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<ws2007FederationHttpBinding>
<binding name="secureHttpBinding">
<security mode="None">
<message establishSecurityContext="false" issuedKeyType="SymmetricKey" issuedTokenType="urn:ietf:params:oauth:token- type:jwt">
<issuerMetadata address="https://ACS namespace/v2/wstrust/mex"></issuerMetadata>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials useIdentityConfiguration="true"></serviceCredentials>
<serviceAuthorization principalPermissionMode="Always" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpAutoFormat">
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="Service1.svc" service="TestWCF.Service1" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
Please note my WCF service is not HTTPS also I am using JWT token from ACS. No certificates.
I get below error
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
Can anyone help?
You are currently initializing your binding with
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message)
Try changing to
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential)
From (MSDN - WS Transport With Message Credential):
By default, the wsHttpBinding binding provides HTTP communication.
When configured for transport security, the binding supports HTTPS
communication. HTTPS provides confidentiality and integrity protection
for the messages that are transmitted over the wire. However the set
of authentication mechanisms that can be used to authenticate the
client to the service is limited to what the HTTPS transport supports.
Windows Communication Foundation (WCF) offers a
TransportWithMessageCredential security mode that is designed to
overcome this limitation. When this security mode is configured, the
transport security is used to provide confidentiality and integrity
for the transmitted messages and to perform the service
authentication. However, the client authentication is performed by
putting the client credential directly in the message. This allows you
to use any credential type that is supported by the message security
mode for the client authentication while keeping the performance
benefit of transport security mode.
Your web config should have this instead for <ws2007FederationHttpBinding>:
<ws2007FederationHttpBinding>
<binding name="secureHttpBinding">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" issuedKeyType="SymmetricKey" issuedTokenType="urn:ietf:params:oauth:token- type:jwt">
<issuerMetadata address="https://ACS namespace/v2/wstrust/mex"></issuerMetadata>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
See also the following answer for some additional info as well: StackOverflow - The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via

Does Visual Studio Online support SOAP WorkItem change notification?

The reason I ask, is that I've set up a WCF service following the guidance out there (specifics below), and set up a SOAP notification in Visual Studio Online and my service doesn't appear to be called. IIS 8.5 Logs show no attempt to make contact with the service from VSO servers.
In case it IS supported, here are relevant bits to see if I have something set up wrong on the service side.
WCF Service - .NET 4.5.1 hosted as an Azure WebRole
Contract and Implementation
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface IWorkItemSubscriber
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml);
}
// Note, I've tried w/ and w/out this Compatibility Attribute
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WorkItemSubscriber : IWorkItemSubscriber
{
public void Notify(string eventXml, string tfsIdentityXml)
{
// Do stuff
}
}
Web.Config
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="noSecurity">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="VsoNotificationService.Wcf.WorkItemSubscriber" behaviorConfiguration="eventServiceBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="noSecurity" contract="VsoNotificationService.Wcf.IWorkItemSubscriber" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="eventServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" aspNetCompatibilityEnabled="true" /> <!-- note: I've tried w/ and w/out the aspNetCompatibilityEnabled attribute -->
</system.webServer>
</configuration>
Visual Studio Online Configuration
I've confirmed I can hit the service, via creating my own client and calling the service. Whatever code I put in the method is executed, and if I do remote debugging via Visual Studio 2013 I'll hit the method's breakpoint. So the service is up and running, I just don't see traffic from Visual Studio Online (via code breakpoint, code content, nor IIS Logs). Makes me think that feature is not working there?
I see that you are missing the aspNetCompatibilityEnabled="true" on the <serviceHostingEnvironment element, as compared to my working solution, it might be the missing piece of the puzzle?
I only also achieved success by carefully including all little config settings.

WCF custom security over netTcp

I'm new to WCF and I'm making server/client application in which I need to have some user/password schema to maintain some customization settings for each client and to log who access the service, but "security" in the traffic going through the net is not really needed, since information is not sensitive.
So taking this into account I was searching for a SIMPLE way of accomplishing this but I couldn't find it.
I have a few constraints and conditions:
Windows security is not an option.
I'm using clickonce deployment, so everything should be contained
within the installation packet. I don't know the actual list of users
that are downloading it, so I don't have a way to distribute some
certificate to all users.
Also the client will be accesed within the LAN and through several
WANs. Another requirement has to be met is that the service should
have very good performance since a lot of data is flowing with each
response, so the questions is:
Does message security hurts performance notoriously?
The "manual" way would be to pass the username as a parameter for each method I'm exposing, but it seems like a very dirty solution.
It seems to me a lot of constrains to design this, so that's why I'm asking about this.
Which would be the simplest solution to accomplish this?
First of all we have to assume that all users consuming the service are in some way "registered" to use the service. Because if it is out in the open, anonymous, then there is simply no tracking. So my assumption is as follows:
The service is hosted in Windows Service/WinForms to support TCP
Endpoint. - With new versions of IIS(>6) this is not a required assumption anymore
There is a combination like "UserName/Password" to authenticate. This
is not in the active directory (not opting windows authentication)
but may be xml/database.
We are not willing to have methods like public int Add(string
User, string Password, int A, int B)
I have a service with a TCP endpoint which does something like this. I will share that. I don't claim it is the best practice.
Application name is MYAPP
I have provided
customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost"
in
serviceCredentials > userNameAuthentication
section of web.config.
MYAPPHost is name of my windows service. Authenticate is the class which does the authentication from Database.
message clientCredentialType="UserName" is set for TCPBinding.
App.Config of my windows service:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Off" propagateActivity="true" >
<listeners>
<add name="SERVICE_MONITOR" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MYAPP_MONITOR.svclog" />
</listeners>
</source>
<source name="MYAPP_TRACE" switchValue="All" >
<listeners>
<add name="MYAPP_TRACE_LISTENER" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MYAPP_TRACE.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true" />
</system.diagnostics>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="OverAllServiceBehavior">
<serviceSecurityAudit
auditLogLocation="Application"
serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="Failure"
suppressAuditFailure="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MYAPPHost.Authenticate, MYAPPHost"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="OverAllEndPointBehavior" />
</endpointBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="ServiceTCPEndPointBinding" maxBufferSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" algorithmSuite="TripleDes"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="OverAllServiceBehavior"
name="MiddleWare.ServiceClasses.ServiceClass">
<host>
<baseAddresses>
<add baseAddress="net.tcp://127.0.0.1:15010/ServiceTCPEndPointMEX"/>
</baseAddresses>
</host>
<endpoint address="net.tcp://127.0.0.1:15020/ServiceTCPEndPoint" contract="MiddleWare.ServiceContracts.IServiceContract" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
Authenticate Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IdentityModel.Selectors;
namespace MYAPPHost
{
public class Authenticate : UserNamePasswordValidator
{
public override void Validate(string UserName, string Password)
{
if (!CheckFromDB(UserName,Password))
throw new Exception("UNAUTHORIZED ACCESS!!!");
}
}
}
In Client Side,after adding reference to the WCF (SR)
SR.ServiceContractClient obj = new SR.ServiceContractClient("ServiceTCPEndPoint");
obj.ClientCredentials.UserName.UserName = "User1";
obj.ClientCredentials.UserName.Password = "Password1";
int I = obj.Add(1, 2);
If credentials are not provided, message security token error is thrown. For wrong credentials UNAUTHORIZED ACCESS occurs.

Wcf Basic authentication

Having some trouble using basic authentication with a simple test Wcf service. I am getting an exception:
The requested service, 'http://qld-tgower/test/Service.svc' could not be activated. See the > server's diagnostic trace logs for more information.
And in the trace log it shows:
The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the <serviceAuthenticationManager> element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.
But what I don understand it when I us the incorrect username and password it says it IS using basic authentication?
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="qld-tgower"'.
This is my web.config details
<system.serviceModel>
<services>
<service name="WcfService"
behaviorConfiguration="Behavior">
<endpoint address="http://QLD-TGOWER/test/Service.svc"
binding="basicHttpBinding"
bindingConfiguration="httpBinding"
contract="IService" />
</service>
</services>
<diagnostics>
<endToEndTracing activityTracing="false" messageFlowTracing="true" propagateActivity="true"></endToEndTracing>
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Basic">
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
and this is my App.config
<system.serviceModel>
<diagnostics>
<endToEndTracing activityTracing="true" />
<messageLogging logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" >
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Basic"></transport>
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://QLD-TGOWER/test/Service.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
my test application
private static void Main(string[] args)
{
var proxy = new ServiceClient("BasicHttpBinding_IService");
var clientCredentials = proxy.ClientCredentials;
clientCredentials.UserName.UserName = "username";
clientCredentials.UserName.Password = "password";
var res = proxy.GetData(1);
Console.WriteLine(res);
Console.WriteLine("Done");
Console.ReadKey(true);
}
And my service
public class Service : IService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Is there something that I am missing here?
Change the name and contract of the service to include the namespace.
Also, remove the endpoint address (set it to "") and don't include proxyCredentialType in the transport tag.
End result of the web.config should look something like this
<system.serviceModel>
<services>
<service name="MyNameSpace.MyService" behaviorConfiguration="asdf">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="httpBinding" contract="MyNameSpace.IMyService" />
</service>
</services>
<diagnostics>
<endToEndTracing activityTracing="true" messageFlowTracing="true"
propagateActivity="true">
</endToEndTracing>
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="asdf">
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>
</system.serviceModel>
Try for both client and server configs
<basicHttpBinding>
<binding name="BasicHttpBinding_IService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
Install/Enable basic authentication
You may also need to install and apply basic authentication in IIS.
Goto "Programs and Features" / "Turn windows features on/off ".
Enable "basic authentication" somewhere under IIS and security.
I closed and opened the IIS console and was able to enable it under authentication settings.
This of course if for a development testing and it warns you about not having an SSL certificate.
You're not allowed to use username authentication over an unsecured connection
You can secure the message by using a secure transport (e.g. SSL) or message encryption (using certificates)
I have used ClearUsernameBinding in the past to great success, but I don't recommend it in production. I used it so that I could keep all my authentication code the same without requiring SSL in dev/test environments, but having it work with SSL by changing the configuration only.
Note: that custom binding isn't perfect, and I had to change it a bit to enable certain configuration changes.
This is what solved the issue for me:
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
For reference see:
https://msdn.microsoft.com/en-gb/library/ff648505.aspx