How to make a WCF Service work with https? - c#

I am trying to enable https in my WCF service. I've added the SSL certificate to my localhost and I am able to view the WSDL when I use https in the browser. And the WCF service works fine with http without the SSL configuration in the web.config. But as soon as I change it to use https, I get the following error. If anybody can point me to the solution for this issue, it will be helpful as there isn't much reference for this error.
at Microsoft.Http.HttpStageProcessingAsyncResult.Complete(HttpStage stage, Exception e)
at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self)
at Microsoft.Http.HttpStageProcessingAsyncResult..ctor(HttpStageProcessingAsyncState state, AsyncCallback callback, Object user)
at Microsoft.Http.HttpClient.Send(HttpRequestMessage request)
at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri, RequestHeaders headers, HttpContent content)
at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri)
at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, Uri uri)
at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, String uri)
at Microsoft.Http.HttpMethodExtensions.Get(HttpClient client, String uri)
at MobileScreening.Client.CommonTests.LoginPost(HttpClient client, String username, String password) in c:\TFS Projects\MobileScreening\MobileScreening.Client\CommonTests.cs:line 118
My client code where I am making the request to the service
static string LoginPost(HttpClient client, string username, string password)
{
string key = string.Empty;
try
{
var user = new UserCredentials
{
Email = username,
Password = password
};
Console.WriteLine("User Authentication:");
HttpContent content = HttpContentExtensions.CreateJsonDataContract(user);
using (HttpResponseMessage response = client.Post("AuthenticationService.svc/", content))
{
Console.WriteLine(response.Content.ReadAsString());
Console.WriteLine(response.Headers.ToString());
key = response.Headers["MobileScreening"] ?? string.Empty;
}
}
catch (Exception ex)
{
var stack = ex.StackTrace;
var innerException = ex.InnerException;
var message = ex.Message;
}
return key;
}
My interface with the operation contract
public interface IAuthenticationService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
AuthenticationWrapper Authenticate(UserCredentials user);
}
My Service to authenticate users:
public class AuthenticationService : IAuthenticationService
{
public AuthenticationWrapper Authenticate(UserCredentials user)
{
string email = user.Email ?? string.Empty;
string password = user.Password ?? string.Empty;
var authentication = new Authentication();
var authenticationWrapper = new AuthenticationWrapper();
if (!authentication.AuthenticateUser(email, password))
{
const string description = "Authentication failed. Username and/or password is incorrect.";
BLL.Authentication.ThrowAuthorisationFailed(description, email);
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized;
authenticationWrapper.Code = (short)HttpStatusCode.Unauthorized;
authenticationWrapper.Status = HttpStatusCode.Unauthorized.ToString();
authenticationWrapper.Message = description;
return authenticationWrapper;
}
else
{
const string description = "Authentication: Authenticate User";
LogHandler.LogMessage(email, description, Common.Event.LoginSuccessful);
string authorisationKey = authentication.CreateAuthorisationKey(email);
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.Headers.Add(Common.AuthorisationHeader, authorisationKey);
ctx.OutgoingResponse.StatusCode = HttpStatusCode.OK;
authenticationWrapper.Code = (short)HttpStatusCode.OK;
authenticationWrapper.Status = HttpStatusCode.OK.ToString();
authenticationWrapper.Message = description;
return authenticationWrapper;
}
}
}
Finally my web.config configuration for the service
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="MobileScreening.ServiceApp.AuthenticationService">
<endpoint address="AuthenticationService" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" contract="MobileScreening.ServiceApp.IAuthenticationService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
<service name="MobileScreening.ServiceApp.ProgrammeService">
<endpoint address="ProgrammeService" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" contract="MobileScreening.ServiceApp.IProgrammeService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
<service name="MobileScreening.ServiceApp.ActivityService">
<endpoint address="ActivityService" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" contract="MobileScreening.ServiceApp.IActivityService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
<service name="MobileScreening.ServiceApp.UserConfigurationService">
<endpoint address="UserConfigurationService" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" contract="MobileScreening.ServiceApp.IUserConfigurationService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</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 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Create a new self signed certificate using your machine name instead of the local host. Configure your solution to use the new certificate and make sure that it is installed in the client machine's under the Trusted Root Certification Authority (in your case, the client is also the server).
Also, you may also try to create the certificate pointing to the machine's fully qualified domain name.

