You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6下RestSharp认证失败求助(Framework环境可正常运行)

RestSharp认证在.NET 6环境返回未授权问题排查与解决

问题背景

业务逻辑迁移至.NET Standard DLL(原RestSharp 106.15.0)后,在.NET Framework 4.6.1环境正常运行,但.NET 6下所有API调用均返回未授权。升级RestSharp至108.x版本后,虽能获取初始Bearer Token,但后续请求仍失败。已尝试更新NuGet包、切换HttpBasicAuthenticator、重写自定义认证器,均无效果。

代码片段

原客户端初始化(.NET Framework 4.6.1正常)

var client = new RestClient(baseUrl);
client.AddHandler("application/json", new JsonDeserializer());
client.Authenticator = new DayforceAuthenticator(client, credentials);

原自定义Authenticator与AuthenticationModule

public class DayforceAuthenticator : IAuthenticator
{
    private readonly RestClient _client;
    private readonly Credentials _credentials;
    private string _bearerToken;

    public DayforceAuthenticator(RestClient client, Credentials credentials)
    {
        _client = client;
        _credentials = credentials;
    }

    public void Authenticate(IRestClient client, IRestRequest request)
    {
        if (string.IsNullOrEmpty(_bearerToken))
        {
            _bearerToken = GetBearerToken().Result;
        }
        request.AddHeader("Authorization", $"Bearer {_bearerToken}");
    }

    private async Task<string> GetBearerToken()
    {
        var request = new RestRequest("/oauth/token", Method.POST);
        request.AddParameter("grant_type", "password");
        request.AddParameter("username", _credentials.Username);
        request.AddParameter("password", _credentials.Password);
        request.AddParameter("client_id", _credentials.ClientId);
        
        var response = await _client.ExecuteAsync<TokenResponse>(request);
        return response.Data.AccessToken;
    }
}

public class DayforceAuthenticationModule : IAuthenticationModule
{
    public bool CanAuthenticate(IHttpAuthenticator authenticator, IRestRequest request) 
        => authenticator is DayforceAuthenticator;

    public async Task Authenticate(IHttpAuthenticator authenticator, IRestRequest request, 
        IRestResponse response, CancellationToken cancellationToken)
    {
        var auth = authenticator as DayforceAuthenticator;
        await auth.RefreshToken();
        request.AddHeader("Authorization", $"Bearer {auth.BearerToken}");
    }
}

适配RestSharp 108的重写版DayforceAuthenticator

public class DayforceAuthenticator : AuthenticatorBase
{
    private readonly RestClient _client;
    private readonly Credentials _credentials;

    public DayforceAuthenticator(RestClient client, Credentials credentials) : base("")
    {
        _client = client;
        _credentials = credentials;
    }

    protected override async Task<AuthenticatorResult> GetAuthenticationToken(
        string accessToken, CancellationToken cancellationToken)
    {
        var request = new RestRequest("/oauth/token", Method.Post);
        request.AddParameter("grant_type", "password");
        request.AddParameter("username", _credentials.Username);
        request.AddParameter("password", _credentials.Password);
        request.AddParameter("client_id", _credentials.ClientId);
        
        var response = await _client.ExecuteAsync<TokenResponse>(request, cancellationToken);
        if (!response.IsSuccessful) throw new AuthenticationException("Failed to get token");
        
        return new AuthenticatorResult(response.Data.AccessToken)
        {
            ExpiresIn = response.Data.ExpiresIn
        };
    }
}

排查与解决步骤

  1. 校验请求头是否正确添加
    在.NET 6环境下,通过RestSharp的BeforeRequest事件输出请求头,确认Authorization是否被正确注入:
client.BeforeRequest += (sender, args) => 
{
    var authHeader = args.Request.Headers.FirstOrDefault(h => h.Name.Equals("Authorization", StringComparison.OrdinalIgnoreCase))?.Value;
    Console.WriteLine($"Auth Header: {authHeader}");
};

若未正确添加,检查认证器的生命周期是否被正确初始化。

  1. 序列化器兼容性调整
    RestSharp 108默认使用System.Text.Json,而.NET Framework环境可能依赖Newtonsoft.Json。若服务端返回的JSON格式存在兼容性问题(如驼峰/ PascalCase差异),手动指定使用Newtonsoft.Json:
var client = new RestClient(baseUrl, configureSerialization: s => s.UseNewtonsoftJson());
  1. TLS版本适配
    .NET 6默认启用TLS 1.3,部分服务端可能不支持。强制.NET 6使用TLS 1.2:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
  1. 线程安全与token缓存检查
    RestSharp 108的AuthenticatorBase已内置线程安全的token缓存,但需确保GetAuthenticationToken方法没有并发问题。若自定义缓存逻辑,需加锁处理:
private readonly object _lockObj = new object();
protected override async Task<AuthenticatorResult> GetAuthenticationToken(...)
{
    lock(_lockObj)
    {
        // 缓存校验逻辑
    }
    // 其他逻辑
}
  1. 服务端请求校验排查
    确认服务端是否对.NET 6的请求有额外校验(如User-Agent、请求来源IP等)。可复制.NET Framework下的请求头到.NET 6环境中测试:
request.AddHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."); // 复制.NET Framework下的User-Agent

内容的提问来源于stack exchange,提问作者Phillip Garza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:18:02