c# - Authentication using HTTP Authorization Header in WCF SOAP API -


we have wcf soap api allows consumer authenticate using username , password (internally uses usernamepasswordvalidator) reference username , password passed in soap body follows:

<o:security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" mustunderstand="1"> <timestamp id="_0">     <created>         2013-04-05t16:35:07.341z</created>         <expires>2013-04-05t16:40:07.341z</expires>     </timestamp>     <o:usernametoken id="uuid-ac5ffd20-8137-4524-8ea9-3f4f55c0274c-12">         <o:username>someusername</o:username>         <o:password o:type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#passwordtext">somepassword     </o:password> </o:usernametoken> </o:security> 

we additionally support consumer specify credentials in http authorization header, either basic auth, or oauth bearer token

we have several ways of doing authentication non-soap apis, not familiar how tell wcf use class might create this. how can accomplish this? other question have seen attempts answer here, accepted answer uses soap headers, not http headers, , asker gave up.

obviously solution needs backwards compatible - need continue support consumers specifying credentials in soap security header.

one of ways can go using messageinspectors.
this:

first - create message inspector - responsible add header credentials

using system; using system.collections.generic; using system.io; using system.text; using system.servicemodel.dispatcher; using system.servicemodel.channels; using system.servicemodel; using system.xml;  namespace your_namespace {       /// <summary>     /// /************************************     /// *      /// * creating message inspector      /// * updating outgoing messages caller identifier header     /// * read http://msdn.microsoft.com/en-us/magazine/cc163302.aspx     /// * more details     /// *      /// *********************/     /// </summary>     public class credentialsmessageinspector : idispatchmessageinspector,         iclientmessageinspector     {         public object afterreceiverequest(ref message request,             iclientchannel channel,             instancecontext instancecontext)         {             return null;         }          public void beforesendreply(ref message reply, object             correlationstate)         { #if debug             //// leave empty              //messagebuffer buffer = reply.createbufferedcopy(int32.maxvalue);             //message message = buffer.createmessage();             ////assign copy ref received             //reply = buffer.createmessage();               //stringwriter stringwriter = new stringwriter();             //xmltextwriter xmltextwriter = new xmltextwriter(stringwriter);             //message.writemessage(xmltextwriter);             //xmltextwriter.flush();             //xmltextwriter.close();              //string messagecontent = stringwriter.tostring(); #endif                      }          public void afterreceivereply(ref message reply, object             correlationstate)         { #if debug             //// leave empty              //messagebuffer buffer = reply.createbufferedcopy(int32.maxvalue);             //message message = buffer.createmessage();             ////assign copy ref received             //reply = buffer.createmessage();               //stringwriter stringwriter = new stringwriter();             //xmltextwriter xmltextwriter = new xmltextwriter(stringwriter);             //message.writemessage(xmltextwriter);             //xmltextwriter.flush();             //xmltextwriter.close();              //string messagecontent = stringwriter.tostring(); #endif         }          public object beforesendrequest(ref message request,             iclientchannel channel)         {             request = credentialshelper.addcredentialsheader(ref request);             return null;         }          #region idispatchmessageinspector members          #endregion     } } 

second - add code add header

using system; using system.collections.generic; using system.linq; using system.runtime.compilerservices; using system.text; using system.servicemodel.channels; using system.servicemodel;  namespace your_namespace {      public class credentialshelper     {        // siple string example - can use data structure here         private static readonly string credentialsheadername = "mycredentials";         private static readonly string credentialsheadernamespace = "urn:urn_probably_like_your_namespance";          /// <summary>         /// update message credentials         /// </summary>         public static message addcredentialsheader(ref message request)         {            string user = "john";           string password = "doe";              string cred = string.format("{0},{1}",   user, password);              // add header             messageheader<string> header = new messageheader<string>(cred);             messageheader untyped = header.getuntypedheader(credentialsheadername, credentialsheadernamespace);              request = request.createbufferedcopy(int.maxvalue).createmessage();             request.headers.add(untyped);              return request;         }          /// <summary>         /// details of current credentials client-side added incoming headers         ///          /// return empty credentials when empty credentials specified          /// or when exception occurred         /// </summary>         public static string getcredentials()         {             string credentialdetails = string.empty;             try             {                 credentialdetails = operationcontext.current.incomingmessageheaders.                     getheader<string>                         (credentialsheadername, credentialsheadernamespace);             }             catch             {                     // todo: ...             }             return credentialdetails;         }      } } 

third - credentials on server side

public void myserversidemethod() {    string credentials = credentialshelper.getcredentials();    . . .  } 

hope helps.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -