c# - WCF "Basic" transport security issue when hosted in IIS -


i attempting secure new .net 4.5 wcf service using https / ssl, basic client credentials , webhttpbinding. reading online found series of blog posts allen conway have used template.

wcf configuration

 <system.servicemodel>     <bindings>       <webhttpbinding>         <binding name="webinteropsecurebinding" allowcookies="false" maxbufferpoolsize="2097152" maxbuffersize="2097152" maxreceivedmessagesize="2097152">           <security mode="transport">             <transport clientcredentialtype="basic"></transport>           </security>         </binding>       </webhttpbinding>     </bindings>     <services>       <service name="psmdataprovider.psmprovider" behaviorconfiguration="securerest">         <clear />         <endpoint address="" binding="webhttpbinding" bindingconfiguration="webinteropsecurebinding" name="psmprovider" contract="psmdataprovider.ipsmprovider" behaviorconfiguration="webhttpbehavior" />         <endpoint address="mex" binding="mexhttpsbinding" name="mex" contract="imetadataexchange" listenurimode="explicit" />         <host>           <baseaddresses>             <add baseaddress="https://localhost:44300/psmprovider/" />           </baseaddresses>         </host>       </service>     </services>     <behaviors>       <servicebehaviors>         <behavior name="securerest">           <servicemetadata httpgetenabled="false" httpsgetenabled="true" />           <servicedebug includeexceptiondetailinfaults="true" />           <servicecredentials>             <usernameauthentication usernamepasswordvalidationmode="custom"                                      customusernamepasswordvalidatortype="psmdataprovider.security.customerusernamepasswordvalidator, psmdataprovider"/>           </servicecredentials>         </behavior>       </servicebehaviors>       <endpointbehaviors>         <behavior name="webhttpbehavior">           <webhttp />         </behavior>       </endpointbehaviors>     </behaviors>     <servicehostingenvironment aspnetcompatibilityenabled="true" multiplesitebindingsenabled="true" />   </system.servicemodel> 

customerusernamepasswordvalidator

i have stubbed out customerusernamepasswordvalidator implementation , have confirmed constructor called before exception raised.

using system; using system.identitymodel.selectors;  namespace psmdataprovider.security {     internal class customerusernamepasswordvalidator : usernamepasswordvalidator, icustomerusernamepasswordvalidator      {          public customerusernamepasswordvalidator()         {         }          public override void validate(string username, string password)         {                       if (username == null) throw new argumentnullexception("username","the username must provided in request access service");             if (password == null) throw new argumentnullexception("password", "the password must provided in request access service");          }     } } 

when try run code in vs2012 through iis express service fails start below error.

enter image description here

if remove clientcredentialtype configuration works require additional security of using username / password validation on service , possibly @ method level in future.

is have configured incorrectly in wcf config or problem configuration in iisexpress?

please help...

the issue appears when using basic authentication when hosting service in iis iis wants handle authentication.

this discussed in this msdn blog post

in version of wcf shipped .net framework 3.0 didn't support custom validators transport level http security. received feedback community highly desired feature, i'm happy added support scenario in 3.5 release of .net framework. note supported under self hosted services.

there resolution discussed in allen conway's blog post implementing custom authorisation manager derived serviceauthorizationmanager

customauthorizationmanager

public class customauthorizationmanager : serviceauthorizationmanager  {     private const string username = "username";     private const string password = "password";      protected override bool checkaccesscore(operationcontext operationcontext)     {         string authheader = weboperationcontext.current.incomingrequest.headers["authorization"];          if ((authheader != null) && (authheader != string.empty))         {             string[] svccredentials = system.text.asciiencoding.ascii                                         .getstring(convert.frombase64string(authheader.substring(6)))                                         .split(':');              var user = new { name = svccredentials[0], password = svccredentials[1] };              if ((user.name.equals(username) && user.password.equals(password)))                 return true;             else                 return false;         }         else         {             weboperationcontext.current.outgoingresponse.headers.add("www-authenticate: basic realm=\"psmprovider\"");             throw new webfaultexception(httpstatuscode.unauthorized);         }     }  } 

config

  <system.servicemodel>     <bindings>       <webhttpbinding>         <binding name="webinteropsecurebinding" allowcookies="false" maxbufferpoolsize="51200" maxbuffersize="51200" maxreceivedmessagesize="51200">           <security mode="transport"/>         </binding>       </webhttpbinding>     </bindings>     <services>       <service name="psmdataprovider.psmprovider" behaviorconfiguration="securerest">         <clear />         <endpoint binding="webhttpbinding" bindingconfiguration="webinteropsecurebinding"                      name="psmprovider" contract="psmdataprovider.ipsmprovider" behaviorconfiguration="webhttpbehavior" />         <endpoint address="mex" binding="mexhttpsbinding" name="mex" contract="imetadataexchange" />         <host>           <baseaddresses>             <add baseaddress="https://localhost:44300/psmprovider/" />           </baseaddresses>         </host>       </service>     </services>     <behaviors>       <servicebehaviors>         <behavior name="securerest">           <servicemetadata httpgetenabled="false" httpsgetenabled="true" />           <servicedebug includeexceptiondetailinfaults="true" />           <serviceauthorization serviceauthorizationmanagertype="psmdataprovider.security.customauthorizationmanager, psmdataprovider"/>         </behavior>       </servicebehaviors>       <endpointbehaviors>         <behavior name="webhttpbehavior">           <webhttp/>         </behavior>       </endpointbehaviors>     </behaviors>     <servicehostingenvironment aspnetcompatibilityenabled="true" multiplesitebindingsenabled="true" />   </system.servicemodel> 

note

also note comment travich regarding iis / iis express configuration

travich said... 1 thing other users. briefly stated, overlooked... turn off basic auth in iis , remove tag webhttpbinding!

works me.


Comments

Popular posts from this blog

matlab - Deleting rows with specific rules -

php - MySQLi multi_query results for later use -