Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi there (long time reader, first time poster)
Here is problem folks, I have lots of services using the standard AspNetSqlMembership authorization.
HTML
<webhttpbinding>
        <binding name="webHttpTransportBinding">
          <security mode="Transport">            
          </security>
        </binding>
      </webhttpbinding>
        <behavior name="TaskServiceBehavior">
          <serviceauthorization principalpermissionmode="UseAspNetRoles" roleprovidername="AspNetSqlRoleProvider" />
          <servicemetadata httpgetenabled="true" httpsgetenabled="true" />
          <servicedebug includeexceptiondetailinfaults="true" />
          <servicecredentials>
            <servicecertificate findvalue="XXXXXCERT" storelocation="LocalMachine" storename="My" x509findtype="FindBySubjectName" />
            <usernameauthentication usernamepasswordvalidationmode="MembershipProvider" membershipprovidername="CustomMembershipProvider" />
          </servicecredentials>
        </behavior>
      <endpointbehaviors>
        <behavior name="AspNetAjaxBehavior">
          <enablewebscript />
        </behavior>
      </endpointbehaviors>
      <service behaviorconfiguration="TaskServiceBehavior" name=" Business.Managers.Managers.TaskManager">
        <endpoint>
                address=""  
                binding="wsHttpBinding" 
                bindingConfiguration="wsCertificateBinding"                   
                contract=" Business.Contracts.Service.ITaskService" />
        <endpoint>
                address="api/ssl" 
                binding="webHttpBinding" 
                bindingConfiguration="webHttpTransportBinding" 
                behaviorConfiguration="AspNetAjaxBehavior"                 
                contract="Business.Contracts.Service.ITaskService" />
        <endpoint>
                address="api" 
                binding="webHttpBinding" 
                behaviorConfiguration="AspNetAjaxBehavior" 
                contract="Business.Contracts.Service.ITaskService" />
      </endpoint></endpoint></endpoint></service>


When I’m using webHttBinding, without HTTPS, and there is no “OperationContext.Current.ServiceSecurityContext” so I can just inject the user name and password in the ajax request and presto… I can set the user by setting Thread.Principal = ...
C#
private void AuthenticateWebHttpRequest(string authorizationHeader)
{
    try
    {
        string applicationHeader = HttpContext.Current.Request.Headers["Authorization"];

        if (authorizationHeader != null && authorizationHeader.StartsWith(_headerAutorizationContainer))
        {
            string encodedUserPass = authorizationHeader.Substring(_headerAutorizationContainer.Length + 1).Trim();
            Encoding encoding = Encoding.GetEncoding(_encoding);
            string userPass = encoding.GetString(Convert.FromBase64String(encodedUserPass));
            string[] credentials = userPass.Split(':');
            string username = credentials[0];
            string password = credentials[1];

            string application = encoding.GetString(Convert.FromBase64String(applicationHeader));

            if (Membership.ValidateUser(username, password))
            {       
                HttpApplication app = HttpContext.Current.ApplicationInstance;                        
                if (app != null)
                {
                    string[] roles = Roles.GetRolesForUser(username);
                    var genericIdentity = new System.Security.Principal.GenericIdentity(username);                          
                    var genericPrincipal = new System.Security.Principal.GenericPrincipal(genericIdentity, roles);
                    HttpContext.Current.User = genericPrincipal;
                    Thread.CurrentPrincipal = genericPrincipal;
                                                                                  
                    _application = application;
                    _operationUser = username;
                }
            }
        }
    }
    catch(Exception ex)
    {
        Logger.LogException(this.Application, this.OperationUsername, ex);
        throw new FaultException(ex.Message);
    }
}

This is the client code
var username = 'xxxxxxxxxxxxx@xxxxxxxxxx.com';
var password = 'xxxxxxxxx';
var application = 'Mobile';
var sendData = { accountId: 1, userId: 2, recordCount: 100, taskListResponse: taskListResponse };
var jsonData = JSON.stringify(sendData);
$.ajax({
    type: "POST",
    url: "/TaskService.svc/api/ssl/GetTaskList", //http request
    data: jsonData,
    dataType: "json",
    contentType: "application/json; charset=utf-8",
                    
    beforeSend: function (xhr) {
        xhr.withCredentials = true;
        var creds = username + ':' + password;
        var basicScheme = btoa(creds);                        
        xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
        xhr.setRequestHeader('Application', btoa(application));
        xhr.setRequestHeader('username', username);
        xhr.setRequestHeader('password', password);
    },

}).success(function (data) {
    var isValid = data.d.IsValid;
    alert('valid');
}).error(function (jqXHR, textStatus, errorThrown) {
    console.log(jqXHR);
    console.log(jqXHR.responseText);
    console.log(textStatus);
    console.log(errorThrown);
    alert('error');
});

With the user injected it’s then valid to do this
C#
[PrincipalPermission(SecurityAction.Demand, Role = SecurityRole.SystemAdministrator)]
public string GetTaskList(int accountId, int userId, int recordCount, string taskListResponse)
{
//Stuff
}


My problem occurs when HTTPS is used instead of HTTP. In those cases, the Principal is in “OperationContext.Current.ServiceSecurityContext” and doing HttpContext.Current.User = genericPrincipal; Thread.CurrentPrincipal = genericPrincipal; simply has no side effects. I can’t get permission to access the method.

I’ve tried a couple of things with no success. I can’t seem to be able to simulate sending the credentials over the ajax request. Username and Password don’t work and using “<transport clientcredentialtype="Basic"/>” seem to stop the service altogether.

Is there anyone out there that has done something similar?
Thanks in advanced for your time
Posted
Updated 21-Nov-15 8:22am
v8

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900