Search code examples
wcfxamarin

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?


Solution

  • 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