RestSharp 认证机制完全指南:从 Basic、OAuth1 到 JWT 与自定义 Authenticator
2026/9/24 15:58:05 网站建设 项目流程
  • 后端
  • API设计

【免费下载链接】RestSharp

Simple REST and HTTP API Client for .NET

项目地址:https://gitcode.com/gh_mirrors/re/RestSharp
点击查看免费下载

RestSharp 内置了一套分层清晰的认证体系,覆盖 HTTP Basic、OAuth1(含 xAuth 与 0-legged 流程)、OAuth2 令牌携带以及 JWT Bearer Token 等常见场景,同时通过IAuthenticator接口与AuthenticatorBase抽象基类支持完全自定义的认证逻辑。本文将基于 RestSharp v112 版本文档(authenticators.md),结合仓库源码与测试用例,逐一拆解各类认证器的构造方式、配置位置、底层实现与调用时机,帮助你为不同类型的 API 客户端选择并落地正确的认证方案。

认证器的两种挂载方式

RestSharp 允许你把认证器挂载在两个层级上,二者取其一即可:

  • 客户端级(client-wide):通过RestClientOptions.Authenticator属性设置,作用于该客户端发起的每一次请求,适合整个 API 服务使用同一种认证方式的场景:
var options = new RestClientOptions("https://example.com") { Authenticator = new HttpBasicAuthenticator("username", "password") }; var client = new RestClient(options);
  • 请求级(per-request):通过RestRequest.Authenticator属性设置,只对当前这一次请求生效,适合同一客户端内不同接口使用不同认证方式的场景:
var request = new RestRequest("/api/users/me") { Authenticator = new HttpBasicAuthenticator("username", "password") }; var response = await client.ExecuteAsync(request, cancellationToken);

从源码实现看,无论哪种挂载方式,最终认证逻辑都收敛到同一个接口。IAuthenticator 的定义极为精简,只有一个异步方法:

public interface IAuthenticator { ValueTask Authenticate(IRestClient client, RestRequest request, CancellationToken cancellationToken = default); }

也就是说,任何认证器本质上都是"在请求发出前,往RestRequest上附加认证参数"的一段逻辑。RestSharp 内置认证器大多继承自 AuthenticatorBase,该基类保存了一个可变的Token字符串,并通过一个抽象方法把令牌转换为请求参数:

public abstract class AuthenticatorBase(string token) : IAuthenticator { protected string Token { get; set; } = token; protected abstract ValueTask<Parameter> GetAuthenticationParameter(string accessToken); public async ValueTask Authenticate(IRestClient client, RestRequest request, CancellationToken cancellationToken = default) => request.AddOrUpdateParameter(await GetAuthenticationParameter(Token).ConfigureAwait(false)); }

因此,RestSharp 所有内置认证器的职责都很单一:把认证信息翻译成一个Parameter(通常是HeaderParameter,也可能是GetOrPostParameter),再通过AddOrUpdateParameter附加到请求上。这一设计也让自定义认证器变得非常直接。

Basic 认证

HttpBasicAuthenticator用于 HTTP Basic 访问认证。它把username:password按 Base64 编码后放入Authorization请求头,编码结果以Basic前缀开头。

最常用的两参数构造方式:

var options = new RestClientOptions("https://example.com") { Authenticator = new HttpBasicAuthenticator("username", "password") }; var client = new RestClient(options);

从 HttpBasicAuthenticator 源码可以看到,它还提供一个三参数重载,允许指定字符编码

public class HttpBasicAuthenticator(string username, string password, Encoding encoding) : AuthenticatorBase(GetHeader(username, password, encoding)) { public HttpBasicAuthenticator(string username, string password) : this(username, password, Encoding.UTF8) { } static string GetHeader(string username, string password, Encoding encoding) => Convert.ToBase64String(encoding.GetBytes($"{username}:{password}")); protected override ValueTask<Parameter> GetAuthenticationParameter(string accessToken) => new(new HeaderParameter(KnownHeaders.Authorization, $"Basic {accessToken}")); }

