Note that there are some explanatory texts on larger screens.

plurals
  1. POHTTP WCF Service via HTTPS
    text
    copied!<p>I have a C# Web Application project that is secured using Forms Authentication. Managing the Authorization of various pages using the default Role Manager is working well. </p> <p>I've recently added a number of WCF (*.svc) services to the project which I call using Javascript from the browser using ASP.NET AJAX (adding a ScriptManager referencing the service). This all works fine using HTTP.</p> <p>I have now added a HTTPS binding to IIS with a certificate and am attempting to use the application via HTTPS; however the pages that reference the service throw up a '401 Unauthorized' error when they try and load the js proxy class (service.svc/jsdebug). From what I've gathered I need to change the configuration in my web.config file to make it work, but I can't find any settings that will get it working. I need it to be accessible via HTTP protocol (enableWebScript), but via HTTPS. It also needs to use the identity of the currently authenticated Forms user. </p> <p>Any general advice on configuring the endpoints in web.config would also be appreciated - or a pointer to a good tutorial. Thanks</p> <p><strong>Here is the services section of my web.config file at present</strong></p> <pre><code> &lt;system.serviceModel&gt; &lt;bindings&gt; &lt;wsHttpBinding&gt; &lt;binding name="WsHttpBindingConfig"&gt; &lt;security mode="Transport"&gt; &lt;transport clientCredentialType="None" /&gt; &lt;message clientCredentialType="UserName"/&gt; &lt;/security&gt; &lt;/binding&gt; &lt;/wsHttpBinding&gt; &lt;webHttpBinding&gt; &lt;binding name="webHttp"&gt; &lt;security mode="None"&gt; &lt;/security&gt; &lt;/binding&gt; &lt;binding name="default"/&gt; &lt;/webHttpBinding&gt; &lt;/bindings&gt; &lt;behaviors&gt; &lt;endpointBehaviors&gt; &lt;behavior name="webScriptEnablingBehavior"&gt; &lt;enableWebScript/&gt; &lt;/behavior&gt; &lt;behavior name="scorelink.groups.Risk"&gt; &lt;enableWebScript /&gt; &lt;/behavior&gt; &lt;behavior name="scorelink.tests.Benchmarks"&gt; &lt;enableWebScript /&gt; &lt;/behavior&gt; &lt;behavior name="default"&gt; &lt;/behavior&gt; &lt;/endpointBehaviors&gt; &lt;serviceBehaviors&gt; &lt;behavior name="DefaultBehaviours"&gt; &lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/&gt; &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt; &lt;serviceCredentials&gt; &lt;userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlProvider"/&gt; &lt;/serviceCredentials&gt; &lt;serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlProvider" /&gt; &lt;/behavior&gt; &lt;behavior name=""&gt; &lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&gt; &lt;serviceDebug includeExceptionDetailInFaults="false" /&gt; &lt;/behavior&gt; &lt;/serviceBehaviors&gt; &lt;/behaviors&gt; &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /&gt; &lt;services&gt; &lt;service name="scorelink.groups.Risk"&gt; &lt;endpoint address="" behaviorConfiguration="scorelink.groups.Risk" binding="webHttpBinding" contract="scorelink.groups.Risk" /&gt; &lt;/service&gt; &lt;service name="scorelink.tests.Benchmarks" behaviorConfiguration="DefaultBehaviours"&gt; &lt;endpoint address="" behaviorConfiguration="scorelink.tests.Benchmarks" binding="webHttpBinding" contract="scorelink.tests.Benchmarks" /&gt; &lt;/service&gt; &lt;service name="scorelink.services.user" behaviorConfiguration="DefaultBehaviours"&gt; &lt;endpoint address="" binding="wsHttpBinding" behaviorConfiguration="default" bindingConfiguration="WsHttpBindingConfig" contract="scorelink.services.Iuser" /&gt; &lt;endpoint address="http" binding="webHttpBinding" behaviorConfiguration="webScriptEnablingBehavior" bindingConfiguration="webHttp" contract="scorelink.services.Iuser" /&gt; &lt;/service&gt; &lt;/services&gt; &lt;/system.serviceModel&gt; </code></pre> <p>It might be a bit confusing since I've tried so very many things. I am only focusing on <code>user.svc</code> at the moment, but once it's working I'll apply the configuration to all the services.</p> <p><strong>EDIT</strong></p> <p>I updated my config to one suggested but now get the following error:</p> <pre><code>The endpoint at 'https://localhost:44300/_assets/code/services/user.svc' does not have a Binding with the None MessageVersion. System.ServiceModel.Description.WebScriptEnablingBehavior' is only intended for use with WebHttpBinding or similar bindings. </code></pre> <p>I assume that this is because it is using an endpoint behaviour that specifies <code>&lt;enableWebScript /&gt;</code>. The problem is if I take that away then the service doesn't generate a javascript proxy class so I can't call it from js.</p> <p><strong>EDIT 2</strong> Here is a dump of the js proxy class that is generated by ASP.NET in response to the EnableWebScript flag. It is accessible from <code>http://uri/service.svc/jsdebug</code>:</p> <pre><code>Type.registerNamespace('scorelink.services'); scorelink.services.Iuser=function() { scorelink.services.Iuser.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null; } scorelink.services.Iuser.prototype={ _get_path:function() { var p = this.get_path(); if (p) return p; else return scorelink.services.Iuser._staticInstance.get_path();}, CreateUser:function(FirstName,LastName,Username,DateOfBirth,Roles,succeededCallback, failedCallback, userContext) { /// &lt;param name="FirstName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="LastName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="DateOfBirth" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="Roles" type="Array"&gt;System.String[]&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'CreateUser',false,{FirstName:FirstName,LastName:LastName,Username:Username,DateOfBirth:DateOfBirth,Roles:Roles},succeededCallback,failedCallback,userContext); }, UpdateUser:function(username,firstName,lastName,dateOfBirth,roles,succeededCallback, failedCallback, userContext) { /// &lt;param name="username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="firstName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="lastName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="dateOfBirth" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="roles" type="Array"&gt;System.String[]&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'UpdateUser',false,{username:username,firstName:firstName,lastName:lastName,dateOfBirth:dateOfBirth,roles:roles},succeededCallback,failedCallback,userContext); }, DeleteUser:function(Username,succeededCallback, failedCallback, userContext) { /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'DeleteUser',false,{Username:Username},succeededCallback,failedCallback,userContext); }, GetUserDetails:function(Username,succeededCallback, failedCallback, userContext) { /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'GetUserDetails',true,{Username:Username},succeededCallback,failedCallback,userContext); }, ChangePassword:function(oldPassword,newPassword,succeededCallback, failedCallback, userContext) { /// &lt;param name="oldPassword" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="newPassword" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'ChangePassword',false,{oldPassword:oldPassword,newPassword:newPassword},succeededCallback,failedCallback,userContext); }, ChangeLockoutCode:function(password,symbol1,symbol2,succeededCallback, failedCallback, userContext) { /// &lt;param name="password" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="symbol1" type="Number"&gt;System.Int32&lt;/param&gt; /// &lt;param name="symbol2" type="Number"&gt;System.Int32&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; return this._invoke(this._get_path(), 'ChangeLockoutCode',false,{password:password,symbol1:symbol1,symbol2:symbol2},succeededCallback,failedCallback,userContext); }} scorelink.services.Iuser.registerClass('scorelink.services.Iuser',Sys.Net.WebServiceProxy); scorelink.services.Iuser._staticInstance = new scorelink.services.Iuser(); scorelink.services.Iuser.set_path = function(value) { scorelink.services.Iuser._staticInstance.set_path(value); } scorelink.services.Iuser.get_path = function() { /// &lt;value type="String" mayBeNull="true"&gt;The service url.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_path();} scorelink.services.Iuser.set_timeout = function(value) { scorelink.services.Iuser._staticInstance.set_timeout(value); } scorelink.services.Iuser.get_timeout = function() { /// &lt;value type="Number"&gt;The service timeout.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_timeout(); } scorelink.services.Iuser.set_defaultUserContext = function(value) { scorelink.services.Iuser._staticInstance.set_defaultUserContext(value); } scorelink.services.Iuser.get_defaultUserContext = function() { /// &lt;value mayBeNull="true"&gt;The service default user context.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_defaultUserContext(); } scorelink.services.Iuser.set_defaultSucceededCallback = function(value) { scorelink.services.Iuser._staticInstance.set_defaultSucceededCallback(value); } scorelink.services.Iuser.get_defaultSucceededCallback = function() { /// &lt;value type="Function" mayBeNull="true"&gt;The service default succeeded callback.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_defaultSucceededCallback(); } scorelink.services.Iuser.set_defaultFailedCallback = function(value) { scorelink.services.Iuser._staticInstance.set_defaultFailedCallback(value); } scorelink.services.Iuser.get_defaultFailedCallback = function() { /// &lt;value type="Function" mayBeNull="true"&gt;The service default failed callback.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_defaultFailedCallback(); } scorelink.services.Iuser.set_enableJsonp = function(value) { scorelink.services.Iuser._staticInstance.set_enableJsonp(value); } scorelink.services.Iuser.get_enableJsonp = function() { /// &lt;value type="Boolean"&gt;Specifies whether the service supports JSONP for cross domain calling.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_enableJsonp(); } scorelink.services.Iuser.set_jsonpCallbackParameter = function(value) { scorelink.services.Iuser._staticInstance.set_jsonpCallbackParameter(value); } scorelink.services.Iuser.get_jsonpCallbackParameter = function() { /// &lt;value type="String"&gt;Specifies the parameter name that contains the callback function name for a JSONP request.&lt;/value&gt; return scorelink.services.Iuser._staticInstance.get_jsonpCallbackParameter(); } scorelink.services.Iuser.set_path("http://localhost:5584/_assets/code/services/user.svc"); scorelink.services.Iuser.CreateUser= function(FirstName,LastName,Username,DateOfBirth,Roles,onSuccess,onFailed,userContext) { /// &lt;param name="FirstName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="LastName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="DateOfBirth" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="Roles" type="Array"&gt;System.String[]&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.CreateUser(FirstName,LastName,Username,DateOfBirth,Roles,onSuccess,onFailed,userContext); } scorelink.services.Iuser.UpdateUser= function(username,firstName,lastName,dateOfBirth,roles,onSuccess,onFailed,userContext) { /// &lt;param name="username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="firstName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="lastName" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="dateOfBirth" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="roles" type="Array"&gt;System.String[]&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.UpdateUser(username,firstName,lastName,dateOfBirth,roles,onSuccess,onFailed,userContext); } scorelink.services.Iuser.DeleteUser= function(Username,onSuccess,onFailed,userContext) { /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.DeleteUser(Username,onSuccess,onFailed,userContext); } scorelink.services.Iuser.GetUserDetails= function(Username,onSuccess,onFailed,userContext) { /// &lt;param name="Username" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.GetUserDetails(Username,onSuccess,onFailed,userContext); } scorelink.services.Iuser.ChangePassword= function(oldPassword,newPassword,onSuccess,onFailed,userContext) { /// &lt;param name="oldPassword" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="newPassword" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.ChangePassword(oldPassword,newPassword,onSuccess,onFailed,userContext); } scorelink.services.Iuser.ChangeLockoutCode= function(password,symbol1,symbol2,onSuccess,onFailed,userContext) { /// &lt;param name="password" type="String"&gt;System.String&lt;/param&gt; /// &lt;param name="symbol1" type="Number"&gt;System.Int32&lt;/param&gt; /// &lt;param name="symbol2" type="Number"&gt;System.Int32&lt;/param&gt; /// &lt;param name="succeededCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="failedCallback" type="Function" optional="true" mayBeNull="true"&gt;&lt;/param&gt; /// &lt;param name="userContext" optional="true" mayBeNull="true"&gt;&lt;/param&gt; scorelink.services.Iuser._staticInstance.ChangeLockoutCode(password,symbol1,symbol2,onSuccess,onFailed,userContext); } var gtc = Sys.Net.WebServiceProxy._generateTypedConstructor; if (typeof(scorelink.services.UserDetails) === 'undefined') { scorelink.services.UserDetails=gtc("UserDetails:http://schemas.datacontract.org/2004/07/scorelink.services"); scorelink.services.UserDetails.registerClass('scorelink.services.UserDetails'); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload