自更新至 RestSharp v110 之后,仅出现 401 未经授权错误。

huangapple go评论62阅读模式
英文:

Since update to RestSharp v110 only 401 unauthorized errors

问题

我们以以下方式使用了 RestSharp v107 而没有出现问题:

            RestClientOptions options = new RestClientOptions()
            {
                BaseUrl = new Uri(serviceUrl),
                PreAuthenticate = false,
                Timeout = cTimeout,
                UseDefaultCredentials = false,
                UserAgent = $"{Assembly.GetExecutingAssembly().GetName().Name}/{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}",
                Encoding = System.Text.Encoding.UTF8
            };
            _restClient = new RestClient(options);

            RestRequest request = new RestRequest("instancetoken", Method.Post);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            request.AddHeader("Accept", "text/plain");
            request.AddParameter(nameof(username), username);
            request.AddParameter(nameof(password), password);
            RestResponse response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

现在使用 v110 我们必须做一些更改,尝试了以下方式:

            RestClientOptions options = new RestClientOptions()
            {
                BaseUrl = new Uri(serviceUrl),
                Authenticator = string.IsNullOrEmpty(instanceToken) ? new HttpBasicAuthenticator(username, password) : (IAuthenticator)new JwtAuthenticator(instanceToken),
                MaxTimeout = cTimeout,
                UseDefaultCredentials = false,
                UserAgent = $"{Assembly.GetExecutingAssembly().GetName().Name}/{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}",
                Encoding = System.Text.Encoding.UTF8
            };
            _restClient = new RestClient(options);
            RestRequest request = new RestRequest("instancetoken", Method.Post);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            request.AddHeader("Accept", "text/plain");
            RestResponse response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

现在的问题是:我们在这里做错了什么?这样做只会得到 401 认证失败的错误。

---

编辑:抱歉忘了提及一件事。我曾使用实例令牌的setter来设置jwt的验证器(如果需要的话)。现在它是只读的:

        private string _instanceToken = null;
        /// <summary>
        /// 获取或设置当前实例令牌。
        /// </summary>
        public string InstanceToken
        {
            get => _instanceToken;
            private set
            {
                if (_instanceToken != value)
                {
                    _instanceToken = value;
                    _restClient.Authenticator = string.IsNullOrEmpty(value) ? null : (IAuthenticator)new JwtAuthenticator(value);
                    OnPropertyChanged("InstanceToken");
                    OnPropertyChanged("IsConnected");
                }
            }
        }
英文:

We used RestSharp v107 without problems this way:

        RestClientOptions options = new RestClientOptions()
        {
            BaseUrl = new Uri(serviceUrl),
            PreAuthenticate = false,
            Timeout = cTimeout,
            UseDefaultCredentials = false,
            UserAgent = $"{Assembly.GetExecutingAssembly().GetName().Name}/{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}",
            Encoding = System.Text.Encoding.UTF8
        };
        _restClient = new RestClient(options);

        RestRequest request = new RestRequest("instancetoken", Method.Post);
        request.AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        request.AddHeader("Accept", "text/plain");
        request.AddParameter(nameof(username), username);
        request.AddParameter(nameof(password), password);
        RestResponse response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

Now with v110 we had to change some things and tried it this way:

        RestClientOptions options = new RestClientOptions()
        {
            BaseUrl = new Uri(serviceUrl),
            Authenticator = string.IsNullOrEmpty(instanceToken) ? new HttpBasicAuthenticator(username, password) : (IAuthenticator)new JwtAuthenticator(instanceToken),
            MaxTimeout = cTimeout,
            UseDefaultCredentials = false,
            UserAgent = $"{Assembly.GetExecutingAssembly().GetName().Name}/{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}",
            Encoding = System.Text.Encoding.UTF8
        };
        _restClient = new RestClient(options);
        RestRequest request = new RestRequest("instancetoken", Method.Post);
        request.AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        request.AddHeader("Accept", "text/plain");
        RestResponse response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

So now the question: What are we doing wrong here? This way I only get 401 authentication failed errors.


Edit: Sorry forgot to mention one thing. I had used the setter of the instance token to set the authenticator of the jwt if needed. Now it is read only:

    private string _instanceToken = null;
    /// <summary>
    /// Gets or sets the current instance token.
    /// </summary>
    public string InstanceToken
    {
        get => _instanceToken;
        private set
        {
            if (_instanceToken != value)
            {
                _instanceToken = value;
                _restClient.Authenticator = string.IsNullOrEmpty(value) ? null : (IAuthenticator)new JwtAuthenticator(value);
                OnPropertyChanged("InstanceToken");
                OnPropertyChanged("IsConnected");
            }
        }
    }

答案1

得分: 2

Here is the translated code snippet:

根据您的评论和更新的问题,我认为这个方法会起作用。我可能仍然对情况有所误解,但仍然如下:

RestClientOptions options = new RestClientOptions()
{
    BaseUrl = new Uri(serviceUrl),
    Authenticator = string.IsNullOrEmpty(instanceToken) ? null : new JwtAuthenticator(instanceToken),
    MaxTimeout = cTimeout,
    UserAgent = userAgent,
};
_restClient = new RestClient(options);
var request = new RestRequest("instancetoken", Method.Post);
if (string.IsNullOrEmpty(instanceToken))
{
    request
        .AddParameter(nameof(username), username)
        .AddParameter(nameof(password), password);
}
var response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

它只有在提供令牌时才设置身份验证器,并为表单添加了两个参数。我删除了设置Content-Type(POST调用默认使用url编码表单)和Accept标头的代码,因为它们默认情况下已设置。

英文:

Based on your comments and updated question, I think this would work. I might still misunderstand the case, but still:

RestClientOptions options = new RestClientOptions()
{
    BaseUrl = new Uri(serviceUrl),
    Authenticator = string.IsNullOrEmpty(instanceToken) ? null : new JwtAuthenticator(instanceToken),
    MaxTimeout = cTimeout,
    UserAgent = userAgent,
};
_restClient = new RestClient(options);
var request = new RestRequest("instancetoken", Method.Post);
if (string.IsNullOrEmpty(instanceToken))
{
    request
        .AddParameter(nameof(username), username)
        .AddParameter(nameof(password), password);
}
var response = await _restClient.ExecuteAsync(request).ConfigureAwait(true);

It won't set the authenticator if there's no token supplied, and add two parameters for the form. I removed the code that sets the Content-Type (POST calls are by default using url-encoded form) and Accept headers as they are set by default anyway.

huangapple
  • 本文由 发表于 2023年4月11日 15:29:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75983414.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定