要点说明:

  • 默认使用UTF-8编码拼接username:password后做 Base64;部分旧服务器可能期望 ISO-8859-1 编码,此时可以传入自定义Encoding
  • 编码在构造器里一次性完成,之后每次请求都复用同一个 Base64 字符串。
  • 认证参数以 HeaderParameter 形式写入Authorization头。仓库测试 HttpBasicAuthTests.cs 对该行为有专门覆盖。

OAuth1

OAuth1 是签名型认证协议,RestSharp 的OAuth1Authenticator会为请求自动生成并附加所需的 OAuth 参数与签名。它默认使用HMAC-SHA1生成签名,但每个静态工厂方法都支持通过signatureMethod参数切换算法。

底层签名与参数生成由 OAuthWorkflow 完成:它负责生成oauth_timestampoauth_nonceoauth_signature_methodoauth_version等参数,并按 RFC 5849 的规则拼接签名基串后计算签名。支持的签名算法定义在 Enums.cs 中:

public enum OAuthSignatureMethod { HmacSha1, HmacSha256, PlainText, RsaSha1 }

对应的测试见 OAuth1SignatureTests.cs 与 OAuth1AuthTests.cs。

OAuth1Authenticator的公开属性(见 OAuth1Authenticator.cs)非常完备,包括ConsumerKeyConsumerSecretTokenTokenSecretVerifierVersionCallbackUrlSessionHandleClientUsernameClientPasswordRealmSignatureMethodParameterHandling等。日常使用只需调用静态工厂方法,无需手动逐项赋值。

获取 Request Token(三步授权流程第一步)

获取临时 request token 是 OAuth1 三足授权流程的常规第一步,使用ForRequestToken工厂方法,只需consumerKeyconsumerSecret

var options = new RestClientOptions("https://api.twitter.com") { Authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret) }; var client = new RestClient(options); var request = new RestRequest("oauth/request_token");

响应中应包含 token 与 token secret,用于后续完成授权。如果需要指定回调地址,可给认证器赋CallbackUrl属性:

var authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret); authenticator.CallbackUrl = "https://myapp.example.com/callback";

实际上ForRequestToken还提供了一个直接接收回调地址的重载(见 OAuth1Authenticator.cs)。

换取 Access Token(三步授权流程第三步)

拿到 request token 后,用ForAccessToken换取 access token,需要传入consumerKeyconsumerSecretoauthTokenoauthTokenSecret

var authenticator = OAuth1Authenticator.ForAccessToken( consumerKey, consumerSecret, oauthToken, oauthTokenSecret ); var options = new RestClientOptions("https://api.twitter.com") { Authenticator = authenticator }; var client = new RestClient(options); var request = new RestRequest("oauth/access_token");

如果三步流程的第二步返回了 verifier(用户授权后服务端下发的校验码),使用带verifier参数的重载:

var authenticator = OAuth1Authenticator.ForAccessToken( consumerKey, consumerSecret, oauthToken, oauthTokenSecret, verifier );

ForAccessToken的可选signatureMethod参数同样默认是HmacSha1。响应中应包含可用于访问受保护资源的 access token。

刷新 Access Token

RestSharp 提供两个接受sessionHandle的刷新重载(ForAccessTokenRefresh,见 OAuth1Authenticator.cs),分别对应"无 verifier"与"有 verifier"两种情况:

// 不带 verifier 的刷新 var authenticator = OAuth1Authenticator.ForAccessTokenRefresh( consumerKey, consumerSecret, oauthToken, oauthTokenSecret, sessionHandle ); // 带 verifier 的刷新 var authenticator = OAuth1Authenticator.ForAccessTokenRefresh( consumerKey, consumerSecret, oauthToken, oauthTokenSecret, verifier, sessionHandle );

访问受保护资源

拿到 access token 后,调用ForProtectedResource获取用于访问受保护资源的认证器:

