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

如何为现有令牌服务配置ASP.NET Core客户端Web应用身份验证?

配置独立STS的ASP.NET Admin客户端认证与API调用

一、启动时配置认证服务器(关联独立STS)

不管你用的是Startup.cs还是.NET 6+的Program.cs,核心是把Cookie认证和OpenID Connect(OIDC)结合,指向你的独立STS服务,同时配置保存令牌以便后续调用API。

关键配置代码(以.NET 6+为例):

var builder = WebApplication.CreateBuilder(args);

// 添加认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    // 你的独立STS服务地址
    options.Authority = "https://your-sts-api-url";
    // 客户端ID(需在STS提前注册)
    options.ClientId = "admin-client";
    // 客户端密钥(STS对应配置)
    options.ClientSecret = "your-client-secret";
    // 响应类型,需与STS支持的一致,例如code+token+id_token
    options.ResponseType = "code id_token token";
    // 请求的权限(资源服务器的API范围)
    options.Scope.Add("api-resource-scope");
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    
    // 核心配置:将获取到的令牌保存到Cookie,供后续API调用使用
    options.SaveTokens = true;
    // 回调地址,需与STS注册的一致
    options.CallbackPath = "/signin-oidc";
    // 登出回调地址
    options.SignedOutCallbackPath = "/signout-callback-oidc";
    
    // 令牌验证参数配置
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role"
    };
});

// 注册HttpContextAccessor,用于后续获取当前用户令牌
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// 启用认证、授权中间件(顺序不能错)
app.UseAuthentication();
app.UseAuthorization();

// 其他中间件配置...
app.Run();

配置要点:

  • Authority必须指向独立STS的根地址,OIDC会自动读取它的配置端点(如/.well-known/openid-configuration)
  • SaveTokens = true是核心,只有开启这个,登录后获取的Access Token才会存储在Cookie中
  • ResponseType要和STS的配置匹配,若用授权码流,推荐code id_token token或纯code(纯code需额外调用令牌接口换Token)
  • 客户端ID、密钥、回调地址必须和STS里的注册信息完全一致

二、调用资源服务器API时自动携带令牌

登录后,每次调用受保护API,需要将当前用户的Access Token放入请求头的Authorization字段。可以通过封装HttpClient自动处理,避免手动重复编码。

方法1:注册带令牌拦截器的HttpClient(推荐)

// 注册带令牌拦截的命名HttpClient
builder.Services.AddHttpClient("ProtectedApiClient", client =>
{
    client.BaseAddress = new Uri("https://your-resource-api-url");
}).AddHttpMessageHandler<BearerTokenHandler>();

// 自定义令牌拦截器
public class BearerTokenHandler : DelegatingHandler
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public BearerTokenHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext != null)
        {
            // 从当前用户认证信息中获取Access Token
            var accessToken = await httpContext.GetTokenAsync("access_token");
            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            }
        }

        return await base.SendAsync(request, cancellationToken);
    }
}

// 注册拦截器服务
builder.Services.AddTransient<BearerTokenHandler>();

方法2:Controller内手动获取令牌(简单场景)

public class HomeController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HomeController(IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor)
    {
        _httpClientFactory = httpClientFactory;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<IActionResult> CallProtectedApi()
    {
        var client = _httpClientFactory.CreateClient();
        var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
        
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        var response = await client.GetAsync("https://your-resource-api-url/api/protected-endpoint");
        
        // 处理API响应逻辑...
        return View();
    }
}

注意事项:

  • 必须确保IHttpContextAccessor已注册(前面配置中已添加builder.Services.AddHttpContextAccessor())
  • 若STS颁发的是JWT令牌,资源服务器需能验证令牌的签名和有效期,确保双方密钥/证书一致
  • 如需自动刷新过期令牌,需STS支持刷新令牌,且客户端请求时添加offline_access scope

内容的提问来源于stack exchange,提问作者Donald N. Mafa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:43:20