locked
WCF authentication using credentials in setRequestHeader RRS feed

  • Question

  • User1114424055 posted

    Here is what I am trying to do (unsuccessfully, I might add) and would appreciate any direction you can give me

    I am working on ajax enabled WCF service while I have pure HTML pages wth jQuery which consume this service. I want to do login authentication using http authorization header over cross domain ajax enabled WCF Service. I am using jquery ajax to send http request.

    The issue is that when i use this given code, in Application_BeginRequest in Global.ascx, contorl would never pass to operaton contract and I get an exception with httprequest is aborted without login authentication(Operation contract is never called).

    Jquery ajax Code:

    function CheckLogin() {
    //var userid = window.localStorage.getItem("userid");
    //alert(userid);
    var vaildate = ValidateForm();
    if (vaildate != false) {
    "use strict";
    var wcfServiceUrl = "http://192.168.0.6:40000/Service1.svc/XMLService/";
    var name = $('#txtUserName');
    var password = $('#txtPassword');
    
    $.ajax({
    
    url: wcfServiceUrl + "Login",
    data: "UserName=" + name.val() + "&password=" + password.val() + "",
    type: "GET",
    processData: true,
    contentType: "application/json",
    dataType: "json",
    
    beforeSend: function (xhr) {
    $.mobile.showPageLoadingMsg();
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.setRequestHeader("Authorization", "Basic " + base64_encode(name.val() + ":" + password.val()));
    
    },
    complete: function () {
    $.mobile.hidePageLoadingMsg();
    },
    success: function (data) {
    if (data != '"Invalid username or password."') {
    window.localStorage.setItem("userid", data);
    window.localStorage.setItem("loginname", name.val());
    $.mobile.page.prototype.options.domCache = true;
    window.location.href = 'default.html';
    
    }
    else {
    $('#failAttempt').text(data);
    return;
    }
    
    },
    error: function () {
    alert('an error');
    
    }
    
    });
    }
    }



    And i am using global.ascx in wcf

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
    EnableCrossDomainAjaxCall();
    }
    
    private void EnableCrossDomainAjaxCall()
    {
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");
    HttpContext.Current.Response.End();
    }
    }



    And WCF Service and Iservice Code:

    [OperationContract]
    [WebGet(UriTemplate = "Login?UserName={UserName}&Password={Password}", ResponseFormat = WebMessageFormat.Json)]
    string LoginUser(string UserName, string password);
    
    // implimentation of LoginUser
    
    public string LoginUser(string UserName, string password)
    {
    string loginUsername = UserName;
    string loginPassword = password; 
    var message = OperationContext.Current.RequestContext.RequestMessage;
    var request = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
    string authorization = request.Headers[HttpRequestHeader.Authorization];
    MembershipUser memUser = Membership.GetUser(loginUsername);
    if (Membership.ValidateUser(loginUsername, loginPassword))
    {
    
    PatientBLL objBLL = new PatientBLL();
    List<PatientDTO> lstPatient = new List<PatientDTO>();
    lstPatient = objBLL.GetPatientByUserID(new Guid(memUser.ProviderUserKey.ToString()));
    string UserID = lstPatient[0].PatientID.ToString();
    
    return UserID;
    
    }
    else
    {
    
    return "Invalid username or password.";
    }
    }




    WCF web.config

    <system.serviceModel>
    <bindings>
    <webHttpBinding>
    
    <binding crossDomainScriptAccessEnabled="true" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="524288"
    transferMode="Buffered">
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647"
    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    <security mode="TransportCredentialOnly">
    <transport clientCredentialType="Basic"></transport>
    </security>
    
    </binding>
    </webHttpBinding>
    </bindings>
    
    <services>
    <service name="PHRWCFService.Service1" behaviorConfiguration="ServBehave">
    <!--Endpoint for SOAP-->
    <endpoint
    address="soapService"
    binding="webHttpBinding"
    behaviorConfiguration="restPoxBehavior"
    contract="PHRWCFService.IService1"/>
    <!--Endpoint for REST-->
    <endpoint
    address="XMLService"
    binding="webHttpBinding"
    behaviorConfiguration="restPoxBehavior"
    contract="PHRWCFService.IService1"/>
    </service>
    </services>
    <behaviors>
    
    <serviceBehaviors>
    <behavior name="ServBehave">
    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    <serviceMetadata httpGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="false"/> 
    
    </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
    <!--Behavior for the REST endpoint for Help enability-->
    <behavior name="restPoxBehavior">
    <webHttp helpEnabled="true"/>
    
    <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    </behavior>
    </endpointBehaviors>
    </behaviors>
    <standardEndpoints>
    <webHttpEndpoint>
    <standardEndpoint name="" helpEnabled="true" crossDomainScriptAccessEnabled="true"/>
    </webHttpEndpoint>
    </standardEndpoints>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    
    </system.serviceModel>
    <system.webServer>
    <security>
    <requestFiltering>
    <requestLimits maxAllowedContentLength="2147483647" maxUrl="4294967295" maxQueryString="4294967295" />
    </requestFiltering>
    </security>
    <directoryBrowse enabled="true" />
    <modules runAllManagedModulesForAllRequests="true" />
    <httpProtocol>
    <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    
    </customHeaders>
    </httpProtocol>
    </system.webServer>
    



    Please help me to solve this problem.

    Wednesday, April 3, 2013 10:14 AM

Answers

  • User1114424055 posted

    I have solved this issue. Removing just 

    <transport clientCredentialType="Basic"></transport>

    From wcf config file.

    Thanks.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, April 9, 2013 3:21 AM

All replies

  • User220959680 posted

    Can the service be accessed when Transport security is disable?

    It appears to be CORS isssue rather than authentication issue.

    Wednesday, April 3, 2013 2:26 PM
  • User1114424055 posted

    yes Service is accessed when Transport Security is disable.

    Thursday, April 4, 2013 1:10 AM
  • User-1658256289 posted

    Hi, do you try with some tool such as Fiddler to inspect the root issue?

    Tuesday, April 9, 2013 2:34 AM
  • User1114424055 posted

    I have solved this issue. Removing just 

    <transport clientCredentialType="Basic"></transport>

    From wcf config file.

    Thanks.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, April 9, 2013 3:21 AM