var authenticator = OAuth1Authenticator.ForAccessToken( consumerKey, consumerSecret, accessToken, accessTokenSecret ); var options = new RestClientOptions("https://api.twitter.com/1.1") { Authenticator = authenticator }; var client = new RestClient(options); var request = new RestRequest("statuses/update.json", Method.Post) .AddParameter("status", "Hello Ladies + Gentlemen, a signed OAuth request!") .AddParameter("include_entities", "true");

需要注意,源码中AddOAuthData会明确拒绝在 base URL 中携带查询字符串的用法(抛ApplicationException提示改用AddDefaultQueryParameter),这是使用 OAuth1 时容易踩到的坑。

xAuth

xAuth 是 OAuth1 的简化变体:直接把用户名密码以x_auth_usernamex_auth_password请求参数发送,从而直接换取 access token。该方式并未被广泛支持,但 RestSharp 仍然保留了它。通过ForClientAuthentication创建:

var authenticator = OAuth1Authenticator.ForClientAuthentication( consumerKey, consumerSecret, username, password );

从 OAuthWorkflow.cs 可以看到,xAuth 流程会额外生成x_auth_mode=client_auth参数,且签名基于用户名密码与 consumer 密钥计算。

0-legged OAuth

0-legged(零足)OAuth 场景下,access token 认证器可把consumerSecret传为null,用于对访问令牌已预先签发、无需完整授权流程的情况:

var authenticator = OAuth1Authenticator.ForAccessToken( consumerKey, null, oauthToken, oauthTokenSecret );

OAuth1 的参数携带方式

OAuth1Authenticator还暴露了ParameterHandling属性,支持两种 OAuth 参数携带策略(见 Enums.cs):

  • HttpAuthorizationHeader(默认):把所有oauth_*参数拼进Authorization请求头;
  • UrlOrPostParameters:把参数作为 URL 查询串或 POST 表单参数发送。

默认工厂方法统一采用HttpAuthorizationHeader模式,并配合Escaped的签名处理方式。

OAuth2

RestSharp 内置了两个非常简单的 OAuth2 认证器——它们只负责把已经获取到的 access token 附加到请求上,本身不参与令牌的获取与刷新。

以查询参数携带令牌:OAuth2UriQueryParameterAuthenticator

该认证器只接受 access token 一个构造参数,会把令牌作为名为oauth_token的查询参数附加到请求 URL 上(见 OAuth2UriQueryParameterAuthenticator.cs):

var authenticator = new OAuth2UriQueryParameterAuthenticator(accessToken);

其内部实现正是把令牌包装成GetOrPostParameter("oauth_token", accessToken)——这也是它与其它认证器(产出HeaderParameter)的关键区别。

以请求头携带令牌:OAuth2AuthorizationRequestHeaderAuthenticator

该认证器提供两个构造重载:

  • 单参数:只传 access token,此时默认令牌类型为OAuth
  • 双参数:可额外指定令牌类型(如Bearer)。

它会按"{tokenType} {accessToken}"的格式写入Authorization头(见 OAuth2AuthorizationRequestHeaderAuthenticator.cs):

var authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator( token, "Bearer" ); var options = new RestClientOptions("https://example.com") { Authenticator = authenticator }; var client = new RestClient(options);

上述代码等同于后续 JWT 小节中JwtAuthenticator的效果——每个请求都会携带Authorization: Bearer <token>

由于这两个认证器都不负责获取令牌本身,如果你需要"自取令牌"的完整 OAuth2 客户端,可以参考仓库中的 示例 OAuth2 认证器(位于 usage 示例文档),它展示了如何请求 token endpoint 并把拿到的 bearer token 自动附加到后续请求。

补充:仓库中还有一个能力更强的 OAuth2TokenAuthenticator。它接受一个异步的Func<CancellationToken, Task<OAuth2Token>>令牌获取委托,会在内部缓存令牌并在过期后自动重新获取;通过SemaphoreSlim保证并发安全。它适用于非标准 OAuth2 流程或自定义令牌提供方,相关设计文档见 docs/plans。

JWT

JwtAuthenticator是携带 JWT Bearer Token 的最简实现:

var authenticator = new JwtAuthenticator(myToken); var options = new RestClientOptions("https://example.com") { Authenticator = authenticator }; var client = new RestClient(options);