Related

Call a WCF service with a HttpClient

I have to call a WCF service. The WCF service is on and I can edit its configuration.
I want to create a client that calls the service. I cannot add the service reference to my client, so I am trying to call it with a HttpClient.
The client side code:
using (var client = new HttpClient())
{
//soapString is my input class serialized
var content = new StringContent(soapString, Encoding.UTF8, "text/xml");
using (var postResponse = client.PostAsync("http://localhost:52937/Attempts.svc/", content).Result)
{
string postResult = postResponse.Content.ReadAsStringAsync().Result;
}
}
The server side code:
[ServiceContract]
public interface IAttempts
{
[OperationContract]
void ReceiveAttemptResult(ReceiveAttemptResultInput result);
}
public class Attempts : IAttempts
{
string _backendUrl;
public void ReceiveAttemptResult(ReceiveAttemptResultInput result)
{
//...
}
}
And in the end the web.config server side:
<system.serviceModel>
<services>
<service name="it.MC.Listeners.Attempts">
<endpoint address="" contract="it.MC.Listeners.IAttempts" binding="basicHttpBinding"/>
<endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I call the service, I just obtain an empty string and I cannot stop in debug inside the service... What's wrong?
Thank you
Just in case this bedevils anyone else. Thank you #Disappointed for your missing piece of the puzzle, it prompted me to run the thing in WCF Test Client with Fiddler open to see what I was missing:
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://tempuri.org/IMyService/Mymethod_Async");
string soapEnvelope = "<s:Envelope xmlns:s= \"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><Mymethod_Async xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
var content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml");
HttpResponseMessage hrm = httpClient.PostAsync("http://MyService.MyDomain.com/MyService.svc", content).Result;

WCF Service not receiving data in POST

I have a WCF Service with a SOAP endpoint. I added a REST endpoint and the Get methods are working just fine. I am having trouble with a POST method which takes in an object and returns a different object. When I pass in my object, I get this error back:
"Message":"Object reference not set to an instance of an object."
Here's the code to call the service:
string URL = "http://qa.acct.webservice";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP POST
var request = new RequestGetInventory
{
BrandIDs = new string[] { "4", "42" },
AccountID = "9900003"
};
var resp = client.PostAsJsonAsync("/AxaptaService.svc/rest/GetInventory", request);
response = resp.Result;
if (response.IsSuccessStatusCode)
{
var temp = response.Content.ReadAsStringAsync().Result;
MessageBox.Show(temp); //error message received here.
}
The RequestGetInventory object is defined as follows:
[DataContract]
public class RequestGetInventory
{
[DataMember]
public string[] BrandIDs { get; set; }
[DataMember]
public string AccountID { get; set; }
}
The contract for the webservice is defined as follows:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]
ResponseGetInventory GetInventory(RequestGetInventory Request);
I tried playing around with the WebInvoke parameters, but received the same error message for all viable attempts.
And this is how my web.config is set up:
<system.serviceModel>
<services>
<service behaviorConfiguration="" name="Proj.AxaptaUS.WebService.AxaptaService">
<endpoint address="rest" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
<endpoint address="" binding="basicHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp helpEnabled="true" />
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I am not entirely sure what I'm doing wrong because I can access this using SOAP just fine. It seems like it is not getting any values for the object which I passed in, thus causing the object reference error.
Any help would be greatly appreciated! Thanks!
#jstreet posted a comment which ended up working.
I changed BodyStyle = WebMessageBodyStyle.WrappedRequest to BodyStyle = WebMessageBodyStyle.Bare and removed <enableWebScript/> from config file.
After doing those things, it started to work correctly! thanks #jstreet!

function called twice with WCF

I am using a DuplexChannelFactory to connect my client to my server and what I want to do now is connect the server to each client that will register on the server. But every time I launch a client, my "init()" function is ran twice. And my DuplexChannelFactory on the server side doesn't work.
Here is how I open my server for clients :
host = new ServiceHost(typeof(NewServeur.NewServeur));
host.Open();
with its App.Config :
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MEX">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MEX" name="NewServeur.NewServeur">
<endpoint address="IProxyNewServeur" binding="netTcpBinding"
bindingConfiguration="configWin" name="NetTcpEndpoint" contract="ProxyNewServeur.IProxyNewServeur" />
<endpoint address="MEX" binding="mexTcpBinding" bindingConfiguration=""
name="MexTcpEndpoint" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://192.156.142.176:8080/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="configWin">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
Here is how I connect my client to my server :
void init()
{
ServiceCablingCallback ServiceCablingCallback = new ServiceCablingCallback();
ServiceCablingCallback.ClientNotified += ServiceCablingCallback_ClientNotified;
this._instanceContext = new InstanceContext(ServiceCablingCallback);
this.factory = new DuplexChannelFactory<ProxyNewServeur.IProxyNewServeur>(_instanceContext, "configClient");
this._serviceCablingClient = factory.CreateChannel();
this._clientId = _serviceCablingClient.Subscribe();
}
with its App.Config
<system.serviceModel>
<client>
<endpoint address="net.tcp://192.156.142.176:8080/IProxyNewServeur"
binding="netTcpBinding" bindingConfiguration="configWin" contract="ALSTEF.Cabling.ProxyNewServeur.IProxyNewServeur"
name="configClient" />
</client>
<bindings>
<netTcpBinding>
<binding name="configWin">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
This works fine, but now I want to do the reverse thing, meaning connecting the server to the client. In order to do so, I added those lines before the last line of my client :
host = new ServiceHost(typeof(Service), new Uri(_serviceCablingClient.getIp()));
host.Open();
with getIp() returning the Ip address + the port 4242 of my client.
and this to the client App.config
<behaviors>
<serviceBehaviors>
<behavior name="MEX">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MEX" name="Client.Model.Service">
<endpoint address="IClientFunction" binding="netTcpBinding" bindingConfiguration="ClientConfig"
name="NetTcpEndpoint" contract="ProxyNewServeur.IClientFunction" />
<endpoint address="MEX" binding="mexTcpBinding" bindingConfiguration=""
name="MexTcpEndpoint" contract="IMetadataExchange" />
</service>
</services>
<!-- in the bindings html tag -->
<binding name="ClientConfig">
<security mode="None" />
</binding>
And I modified the _serviceCablingClient.Subscribe() by adding those lines (so in the server)
public Guid Subscribe()
{
ProxyNewServeur.INewServeurCallback callback =
OperationContext.Current.GetCallbackChannel<ProxyNewServeur.INewServeurCallback>();
System.ServiceModel.Channels.RemoteEndpointMessageProperty endpointProperty =
OperationContext.Current.IncomingMessageProperties[System.ServiceModel.Channels.RemoteEndpointMessageProperty.Name] as System.ServiceModel.Channels.RemoteEndpointMessageProperty;
Guid clientId = Guid.NewGuid();
if (callback != null)
{
lock (clientsCallback)
{
clientsCallback.Add(clientId, callback);
}
}
/* code I added */
string addr = "net.tcp://" + endpointProperty.Address + ":" + "4242" + "/IClientFunction";
ClientCallback cb = new ClientCallback();
var Okvp = new KeyValuePair<Guid, DuplexChannelFactory<ProxyNewServeur.IClientFunction>>(clientId,
new DuplexChannelFactory<ProxyNewServeur.IClientFunction>(new InstanceContext(cb), "configServer",
new EndpointAddress(addr)));
this.DictClient.Add(Okvp, Okvp.Value.CreateChannel());
this.DictClient[Okvp].CreateCallbackChannel();
/* end code I added */
}
And I added this to the server App.config
<client>
<endpoint binding="netTcpBinding" bindingConfiguration="ClientConfig" contract="ProxyNewServeur.IClientFunction" name="configServer" />
</client>
<!-- in the bindings html tag -->
<binding name="ClientConfig">
<security mode="None" />
</binding>
Here is how I define my ProxyServeur file
namespace ProxyNewServeur
{
[ServiceContract(CallbackContract = typeof(INewServeurCallback))]
public interface IProxyNewServeur
{
[OperationContract]
Guid Subscribe();
[OperationContract]
string getIp();
}
[ServiceContract]
public interface INewServeurCallback
{
[OperationContract(IsOneWay = true)]
void HandleMessage(Message message);
}
[ServiceContract(CallbackContract = typeof(IClientCallback))]
public interface IClientFunction
{
[OperationContract(IsOneWay = true)]
void CreateCallbackChannel();
}
[ServiceContract]
public interface IClientCallback
{
[OperationContract(IsOneWay = true)]
void BroadcastToServer(bool isActive, Guid ClientId);
}
}
Now When I launch a client the line
DictClient[Okvp].CreateCallbackChannel();
won't work and I will go twice in the
init()
{ /* code*/
}
function.
I have no idea why this is happening. I did the exact same thing in a test project and it worked fine.
EDIT
As it turns out, you cannot have a DuplexChannelFactory<> and a ServiceHost in the same method. So what I did is that I added a new Class "DoubleConnection" that have only one attribute.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class DoubleConnection : ProxyNewServeur.IClientFunction
{
public ServiceHost host;
public void CreateCallbackChannel()
{}
public void isActive()
{}
}
and in the init() function I removed
host = new ServiceHost(typeof(Service), new Uri(_serviceCablingClient.getIp()));
host.Open();
and added
varClass = new DoubleConnection();
varClass.host = new ServiceHost(typeof(DoubleConnection), new Uri(_serviceCablingClient.getIp()));
varClass.host.Open();
I works fine now but I still don't know why you cannot have a DuplexChannelFactory<> and a ServiceHost in the same method.

