为了账号安全,请及时绑定邮箱和手机立即绑定

授权令牌在 ASP.NET Core 中未绑定

授权令牌在 ASP.NET Core 中未绑定

C#
慕工程0101907 2022-01-15 15:44:33
我正在调用这样的 REST api:HttpClient client;var uri = new Uri(Const.GetUserAccount);client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("accessToken", App.AccessToken);var response = await client.GetAsync(uri);这是我的动作签名(accessToken 为空):public async Task<ActionResult> GetAccountAsync([FromHeader] string accessToken)令牌位于 Request.Headers.HeaderAuthorization 中,其值为:"accessToken" + a space + the guid这似乎很奇怪。不应该有一个名称值对吗?喜欢:“accessToken”:“GUID”这就是它不具有约束力的原因吗?如果是这样,我该如何正确传递它?如果没有,我做错了什么?
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

这就是它不具有约束力的原因吗?


原因是您的操作方法需要accessToken来自请求标头:


public async Task<ActionResult> GetAccountAsync([FromHeader] string accessToken)

AccessToken: xxx_yyy_zzz虽然您在 request 中没有这样的标头。


如果您发送如下请求:


GET https://localhost:44323/api/values/account HTTP/1.1

accessToken : xxx_yyy_zzz

ModelBinder 将绑定accessToken.


如果是这样,我该如何正确传递它?


我不确定您为什么要accessToken在操作方法内获取。但是,如果您确实需要模型绑定的访问令牌,那么至少有两种方法可以做到这一点:


一种方法是更改您的操作方法以Authorization直接获取标题:


public async Task<ActionResult> GetAccount2Async([FromHeader] string authorization) 

{

    if (String.IsNullOrEmpty(authorization)) { /* */ }

    if (!authorization.StartsWith("accessToken",StringComparison.OrdinalIgnoreCase)) { /* */ }


    var token = authorization.Substring("accessToken".Length).Trim();

    // ...

}

当您发送标头为Authorization : accessToken xxx_yyy_zzz.


但是,上面的方法并不干净。更好的方法是创建自定义ModelBinder.


首先让我们创建一个虚拟类来保存 accessToken 值:


public class AccessTokenAuthorizationHeader

{

    public string TokenValue { get; set; }

}

这是一个简单的模型绑定器,它将从 headers 中检索访问令牌:


public class AuthorizationHeaderBinder : IModelBinder

{

    const string DEFAULT_ACCESS_TOKEN_AUTH_HEADER_PREFIX = "accessToken";

    public Task BindModelAsync(ModelBindingContext bindingContext)

    {

        if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); }


        var modelName = bindingContext.BinderModelName;

        if (string.IsNullOrEmpty(modelName)) { modelName = DEFAULT_ACCESS_TOKEN_AUTH_HEADER_PREFIX; }


        var authorization = bindingContext.HttpContext.Request.Headers["Authorization"].FirstOrDefault();

        if (String.IsNullOrWhiteSpace(authorization)) {

            return Task.CompletedTask;

        }

        if (!authorization.StartsWith(modelName, StringComparison.OrdinalIgnoreCase)) {

            return Task.CompletedTask;

        }

        var token = authorization.Substring(modelName.Length).Trim();


        bindingContext.Result = ModelBindingResult.Success(new AccessTokenAuthorizationHeader() {

            TokenValue =token,

        });

        return Task.CompletedTask;

    }

}

最后,AccessTokenAuthorizationHeader用一个ModelBinderAttribute:


[ModelBinder(BinderType =typeof(AuthorizationHeaderBinder))]

public class AccessTokenAuthorizationHeader

{

    public string TokenValue { get; set; }

}

现在我们可以自动绑定它了:


[HttpGet("Account3")]

public async Task<ActionResult> GetAccount3Async(AccessTokenAuthorizationHeader accessToken) {

    var result =new JsonResult(accessToken?.TokenValue);

    return result;

}

让我们用一个 requset 测试它:


GET https://localhost:44323/api/values/account3 HTTP/1.1

Authorization : accessToken 111111

响应将是:


HTTP/1.1 200 OK

Transfer-Encoding: chunked

Content-Type: application/json; charset=utf-8

Server: Kestrel

X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcOVw5LTEzXFNPLkF1dGhvcml6YXRpb25IZWFkZXJcQXBwXEFwcFxhcGlcdmFsdWVzXGFjY291bnQz?=

X-Powered-By: ASP.NET

Date: Thu, 13 Sep 2018 01:54:25 GMT


"111111"


查看完整回答
反对 回复 2022-01-15
  • 1 回答
  • 0 关注
  • 257 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号