每次请求时,它都会添加值为Bearer <your token>Authorization头。

从 JwtAuthenticator.cs 源码可以看到两个值得注意的实现细节:

  1. 自动补前缀:如果传入的 token 本身不以"Bearer "开头,构造器会自动补上该前缀;如果已经带前缀则原样保留。同时会通过Ensure.NotEmptyString拒绝空字符串。
  2. 运行期换令牌SetBearerToken方法允许在请求执行过程中动态更新令牌,底层只是替换AuthenticatorBase.Token属性:
authenticator.SetBearerToken(newToken);

自定义 Authenticator

当内置认证器无法满足需求时,可以直接实现IAuthenticator接口并注册到RestClientOptions

var authenticator = new SuperAuthenticator(); // implements IAuthenticator var options = new RestClientOptions("https://example.com") { Authenticator = authenticator }; var client = new RestClient(options);

Authenticate方法在调用RestClient.ExecuteRestClient.Execute<T>时是最先被调用的逻辑之一。它接收当前正在执行的RestRequest,因此你可以访问请求数据的每一个部分(headers、parameters、body 等),对请求做任意形式的改写。

两种推荐的实现路径:

  • 直接实现IAuthenticator:适合完全不依赖令牌缓存的场景,接口只有一个ValueTask Authenticate(...)方法,签名见 IAuthenticator.cs。
  • 继承AuthenticatorBase:适合需要"懒加载令牌并缓存复用"的场景,只需实现抽象方法GetAuthenticationParameter

仓库的 usage 示例文档 给出了一个真实可运行的参考:TwitterAuthenticator继承AuthenticatorBase,首次调用时发现Token为空,于是内部用HttpBasicAuthenticator请求oauth2/token端点换取 bearer token,随后复用该 token 直到需要刷新。其核心代码模式为:

public class TwitterAuthenticator : AuthenticatorBase { protected override async ValueTask<Parameter> GetAuthenticationParameter(string accessToken) { Token = string.IsNullOrEmpty(Token) ? await GetToken() : Token; return new HeaderParameter(KnownHeaders.Authorization, Token); } }

注意该示例文档同时提示:示例代码为生产级代码,当令牌尚未获取时若多个请求并发执行,可能产生重复获取令牌的副作用,实际生产环境可通过信号量(semaphore)等方式规避。

小结

RestSharp 的认证体系可以用一张表概括:

场景推荐认证器附加位置
HTTP Basic 用户名密码HttpBasicAuthenticatorAuthorization: Basic ...
OAuth1 三步授权/受保护资源OAuth1Authenticator.ForRequestToken/ForAccessToken/ForProtectedResourceAuthorization头(默认)
OAuth1 简化/xAuthOAuth1Authenticator.ForClientAuthenticationAuthorization头 +x_auth_*参数
OAuth2 令牌走查询参数OAuth2UriQueryParameterAuthenticatoroauth_token查询参数
OAuth2 令牌走请求头OAuth2AuthorizationRequestHeaderAuthenticatorAuthorization: {tokenType} {token}
JWT BearerJwtAuthenticator(可用SetBearerToken刷新)Authorization: Bearer <token>
完全自定义实现IAuthenticator或继承AuthenticatorBase任意位置

选择建议:单客户端统一认证时挂载到RestClientOptions;混合认证时挂载到单个RestRequest;需要令牌自动获取与缓存的复杂 OAuth2 场景,优先考虑继承AuthenticatorBase的懒加载模式。仓库中对应的测试(Auth 测试目录)与 OAuth2 认证器测试 是验证各类认证器行为最直接的参考。

  • 后端
  • API设计

【免费下载链接】RestSharp

Simple REST and HTTP API Client for .NET

项目地址:https://gitcode.com/gh_mirrors/re/RestSharp
点击查看免费下载
上一篇:PDF限制怎么解除:PDF补丁丁去复制、打印限制的完整操作指南
下一篇:Ultimate SD Upscale:AI图像分块放大技术深度解析与实践指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询