"No default endpoint found" when starting WCF client

I have a Windows Service which represents the WCF-Host and a WPF-Client-Application wich represents the WCF-Client.
The communication should be duplex so I went with WSDualHttpBinding.
At first I install and start my Service which opens a WCF connection after that I start my WPF app and I get the following error (I translated it):
No default endpoint was found to the contract
\ " WCFCloudManagerFolderWatcherService.Interfaces.IFilesDuplex \ " in the service model client configuration section
refers. This may be caused by: For the purposes of no configuration file was found
or in the client element no endpoint element was found , which corresponded to this contract .
Contracts:
IFilesDuplex-Contract:
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required,
CallbackContract = typeof(IFilesDuplexCallback))]
public interface IFilesDuplex
{
[OperationContract(IsOneWay = true)]
void Update();
}
IFilesDuplexCallback:
interface IFilesDuplexCallback
{
[OperationContract(IsOneWay = true)]
void Equals(string[] result);
}
ClientSide
CallbackHandler:
class CallbackHandler : IFilesDuplexCallback
{
public event Action<string[]> ReceivedList = delegate { };
public void Equals(string[] result)
{
this.ReceivedList(result);
}
}
The Client itself:
class FilesDuplexClient : DuplexClientBase<IFilesDuplex>, IFilesDuplex
{
public FilesDuplexClient(InstanceContext callbackCntx)
: base(callbackCntx)
{
}
public void Update()
{
base.Channel.Update();
}
}
And the Code from the Main Window, where the error is thrown:
CallbackHandler ch = new CallbackHandler();
ch.ReceivedList += ch_ReceivedList;
// Construct InstanceContext to handle messages on callback interface
InstanceContext instanceContext = new InstanceContext(ch);
// Create a client
FilesDuplexClient client = new FilesDuplexClient(instanceContext);
client.Update();
Serverside (Windows Service)
FileProtocoll-Class (Server code)
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class FileProtocoll : IFilesDuplex
{
IFilesDuplexCallback Callback
{ get { return OperationContext.Current.GetCallbackChannel<IFilesDuplexCallback>(); } }
void IFilesDuplex.Update()
{
//....
Callback.Equals(null);// just a dummy
//...
}
}
Code in the OnStart-Method (in a Thread):
// Step 1 Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8899/CloudManager/CommunicationChannel1");
// Step 2 Create a ServiceHost instance
if (selfHost != null)
{
selfHost.Close();
}
selfHost = new ServiceHost(typeof(FileProtocoll), baseAddress);
try
{
// Step 5 Start the service.
selfHost.Open();
}
catch (CommunicationException ce)
{
selfHost.Abort();
}
Code in the OnStop-Method (in a Thread):
if (selfHost != null)
{
if (selfHost.State != CommunicationState.Closed)
{
selfHost.Close();
}
selfHost = null;
}
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<system.serviceModel>
<services >
<service behaviorConfiguration="ServiceBehavior"
name="WCFCloudManagerFolderWatcherService.Communication.FileProtocoll">
<endpoint address="http://localhost:8899/CloudManager /CommunicationChannel1"
binding="wsDualHttpBinding" contract="WCFCloudManagerFolderWatcherService.Interfaces.IFilesDuplex">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true "/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I finally got it.
Had to make a few changes to my Client app.config and had to turn off security.
app.config(client):
<!-- WCF Client information-->
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IFilesDuplex">
<security mode="None"/>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:8899/CloudManager/CommunicationChannel1"
binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_IFilesDuplex"
contract="WCFCloudManagerFolderWatcherService.Interfaces.IFilesDuplex"
name="WSDualHttpBinding_IFilesDuplex">
<identity>
<userPrincipalName value="localhost"/>
</identity>
</endpoint>
</client>
and in the app.config for the serverside I also hat to set
<security mode="None"/>
Now the connection works.

