title: How to use WebEx's XML-API with SSO (SAML)
body: <p>I am writing a small tool to open a WebEx with our support customers using the support ticket information.
  When the site used Username/Password I could make it work, now we use SSO.
  The WebEx server is already setup to accept SSO (by our IT manager - not me).</p>
  
  <p>The WebEx reference (linked below) does not elaborate, and the WebEx dev forum over the official site is so dormant, and void of answers about the subject, that I've decided to try my luck over here.<br/><a href="http://developer.cisco.com/web/webex-developer/forum/-/message_boards/message/9742789?p_p_auth=XqL6p8dS" rel="nofollow">posted this same question over the official forum</a></p>
  
  <p>Anyone have an idea how to make the code below actually work?
  What goes into the <code>&lt;samlResponse&gt;</code> tag and replace the below line in the code with something that will make it work:</p>
  
  <pre><code>    &lt;samlResponse&gt;samlResponse message will go here&lt;/samlResponse&gt;
  </code></pre>
  
  <p>What does <em>SAML assertion</em> in the documentation (see below) means?</p>
  
  <h2>What I've found out till now</h2>
  
  <p>WebEx's <a href="http://lksz.me/TYShyE" rel="nofollow">XML-API documentation</a> (Page 68) describes the following:</p>
  
  <blockquote>
    <p>3.1 AuthenticateUser</p>
    
    <p>The AuthenticateUser API will accept a SAML assertion in place of a user password. The 
     returned can be used for subsequent XML API requests without using 
     for the session duration as defined in Super Admin. This can take the place of the current requirement for a  and  for authentication.
    ...</p>
    
    <p>The following schema diagram shows the element structure of the AuthenticateUser request 
    message.</p>
  </blockquote>
  
  <p>And then it provide the XML schema diagram, and a sample.</p>
  
  <p>Referencing the example .NET code (which does not use SAML) I came up with the following code:</p>
  
  <pre><code>string strXMLServer = "https://varonis.webex.com/WBXService/XMLService";
  WebRequest request = WebRequest.Create(strXMLServer);
  // Set the Method property of the request to POST.
  request.Method = "POST";
  // Set the ContentType property of the WebRequest.
  request.ContentType = "application/x-www-form-urlencoded";
  
  // Create POST data and convert it to a byte array.
  Func&lt;StringBuilder, StringBuilder&gt; webExXML =
      bodySB =&gt; new StringBuilder(1024) // Currently 294 bytes in length
          .AppendLine("&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\"?&gt;")
          .Append("&lt;serv:message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
          .Append(" xmlns:serv=\"http://www.webex.com/schemas/2002/06/service\"")
          .Append(" xsi:schemaLocation=\"http://www.webex.com/schemas/2002/06/service")
          .Append(" http://www.webex.com/schemas/2002/06/service/service.xsd\"&gt;") 
          .AppendLine("&lt;header&gt;")
          .AppendLine("&lt;securityContext&gt;")
          .AppendLine("&lt;siteName&gt;siteName&lt;/siteName&gt;")
          .AppendLine("&lt;webExID&gt;username&lt;/webExID&gt;")
          .AppendLine("&lt;password&gt;&lt;/password&gt;")
          .AppendLine("&lt;partnerID&gt;&lt;/partnerID&gt;")
          .AppendLine("&lt;/securityContext&gt;")
          .AppendLine("&lt;/header&gt;")
          .AppendLine()
          .AppendLine("&lt;body&gt;")
          .Append(bodySB)
          .AppendLine()
          .AppendLine("&lt;/body&gt;")
          .AppendLine("&lt;/serv:message&gt;");
  
  var xmlAuthBodyContent = new StringBuilder()
      .AppendLine("&lt;bodyContent ")
      .AppendLine("xsi:type=\"java:com.webex.service.binding.user.AuthenticateUser\"&gt;")
      .AppendLine("&lt;samlResponse&gt;samlResponse message will go here&lt;/samlResponse&gt;")
      .AppendLine("&lt;/bodyContent&gt;");
  
  byte[] byteArray = Encoding.UTF8.GetBytes(webExXML(xmlAuthBodyContent).ToString());
  
  // Set the ContentLength property of the WebRequest.
  request.ContentLength = byteArray.Length;
  
  // Get the request stream.
  Stream dataStream = request.GetRequestStream();
  // Write the data to the request stream.
  dataStream.Write(byteArray, 0, byteArray.Length);
  // Close the Stream object.
  dataStream.Close();
  // Get the response.
  WebResponse response = request.GetResponse();
  
  DataSet DSResponse = new DataSet();
  DSResponse.ReadXml(response.GetResponseStream());
  DSResponse.GetXml().Dump();
  </code></pre>
  
  <p>The result I get is:</p>
  
  <pre><code>&lt;serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service"&gt;
  &lt;serv:header&gt;
      &lt;serv:response&gt;
      &lt;serv:result&gt;FAILURE&lt;/serv:result&gt;
      &lt;serv:reason&gt;Authentication Server can't generate a valid session ticket&lt;/serv:reason&gt;
      &lt;serv:gsbStatus&gt;PRIMARY&lt;/serv:gsbStatus&gt;
      &lt;serv:exceptionID&gt;030048&lt;/serv:exceptionID&gt;
      &lt;serv:subErrors&gt;
          &lt;serv:subError&gt;
          &lt;serv:exceptionID&gt;AS0062&lt;/serv:exceptionID&gt;
          &lt;serv:reason&gt;Validate assertion failed&lt;/serv:reason&gt;
          &lt;serv:value /&gt;
          &lt;/serv:subError&gt;
      &lt;/serv:subErrors&gt;
      &lt;/serv:response&gt;
  &lt;/serv:header&gt;
  &lt;serv:body&gt;
      &lt;serv:bodyContent /&gt;
  &lt;/serv:body&gt;
  &lt;/serv:message&gt;
  </code></pre>