iis 7 - WCF message authentication with both username and certificate -


long story short:

my wcf clients should able provide both username , certificate service hosted in iis, should use information validate requests using custom policies.

complete story:

i have need authenticate wcf clients verify if can execute operations.

we have 2 kinds of clients: wpf applications , web application. following:

  • the web application uses certificate trusted service recognized special user permissions (the web application verifies permissions , wouldn't touch now)
  • the wpf clients authenticate username/password provided user

in implementation of operations, verify if certificate provided (then recognize "super user"), otherwise fallback username/password authentication.

services hosted in iis 7 , need use nettcpbinding. able implement username validation, problem authorizationcontext inspected service contains identity information, , not certificate. following code used on client side initialize creation of channels (from spike i'm using test solution):

var factory = new channelfactory<t>(this.binding, address);          var defaultcredentials = factory.endpoint.behaviors.find<clientcredentials>();         factory.endpoint.behaviors.remove(defaultcredentials);          var logincredentials = new clientcredentials();         logincredentials.servicecertificate.authentication.certificatevalidationmode =                      x509certificatevalidationmode.none;         logincredentials.username.username = username;         logincredentials.username.password = password;         if (usecertificate)         {             logincredentials.setcertificate();         }          factory.endpoint.behaviors.add(logincredentials);         return factory.createchannel(); 

with setcertificate extension being implemented this:

public static void setcertificate(this clientcredentials logincredentials)     {         logincredentials.clientcertificate.setcertificate(storelocation.localmachine, storename.my, x509findtype.findbysubjectname, "securewcfclient");     } 

this configuration of web application hosting services:

<system.servicemodel> <behaviors>   <servicebehaviors>     <behavior name="securebehavior">       <servicemetadata httpgetenabled="true" />       <servicedebug includeexceptiondetailinfaults="true" />       <servicecredentials>         <servicecertificate findvalue="test"               storelocation="localmachine"               storename="my"               x509findtype="findbysubjectname" />         <clientcertificate>           <authentication certificatevalidationmode="custom" customcertificatevalidatortype="authenticationprotectedservice.security.certificatevalidator, authenticationprotectedservice.security"/>         </clientcertificate>         <usernameauthentication usernamepasswordvalidationmode="custom"          customusernamepasswordvalidatortype="authenticationprotectedservice.security.usernamepassvalidator, authenticationprotectedservice.security" />       </servicecredentials>       <serviceauthorization serviceauthorizationmanagertype="authenticationprotectedservice.security.certificateauthorizationmanager, authenticationprotectedservice.security"/>     </behavior>   </servicebehaviors> </behaviors> <bindings>   <nettcpbinding>     <binding>       <security mode="none"/>     </binding>     <binding name="securenettcp">       <security mode="message">         <message clientcredentialtype="username"/>       </security>     </binding>   </nettcpbinding> </bindings>   <service   name="authenticationprotectedservice.services.onewayserviceb"   behaviorconfiguration="securebehavior">     <endpoint         address=""         binding="wshttpbinding"         contract="authenticationprotectedservice.servicemodel.ionewayserviceb">     </endpoint>   </service>   <service   name="authenticationprotectedservice.services.duplexserviceb" behaviorconfiguration="securebehavior">     <endpoint         address=""         binding="nettcpbinding"         bindingconfiguration="securenettcp"         contract="authenticationprotectedservice.servicemodel.iduplexserviceb">     </endpoint>     <endpoint address="mex" binding="mextcpbinding" contract="imetadataexchange"/>   </service> </services> <servicehostingenvironment multiplesitebindingsenabled="true" /> 

finally, implementation of custom authorization manager (i tried custom certificate validator function never run)

public class certificateauthorizationmanager : serviceauthorizationmanager {     protected override bool checkaccesscore(operationcontext operationcontext)     {         if (!base.checkaccesscore(operationcontext))         {             return false;         }          string thumbprint = getcertificatethumbprint(operationcontext);          // i'd need verify thumbprint, null         return true;     }      private string getcertificatethumbprint(operationcontext operationcontext)     {         foreach (var claimset in operationcontext.servicesecuritycontext.authorizationcontext.claimsets)         {             foreach (claim claim in claimset.findclaims(claimtypes.thumbprint, rights.identity))             {                 string tb = bitconverter.tostring((byte[])claim.resource);                 tb = tb.replace("-", "");                 return tb;             }         }          return null;     } } 

i think problem in clientcredentialtype property of nettcpbinding.security.message node on service configuration, don't see option use both certificate , username withing message security.

any appreciated, thanks

remark: specific goal of project have low level impact on server setup , in general in system, ssl should avoided if possible.

try out link http://msdn.microsoft.com/en-us/library/ms733099.aspx ...it might resolve issue in can have different binding configuration same binding type , associate same different endpoints per need.


Comments

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -