Sharepoint 2013 - 如何注销 WinRT 客户端
Sharepoint 2013 - How to logout a WinRT Client
我们编写了一个连接到 Sharepoint 2013 的 WinRT 应用程序。
我们能够验证并登录共享点,但我们在注销 'process' 时遇到问题。登录实现如下:
我们正在使用相应的用户凭据和域信息设置 HttpClient。配置包装在 HttpClientConfig class 中,并传送到包含 HttpClient object 的 HttpClientService。
之后,我们从共享点检索 formdigestValue
并在每个请求中使用 X-RequestDigest Header 中的令牌。如果令牌超时,我们会取回一个新令牌。
这是我们如何实现上述身份验证的一些代码。
public async Task Inialize()
{
var httpConfig = new HttpClientConfig();
httpConfig.Headers.Add("Accept", "application/json;odata=verbose");
httpConfig.Headers.Add("User-Agent", _userAgent);
httpConfig.DefaultTimeout = Statics.DEFAULT_NETWORK_TIMEOUT_SECONDS;
httpConfig.PreAuthenticate = true;
httpConfig.NetworkCredentials = new NetworkCredential(username, password, _domain);
_httpClientService.ResetCookies();
_httpClientService.ConfigureHttpClient(httpConfig);
}
ConfigureHttpClient 方法处理一个旧的 HttpClient 实例并创建一个新的 HttpClient 实例,如下所示:
public void ConfigureHttpClient(HttpClientConfig config, bool disposeCurrent = true)
{
_config = config;
if (disposeCurrent)
{
DisposeHttpClient();
}
_httpClient = CreateHttpClient(config);
if (disposeCurrent)
{
//make sure remove old httpclient and httpclienthandler instances after they are not hold anywhere else
GC.Collect();
}
_httpClientDisposed = false;
}
public HttpClient CreateHttpClient(HttpClientConfig config)
{
_httpClientHandler = _httpClientFactoryService.CreateHttpClientHandler();
_httpClientHandler.CookieContainer = _cookieContainer;
_httpClientHandler.UseCookies = true;
_httpClientHandler.AllowAutoRedirect = config.AllowAutoRedirect;
_httpClientHandler.PreAuthenticate = config.PreAuthenticate;
if (config.NetworkCredentials != null)
{
_httpClientHandler.Credentials = config.NetworkCredentials;
}
var client = _httpClientFactoryService.CreateHttpClient(_httpClientHandler, true);
client.Timeout = TimeSpan.FromSeconds(config.DefaultTimeout);
if (config.UseGzipCompression)
{
if (_httpClientHandler.SupportsAutomaticDecompression)
{
_httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip;
client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));
}
}
return client;
}
public void DisposeHttpClient()
{
var client = _httpClient;
_httpClientDisposed = true; //set flag before disposing is done to be able to react correctly!
if (client != null)
{
client.Dispose();
}
var handler = _httpClientHandler;
if (handler != null)
{
handler.Dispose();
}
GC.Collect();
}
public async Task<object> InitNewSharepointSession(bool useCookies = true)
{
var config = _httpClientService.CurrentClientConfig;
config.UseCookies = useCookies;
var res = await getRequestDigestAsync();
if (res.IsSuccess)
{
SharepointContextInformation = res.Response;
if (config.Headers.ContainsKey("X-RequestDigest"))
{
config.Headers.Remove("X-RequestDigest");
}
config.Headers.Add("X-RequestDigest", SharepointContextInformation.FormDigestValue);
return new DataServiceResponse<bool>(true);
}
else
{
return new DataServiceResponse<bool>(res.Error);
}
}
ResetCookies 方法只处理旧的 cookies 列表:
public void ResetCookies()
{
_cookieContainer = new CookieContainer();
}
如您所见,我们使用了一些 GC.Collect() 调用,这显示了我们根据注销内容的无助。
对于注销,我们只需处理我们的 httpclient。
但出于某种原因,如果我们用另一个用户登录,有时我们会得到前一个用户的数据,这对我们来说是一个评价很高的错误。
如果我们重新启动应用程序,一切都很好,但是如果我们只处理当前用户 httpClient,我们可能会 运行 在此故障中访问前一个用户的错误 credential/user 上下文。
我观察的另一件事是密码更改后的行为。旧密码一直有效,直到应用程序重新启动。
因此,我将非常感谢 Sharepoint REST 专家关于如何解决此问题的一些提示或建议。
我猜你正在为 Windows 10 创建一个通用应用程序。在这种情况下,除了重新启动应用程序别无选择,。
HTTP 凭据与 cookie 不同,因此重置 cookie 无济于事。
但是,如果您在 Windows 8/8.1 项目(非通用项目)中使用 System.Net.Http.HttpClient
,则处理 HttpClient
应该可行。
带有 Windows 8/8.1 模板的示例。不要与通用模板一起使用。
private async void Foo()
{
// Succeeds, correct username and password.
await Foo("foo", "bar");
// Fails, wrong username and passord.
await Foo("fizz", "buzz");
}
private async Task Foo(string user, string password)
{
Uri uri = new Uri("http://heyhttp.org/?basic=1&user=foo&password=bar");
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential(user, password);
HttpClient client = new HttpClient(handler);
Debug.WriteLine(await client.GetAsync(uri));
}
我们编写了一个连接到 Sharepoint 2013 的 WinRT 应用程序。 我们能够验证并登录共享点,但我们在注销 'process' 时遇到问题。登录实现如下:
我们正在使用相应的用户凭据和域信息设置 HttpClient。配置包装在 HttpClientConfig class 中,并传送到包含 HttpClient object 的 HttpClientService。
之后,我们从共享点检索 formdigestValue
并在每个请求中使用 X-RequestDigest Header 中的令牌。如果令牌超时,我们会取回一个新令牌。
这是我们如何实现上述身份验证的一些代码。
public async Task Inialize()
{
var httpConfig = new HttpClientConfig();
httpConfig.Headers.Add("Accept", "application/json;odata=verbose");
httpConfig.Headers.Add("User-Agent", _userAgent);
httpConfig.DefaultTimeout = Statics.DEFAULT_NETWORK_TIMEOUT_SECONDS;
httpConfig.PreAuthenticate = true;
httpConfig.NetworkCredentials = new NetworkCredential(username, password, _domain);
_httpClientService.ResetCookies();
_httpClientService.ConfigureHttpClient(httpConfig);
}
ConfigureHttpClient 方法处理一个旧的 HttpClient 实例并创建一个新的 HttpClient 实例,如下所示:
public void ConfigureHttpClient(HttpClientConfig config, bool disposeCurrent = true)
{
_config = config;
if (disposeCurrent)
{
DisposeHttpClient();
}
_httpClient = CreateHttpClient(config);
if (disposeCurrent)
{
//make sure remove old httpclient and httpclienthandler instances after they are not hold anywhere else
GC.Collect();
}
_httpClientDisposed = false;
}
public HttpClient CreateHttpClient(HttpClientConfig config)
{
_httpClientHandler = _httpClientFactoryService.CreateHttpClientHandler();
_httpClientHandler.CookieContainer = _cookieContainer;
_httpClientHandler.UseCookies = true;
_httpClientHandler.AllowAutoRedirect = config.AllowAutoRedirect;
_httpClientHandler.PreAuthenticate = config.PreAuthenticate;
if (config.NetworkCredentials != null)
{
_httpClientHandler.Credentials = config.NetworkCredentials;
}
var client = _httpClientFactoryService.CreateHttpClient(_httpClientHandler, true);
client.Timeout = TimeSpan.FromSeconds(config.DefaultTimeout);
if (config.UseGzipCompression)
{
if (_httpClientHandler.SupportsAutomaticDecompression)
{
_httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip;
client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));
}
}
return client;
}
public void DisposeHttpClient()
{
var client = _httpClient;
_httpClientDisposed = true; //set flag before disposing is done to be able to react correctly!
if (client != null)
{
client.Dispose();
}
var handler = _httpClientHandler;
if (handler != null)
{
handler.Dispose();
}
GC.Collect();
}
public async Task<object> InitNewSharepointSession(bool useCookies = true)
{
var config = _httpClientService.CurrentClientConfig;
config.UseCookies = useCookies;
var res = await getRequestDigestAsync();
if (res.IsSuccess)
{
SharepointContextInformation = res.Response;
if (config.Headers.ContainsKey("X-RequestDigest"))
{
config.Headers.Remove("X-RequestDigest");
}
config.Headers.Add("X-RequestDigest", SharepointContextInformation.FormDigestValue);
return new DataServiceResponse<bool>(true);
}
else
{
return new DataServiceResponse<bool>(res.Error);
}
}
ResetCookies 方法只处理旧的 cookies 列表:
public void ResetCookies()
{
_cookieContainer = new CookieContainer();
}
如您所见,我们使用了一些 GC.Collect() 调用,这显示了我们根据注销内容的无助。 对于注销,我们只需处理我们的 httpclient。 但出于某种原因,如果我们用另一个用户登录,有时我们会得到前一个用户的数据,这对我们来说是一个评价很高的错误。 如果我们重新启动应用程序,一切都很好,但是如果我们只处理当前用户 httpClient,我们可能会 运行 在此故障中访问前一个用户的错误 credential/user 上下文。
我观察的另一件事是密码更改后的行为。旧密码一直有效,直到应用程序重新启动。
因此,我将非常感谢 Sharepoint REST 专家关于如何解决此问题的一些提示或建议。
我猜你正在为 Windows 10 创建一个通用应用程序。在这种情况下,除了重新启动应用程序别无选择,
HTTP 凭据与 cookie 不同,因此重置 cookie 无济于事。
但是,如果您在 Windows 8/8.1 项目(非通用项目)中使用 System.Net.Http.HttpClient
,则处理 HttpClient
应该可行。
带有 Windows 8/8.1 模板的示例。不要与通用模板一起使用。
private async void Foo()
{
// Succeeds, correct username and password.
await Foo("foo", "bar");
// Fails, wrong username and passord.
await Foo("fizz", "buzz");
}
private async Task Foo(string user, string password)
{
Uri uri = new Uri("http://heyhttp.org/?basic=1&user=foo&password=bar");
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential(user, password);
HttpClient client = new HttpClient(handler);
Debug.WriteLine(await client.GetAsync(uri));
}