问题描述
我有一个使用Windows Server 2012 R2,ADFS和sharepoint 2013设置的测试环境。我可以使用ADFS作为Claims Identity提供程序成功登录到Sharepoint 2013。现在,我试图从我的C#应用程序登录到Sharepoint。
我可以使用以下命令从adfs请求saml断言令牌。
现在,我需要将saml令牌发布到SharePoint并检索FedAuth cookie的帮助,以便我可以被动地登录到SharePoint 2013并从C#应用程序上载文档。 / p>
当我调用最后一个方法PostSharePointSTS()时,未设置Cookie。
大多数代码是
[TestMethod]
public void GetSamlTestMethod()
{
var client = new WebClient();
client.Headers.Add( Content-Type, application / soap + xml; charset = utf-8);
字符串username = [email protected];
字符串密码= Password1;
string adfsServer = https://logon.2012r2.local/adfs/services/trust/2005/UsernameMixed;
string sharepoint = https://portal.2012r2.local/_trust/;
var samlRequest = GetSAML()
.Replace( [用户名],用户名)
.Replace( [密码],密码)
.Replace( ],adfsServer)
.Replace( [applyTo],sharepoint);
var result = client.UploadString(
地址: https://logon.2012r2.local/adfs/services/trust/2005/UsernameMixed,
方法: POST,
数据:samlRequest);
PostSharePointSTS(GetSAMLAssertion(result));
}
私有静态字符串GetSAMLAssertion(字符串响应)
{
XDocument samlResponse = XDocument.Parse(response);
//检查响应xml中是否存在错误/错误
if(samlResponse.Root == null)
throw new ApplicationException(从身份验证服务接收到无效响应。);
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;
//登录令牌位于消息正文的SAML声明元素中。
XDocument xDoc = XDocument.Parse(response,LoadOptions.PreserveWhitespace);
var assertion =来自xDoc.Descendants()
中的e,其中e.Name == XName.Get( Assertion,saml)
选择e;
字符串samlAssertion = assertion.FirstOrDefault()。ToString();
//由于某种原因,需要将断言字符串加载到XDocument
//中并写出,以使XML有效。否则,我们将从ADFS返回
// XML错误
XDocument doc1 = XDocument.Parse(samlAssertion);
samlAssertion = doc1.ToString(SaveOptions.DisableFormatting);
return samlAssertion;
}
私有静态字符串GetSAML()
{
const string saml = @<?xml版本='1.0'编码='utf-8'?>>
< s:信封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/寻址/匿名< / a:地址>
< / 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:User名称>
< o:密码> [密码]< / o:密码>
< / o:UsernameToken>
< / o:安全性>
< / 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(字符串断言)
{
//将BinarySecurityToken提交给SPO并检索响应
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;
请求。 ContentType = application / x-www-form-urlencoded;
request.ContentLength = assertion.Length;
request.CookieContainer = requestCookies;
request.Method = POST;
request.UserAgent = Mozilla / 5.0(兼容; 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 =(HttpWe bResponse)request.GetResponse();
switch(response.StatusCode)
{
case HttpStatusCode.OK:
case HttpStatusCode.Found:
break;
// TODO:记录错误?
//默认值:
//返回false;
}
}
当我尝试发布给定SAML令牌到SharePOint我得到以下信息。
HTTP / 1.1 302找到
内容长度:0
内容-类型:text / html; charset = utf-8
位置:https://logon.2012r2.local:443 / adfs / ls / wia?wa = wsignin1.0& wtrealm = urn:sharepoint:portal
服务器:Microsoft- HTTPAPI / 2.0
日期:2014年8月16日星期六10:55:51 GMT
此响应未设置任何cookie。
此响应不包含P3P标头。
在以下位置验证P3P策略:http://www.w3.org/P3P/validator.html
了解更多信息:http://fiddler2.com/r/?p3pinfo
为什么不使用标准SharePoint CSOM库在SharePoint中做什么? CSOM会自动在SharePoint端代表用户执行所有必需的ADFS交互。
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 = "[email protected]";
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
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.
这篇关于如何从本地SharePoint 2013和ADFS中获取FedAuth Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!