How to obtain FedAuth Cookie From On Premise SharePoint 2013 and ADFS

一个人想着一个人 提交于 2019-12-07 09:45:57

问题


I have a test environment set up using windows server 2012 R2, ADFS and sharepoint 2013. I can successfully login to Sharepoint 2013 using ADFS as the Claims Identity provider. Now I am trying to login to Sharepoint from my C# application.

I am able to request the saml assertion token from adfs using the following.

Now i would like help with posting the saml token to SharePoint and retrieve a FedAuth cookie so I can passively login to SharePoint 2013 and upload a document from a C# application.

When I call the last method PostSharePointSTS() No Cookies are set.

most of the code has been the help of Leandro Boffi

[TestMethod]
public void GetSamlTestMethod()
{
  var client = new WebClient();

  client.Headers.Add("Content-Type", "application/soap+xml; charset=utf-8");
  string username = "Administrator@2012r2.local";
  string password = "Password1";
  string adfsServer = "https://logon.2012r2.local/adfs/services/trust/2005/UsernameMixed";
  string sharepoint = "https://portal.2012r2.local/_trust/";
  var samlRequest = GetSAML()
    .Replace("[Username]", username)
    .Replace("[Password]", password)
    .Replace("[To]", adfsServer)
    .Replace("[applyTo]", sharepoint);

  var result = client.UploadString(
          address: "https://logon.2012r2.local/adfs/services/trust/2005/UsernameMixed",
          method: "POST",
          data: samlRequest);

          PostSharePointSTS( GetSAMLAssertion(result) );

}
private static string GetSAMLAssertion(string response)
{

  XDocument samlResponse = XDocument.Parse( response);

  // Check response xml for faults/errors
  if(samlResponse.Root == null)
    throw new ApplicationException("Invalid response received from authentication service.");

  XNamespace s = "http://www.w3.org/2003/05/soap-envelope";
  XNamespace psf = "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault";
  XNamespace wst = "http://schemas.xmlsoap.org/ws/2005/02/trust"; // "http://docs.oasis-open.org/ws-sx/ws-trust/200512";// 
  XNamespace wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy";
  XNamespace wsa = "http://www.w3.org/2005/08/addressing";
  XNamespace wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
  const string saml = "urn:oasis:names:tc:SAML:1.0:assertion";

  // the logon token is in the SAML assertion element of the message body
  XDocument xDoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);
  var assertion = from e in xDoc.Descendants()
                  where e.Name == XName.Get("Assertion", saml)
                  select e;

 string samlAssertion = assertion.FirstOrDefault().ToString();     

  // for some reason the assertion string needs to be loaded into an XDocument
  // and written out for for the XML to be valid. Otherwise we get an invalid
  // XML error back from ADFSs
  XDocument doc1 = XDocument.Parse(samlAssertion);
  samlAssertion = doc1.ToString(SaveOptions.DisableFormatting);
  return samlAssertion;

}



   private static string GetSAML()
    {
      const string saml = @"<?xml version='1.0' encoding='utf-8' ?>

<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope' xmlns:a='http://www.w3.org/2005/08/addressing' xmlns:u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>
    <s:Header>
        <a:Action s:mustUnderstand='1'>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
        <a:ReplyTo>
            <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand='1'>[To]</a:To>
        <o:Security s:mustUnderstand='1' xmlns:o='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'>
            <o:UsernameToken>
                <o:Username>[Username]</o:Username>
                <o:Password>[Password]</o:Password>
            </o:UsernameToken>
        </o:Security>
    </s:Header>
    <s:Body>
        <t:RequestSecurityToken xmlns:t='http://schemas.xmlsoap.org/ws/2005/02/trust'>
            <wsp:AppliesTo xmlns:wsp='http://schemas.xmlsoap.org/ws/2004/09/policy'>
                <a:EndpointReference>
                    <a:Address>[applyTo]</a:Address>
                </a:EndpointReference>
            </wsp:AppliesTo>
            <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
            <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
            <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
        </t:RequestSecurityToken>
    </s:Body>
</s:Envelope>";
      return saml;
    }
private static void PostSharePointSTS(string assertion)
{

  // Submit the BinarySecurityToken to SPO and retrieve response
 var loginUri = new Uri("https://logon.2012r2.local/adfs/ls?wa=wsignin1.0&wtrealm=urn:sharepoint:portal");
  var requestCookies = new CookieContainer();

  var request = (HttpWebRequest)WebRequest.Create(loginUri);
  request.AllowAutoRedirect = false;
  request.ContentType = "application/x-www-form-urlencoded";
  request.ContentLength = assertion.Length;
  request.CookieContainer = requestCookies;
  request.Method = "POST";
  request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)";

  using(var requestWriter = new StreamWriter(request.GetRequestStream()))
  {
    requestWriter.Write(assertion);
    requestWriter.Close();
  }

  var response = (HttpWebResponse)request.GetResponse();
  switch(response.StatusCode)
  {
    case HttpStatusCode.OK:
    case HttpStatusCode.Found:
    break;

    // TODO: Log error?
    //default:
    //return false;
  }

}

When I try to Post the given SAML token to SharePOint I get the following. But no cookies are set.

HTTP/1.1 302 Found
Content-Length: 0
Content-Type: text/html; charset=utf-8
Location: https://logon.2012r2.local:443/adfs/ls/wia?wa=wsignin1.0&wtrealm=urn:sharepoint:portal
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 16 Aug 2014 10:55:51 GMT

    This response did not set any cookies.
This response did not contain a P3P Header.

Validate P3P Policies at: http://www.w3.org/P3P/validator.html
Learn more at: http://fiddler2.com/r/?p3pinfo

回答1:


Why don't you just use the standard SharePoint CSOM library to do whatever you want in SharePoint? CSOM does all the necessary ADFS interaction on behalf of the user on the SharePoint side automatically.



来源:https://stackoverflow.com/questions/25339348/how-to-obtain-fedauth-cookie-from-on-premise-sharepoint-2013-and-adfs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!