WCF Custom authentication - HTTP status 401: Unauthorized

WCF Service WebConfig(partial).
<services>
<service name="Bricks99.LicensingServer.LicensingService"
behaviorConfiguration="Bricks99ServiceBehavior">
<!-- use base address specified above, provide one endpoint -->
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="Bricks99Binding"
contract="Bricks99.LicensingServer.ILicensingService" />
<!--<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />-->
</service>
</services>
<basicHttpBinding>
<binding name="Bricks99Binding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Bricks99.LicensingServer.CCustomValidatorClass, Bricks99.LicensingServer"/>
</serviceCredentials>
Client is ASP.NET 2.0
LicensingService service = new LicensingService();
//Authentication
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(service.Url), "Basic", new NetworkCredential("Test", "1234567"));
service.Credentials = credCache;
service.PreAuthenticate = true;
service.UseDefaultCredentials = false;
result = service.VerifyLicenseKey(licenseKey, string.Empty);
The result is always The request failed with HTTP status 401: Unauthorized. I have also turned off Anonymous Access on the folder. Its still not working.
Any ideas on how to set the credentials correctly?
EDIT: Seems like the overridden method
public override void Validate(string userName, string password)
{
try
{
if(userName != "Test" || password != "1234567")
{
throw new FaultException("The provided credentials are invalid.");
}
}
catch(FaultException ex)
{
LicensingData.Operations.LogError(ex);
}
}
is never getting hit.
Well after hours of research I found out that the hosting provider did not allow basic authentication by default. For custom authentication to work it is necessary that basic authentication be enabled in IIS.

Categories