Мы без проблем использовали 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 ошибку аутентификации.
Обновлено: извините, забыл упомянуть одну вещь. Я использовал установщик токена экземпляра, чтобы установить аутентификатор jwt, если это необходимо. Теперь только для чтения:
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");
}
}
}
@AlexeyZimarev Вы правы, но, к сожалению, я забыл упомянуть одну важную вещь. Я отредактировал свой вопрос соответственно. Кстати. извините, что так долго не отвечала, легла приболеть...
И в зависимости от контента... было бы правильно, если бы сервер работал как положено... пусть будет... не хочу спорить с коллегой ;)
HttpBasicAuthenticator
работает, кодируя пару username:password
в hex64 и устанавливая ее в качестве заголовка аутентификации. Он не добавляет параметры в форму.
Основываясь на ваших комментариях и обновленном вопросе, я думаю, что это сработает. Я могу все еще неправильно понимать дело, но все же:
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
, поскольку они в любом случае установлены по умолчанию.
Вы не использовали аутентификатор раньше, зачем вам нужно использовать его сейчас? Код, который у вас был для версии 107, должен точно так же работать с версией 110. Вам также следует избегать установки типа контента вручную, это несколько раз упоминается в документах. Базовый аутентификатор не добавляет параметры имени пользователя и пароля, он устанавливает заголовок аутентификации в шестнадцатеричное кодированное значение. restsharp.dev/authenticators.html