Pergunta

Estou trabalhando em um aplicativo baseado em REST que se conecta ao Office365.O aplicativo estará disponível em múltiplas plataformas, então criei uma biblioteca de classes portátil para lidar com toda a lógica, incluindo autenticação.O PCL é direcionado ao Windows Phone 7.1 e versões posteriores e inclui as bibliotecas de cliente HTTP da Microsoft (NuGet), que são necessárias para aplicativos do Windows Phone 7.1.

A última etapa da autenticação do Office365 é obter um cookie FedAuth do site, e é aí que estou tendo um problema.

O código que uso para obter o cookie é:

var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));

A variável 'host' é apenas a URL do site do Office365 e o binarySecurityToken que recebi de solicitações anteriores.Essas coisas funcionam igualmente bem em todos os aplicativos:Quer eu execute o código PCL no contexto de um aplicativo do Windows Phone 7.1, do Windows Phone 8, do Windows 8 ou até mesmo de um aplicativo de console, recebo exatamente a mesma resposta (veja abaixo), que contém o cookie FedAuth.Isso eu verifiquei usando o Fiddler.

Então tento fazer com que o cookie seja reutilizado em solicitações subsequentes.

var cookieCollection = handler.CookieContainer.GetCookies(new Uri(host));
foreach (var cookie in cookieCollection)
{
    if (cookie.Name.StartsWith("FedAuth"))
    {
        //TODO: Store the cookie.
        return true;
    }
}

Isso leva ao seguinte resultado:No Windows Phone 7.1, a variável 'cookieCollection' contém apenas o cookie rtFa'.Nas outras plataformas contém todos os três cookies 'RpsContextCookie', 'rtFa', 'FedAuth'.

O Windows Phone 7.1 difere dos outros aplicativos porque é a única plataforma que realmente usa o HttpClient do pacote NuGet.As outras plataformas possuem um HttpClient nativo que é trocado pela magia do PCL.

Parece provável que o problema seja causado pelo cookie FedAuth não ter um domínio.Eu tentei usar .GetCookies(null) e diferentes variações de .GetCookies(new Uri("something", UriKind.Relative)), que resultam em uma exceção.Também tentei alterar a maioria das propriedades do HttpClientHandler sem sorte.

Alguém encontrou esse problema e talvez o tenha resolvido?Ou apenas uma sugestão sobre o que eu poderia tentar?

A resposta que recebo no .PostAsync acima é a mesma em todas as plataformas e, de acordo com o Fiddler, a resposta bruta é:

HTTP/1.1 302 Found
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Location: /
Server: Microsoft-IIS/7.5
X-SharePointHealthScore: 0
X-AspNet-Version: 4.0.30319
Set-Cookie: RpsContextCookie=; path=/
Set-Cookie: rtFa=+13jGMMp0A0V+driESaO30ixYclFCRjEvS2jMSwXPfQcrefiJvLEExxYu7V+1JZHM6X5JWeuL70jb3/N/Q/hUTwoAiC/XLJZ1QfERi4aUt8AAVF4ekcNyMdWnj65foDwPkhaV5z8whNSZQigBFD/2Vc1xMTH0ukHbS4cbtJO5U28/4g66vgIZg7dGpNOZg2jDt+HF3GSQ4/W+T1oS9/F5e+Pbwd0p8mqPhkGjL+M7IptmkeHoIqVcS4Ps25dM6q1AniLiv/3NujYmrQjseaEYZ2aaCfc7ZHX7LygBZm8KsoGNyTYRPmC+hZ7tsDq6wfto+xVpX1scggsU0+Qty3DPWUiwy1bBy8JR0znFG0+eDt9uBOQzqfOSjVvd8WNIKUFIAAAAA==; domain=sharepoint.com; path=/; HttpOnly
Set-Cookie: FedAuth=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+RmFsc2UsMGguZnxtZW1iZXJzaGlwfDEwMDMwMDAwODc5MTUwMGVAbGl2ZS5jb20sMCMuZnxtZW1iZXJzaGlwfHRtakB3aWxkY293Lm9ubWljcm9zb2Z0LmNvbSwxMzAzNDIwOTYxNDAxMTIxMzMsRmFsc2UsV2lSQjlUVTdOSTk0MUpKRWZ5d1JDNTFPYUphMVpWNkJqWWdaVGM3MU00U3lqL2VkTnF6dVJpbXdEMnpEWk9oR1lybkFsNnpWb3M4V0FBZDk1VVYrZkt5dlkwQ3dqRTlyaEhEc256bkZUeENoODU1Rm1JZmxoYVBkMTFQS2VjWnFJN0N4OUxUOHk4enZDaVNUTGNQMzR2K3NOeHk1YXBMZ2NIWDNHR3JMcG1Ic24rQzAzUkUzakNDQWhma2F3RVRQbk03R3JycVk5amJseHJmNVNhNHZxMk91NlN1cGszZnpQMUZQTzJBc1UrRXZvSDgvWTllR2Y3c2x2dStvMnVlN3hZLy9VQ1lYU1U4b3AzckZ6c2laK0wwN1NrUnZYMTZjVklUVVZJZ0x6TGIxaTJLd2lwNGp6RHgwRFdmVWF0Rk42UVFaNWhHRzMyOHRJZjI2RXo4YldnPT0saHR0cHM6Ly93aWxkY293LnNoYXJlcG9pbnQuY29tLzwvU1A+; path=/; secure; HttpOnly
SPRequestGuid: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
request-id: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
SPRequestDuration: 125
SPIisLatency: 2
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.2308
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
Date: Thu, 09 Jan 2014 21:46:53 GMT
Content-Length: 118

<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/">here</a>.</h2>
</body></html>
Foi útil?

Solução

Encontrei uma resposta do tipo aqui: Acessando cookies HTTPOnly do Windows Phone 8/PCL.

Lendo o post percebi que cometi um erro acima:Eu não estava recebendo o cookie ‘rtFa’ no aplicativo Windows Phone 7.1, mas sim o ‘RpsContextCookie’.Os cookies que não consegui acessar foram marcados com HttpOnly.

Também percebi que não preciso acessar os cookies diretamente.Em vez disso, eu poderia simplesmente reutilizar o handler.CookieContainer.Então meu código agora está assim:

var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));
this._cookieContainer = handler.CookieContainer;
return true;

this._cookieContainer é apenas um campo com escopo de classe para armazenamento do contêiner de cookies.Então, uma vez autenticado e fazendo as solicitações que são o verdadeiro propósito do aplicativo, faço o seguinte:

var handler = new HttpClientHandler(){ CookieContainer = this._cookieContainer };
var client = new HttpClient(handler);
var response = await client.GetAsync(host + "something");

Portanto, o resultado final é:Não consigo acessar os cookies HttpOnly - mas não preciso.Acabei de reutilizar o contêiner de cookies e os cookies são incluídos automaticamente na próxima solicitação.

Isso funciona em aplicativos do Windows Phone 7.1, aplicativos do Windows Phone 8, aplicativos de console, etc.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top