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

基于Azure B2C的MVC应用:如何自动为REST请求添加Bearer令牌?

问题描述

我已经有一个集成了Azure B2C认证的可用MVC应用。目前为了认证客户端,需要在请求头中添加Bearer令牌,示例代码如下:

public async Task<string> GetValuesAsync() { 
    var client = new HttpClient { 
        BaseAddress = new Uri(this.serviceOptions.BaseUrl, UriKind.Absolute) 
    }; 
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( 
        "Bearer", await this.GetAccessTokenAsync()); 
    return await client.GetStringAsync("api/products"); 
}

我不想为每个CRUD操作创建代理,且希望使用Kendo UI的RESTful API。请问是否有方法能为所有HTTP操作自动添加Bearer令牌,无需创建代理即可使用标准RESTful API?


解决方案

当然有办法!这里有几个实用的方案,既能避免重复写添加令牌的代码,又能直接适配Kendo UI的RESTful API需求:

方案1:复用HttpClient并全局配置默认授权头

如果你在应用中复用同一个HttpClient实例(这也是.NET推荐的最佳实践,避免socket资源耗尽),可以在初始化阶段一次性配置好授权头,后续所有请求都会自动带上令牌:

// 比如在DI容器注册HttpClient的位置
var client = new HttpClient { 
    BaseAddress = new Uri(this.serviceOptions.BaseUrl, UriKind.Absolute) 
};
// 获取令牌并设置默认授权头
var accessToken = await GetAccessTokenAsync();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

// 之后所有用这个client发起的请求,不管是GET/POST/PUT/DELETE,都会自动带上Bearer令牌
// 如果Kendo UI底层复用这个HttpClient,就不需要额外配置

注意:如果令牌有过期时间,你需要在令牌失效前重新刷新并更新默认头,或者结合下面的拦截器方案自动处理令牌刷新逻辑。

方案2:利用Kendo UI DataSource的beforeSend钩子

Kendo UI的DataSource组件原生提供了transport.beforeSend配置项,能在每个请求发送前修改请求头,完美适配你的场景:

// 前端配置Kendo DataSource示例
var dataSource = new kendo.data.DataSource({
    transport: {
        read: {
            url: "/api/products",
            type: "GET",
            dataType: "json"
        },
        create: {
            url: "/api/products",
            type: "POST",
            dataType: "json"
        },
        update: {
            url: function(data) {
                return "/api/products/" + data.id;
            },
            type: "PUT",
            dataType: "json"
        },
        destroy: {
            url: function(data) {
                return "/api/products/" + data.id;
            },
            type: "DELETE",
            dataType: "json"
        },
        // 核心逻辑:每个请求发送前自动添加Bearer令牌
        beforeSend: function(xhr) {
            // 从前端存储(比如localStorage)获取预先拿到的AccessToken
            var accessToken = localStorage.getItem("accessToken");
            if (accessToken) {
                xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
            }
        }
    },
    // 其他必要配置(如schema、分页、排序等)
});

这个方法直接针对Kendo UI的请求流程,不需要额外封装代理,所有CRUD操作都会自动带上令牌。

方案3:全局注册HttpClient拦截器(后端.NET场景)

如果你的后端需要统一处理所有出站请求的令牌注入,可以通过自定义DelegatingHandler实现全局拦截:

public class BearerTokenHandler : DelegatingHandler
{
    private readonly Func<Task<string>> _getAccessTokenAsync;

    public BearerTokenHandler(Func<Task<string>> getAccessTokenAsync)
    {
        _getAccessTokenAsync = getAccessTokenAsync;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var accessToken = await _getAccessTokenAsync();
        if (!string.IsNullOrEmpty(accessToken))
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

// 在Program.cs中注册到DI容器
builder.Services.AddHttpClient("MyApiClient", client =>
{
    client.BaseAddress = new Uri(builder.Configuration["ServiceOptions:BaseUrl"]);
})
.AddHttpMessageHandler(provider =>
{
    // 注入你的令牌获取服务
    var tokenService = provider.GetRequiredService<ITokenService>();
    return new BearerTokenHandler(tokenService.GetAccessTokenAsync);
});

之后,凡是使用命名HttpClient("MyApiClient")发起的请求,都会自动被拦截并添加Bearer令牌,不管是直接调用还是Kendo UI间接使用这个客户端,都无需手动处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:31:36