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
Post a Comment