c# - WCF Authentication - An error occurred when verifying security for the message -
i have problem connecting wcf service clientcredentialtype="username"
.
when run code below error
faultexception: error occurred when verifying security message.
when playing around of binding values access denied.
.
fiddler says there no authorization header , cannot find username or password in request either.
here excerpts config:
<system.webserver> <modules runallmanagedmodulesforallrequests="true"/> </system.webserver> <services> <service name="inventoryservices.mobileapi" behaviorconfiguration="custombehaviour"> <endpoint address="" binding="basichttpbinding" bindingconfiguration="securehttpbinding" contract="inventoryservices.imobileapi"/> <endpoint address="mex" binding="mexhttpsbinding" contract="imetadataexchange" /> </service> </services> <behaviors> <servicebehaviors> <behavior name="custombehaviour"> <servicesecurityaudit auditloglocation="application" serviceauthorizationauditlevel="failure" messageauthenticationauditlevel="failure" suppressauditfailure="true" /> <!-- avoid disclosing metadata information, set value below false , remove metadata endpoint above before deployment --> <servicemetadata httpsgetenabled="true"/> <!-- receive exception details in faults debugging purposes, set value below true. set false before deployment avoid disclosing exception information --> <servicedebug includeexceptiondetailinfaults="true"/> <servicecredentials> <usernameauthentication usernamepasswordvalidationmode="custom" customusernamepasswordvalidatortype="inventorylibrary.helpers.userauthentication,inventorylibrary"/> </servicecredentials> </behavior> </servicebehaviors> </behaviors> <servicehostingenvironment multiplesitebindingsenabled="true" /> <bindings> <basichttpbinding> <binding name="securehttpbinding"> <security mode="transportwithmessagecredential"> <transport clientcredentialtype="basic" proxycredentialtype="basic" realm="myrealm"/> <message clientcredentialtype="username" algorithmsuite="default" /> </security> </binding> </basichttpbinding> </bindings>
my username/password validator looks so:
public class userauthentication : usernamepasswordvalidator { public override void validate(string username, string password) { entitiescontext db = new entitiescontext(); db.logs.add(new domainmodels.log() { datelogged = datetime.now, message = "hit auth", type = domainmodels.logtype.info }); db.savechanges(); try { if (username == "test" && password == "test123") { console.writeline("authentic user"); } } catch (exception ex) { throw new faultexception("unknown username or incorrect password"); } } }
i have simple test on service:
[operationcontract] [xmlserializerformat] void test(); [principalpermission(securityaction.demand, name = "test")] public void test() { }
i have self signed ssl certificate on server , can access service/metadata.
then have added service reference in console application, , attempt connect service code below:
class program { static void main(string[] args) { stuff.initiatessltrust(); basichttpbinding binding = new basichttpbinding(); binding.security.mode = basichttpsecuritymode.transport; binding.security.transport.realm = "myrealm"; servicereference1.mobileapiclient serviceproxy = new servicereference1.mobileapiclient(binding, new endpointaddress("https://xx.xx.xx.xx/inventoryservices.mobileapi.svc")); serviceproxy.clientcredentials.username.username = "test"; serviceproxy.clientcredentials.username.password = "test123"; try { var = serviceproxy.login("a", "b"); } catch (exception ex) { var ex2 = ex; } } } public class stuff { public static void initiatessltrust() { try { //change ssl checks checks pass servicepointmanager.servercertificatevalidationcallback = new remotecertificatevalidationcallback( delegate { return true; } ); } catch (exception ex) { } } }
i've checked event viewer on server , error appears each request:
messagesecurityexception: security processor unable find security header in message. might because message unsecured fault or because there binding mismatch between communicating parties. can occur if service configured security , client not using security.
you specifying client side use basichttpsecuritymode.transport
whereas service expecting basichttpsecuritymode.transportwithmessagecredential
. problem because service looking client credentials in soap message header , client not send them binding configured way.
hence, why username/password pair not present in message header witnessing. event viewer correct there binding mismatch between communicating parties.
also set clientcredentialtype
on client basichttpmessagecredentialtype.username
message
level security. default basichttpbinding
uses none
anonymous clients.
here's code snippet describing above changes:
var basichttpbinding = new basichttpbinding( basichttpsecuritymode.transportwithmessagecredential); basichttpbinding.security.message.clientcredentialtype = basichttpmessagecredentialtype.username;
Comments
Post a Comment