Sharepoint 2013 -如何注销WinRT客户端

本文关键字:注销 WinRT 客户端 2013 何注销 Sharepoint | 更新日期: 2023-09-27 18:18:38

我们已经编写了一个连接到Sharepoint 2013的WinRT应用程序。我们能够验证并登录到sharepoint,但是我们在注销"进程"时遇到了问题。登录的实现如下:

我们正在使用相应的用户凭据和域信息设置HttpClient。配置被封装在HttpClientConfig类中,并传递给包含HttpClient对象的HttpClientService。之后,我们从sharepoint检索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,我们可能会在这个失败中运行,使用错误的前一个用户的凭据/用户上下文访问。

我观察的另一件事是密码更改后的行为。在应用程序重新启动之前,旧密码仍然有效。

所以我将非常感谢sharepoint REST专家的一些提示或建议如何解决这个问题。

Sharepoint 2013 -如何注销WinRT客户端

我猜你是在为Windows 10创建一个通用应用程序。在这种情况下,没有其他选择,只能重新启动应用程序,看看这个答案。

HTTP凭证和cookie不一样,所以重置cookie是没有用的。

但是,如果您在Windows 8/8.1项目(不是Universal项目)中使用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));
}