英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论