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

ASP.NET Core中如何从URL提取Basic Auth的用户名和密码

问题描述
  • 技术环境:基于C#开发.NET Core 2.2版本REST API,全局启用Bearer Token认证方案
  • 实现思路:为单个接口额外增加Basic Auth支持,通过给接口标记[AllowAnonymous]特性跳过全局认证,在方法内部自行校验Authorization请求头,初始校验逻辑如下:
var auth = Request.Headers["Authorization"].ToString();
if (!auth.ToLower().StartsWith("basic "))
    return Unauthorized();
  • 异常现象:Postman中手动配置Basic Auth发起请求时逻辑运行正常,但通过URL内嵌用户名密码格式(https://username:password@localhost:7777/api/file/dl2?id=xxxxx)发起请求时,服务端读取到的Authorization请求头为空,校验直接失败。
  • 初始接口实现代码:
[AllowAnonymous]
[HttpGet("dl2")]
public async Task<IActionResult> DownloadByCryptedIdBasicAuth(string codCat, string id)
{
    var auth = Request.Headers["Authorization"].ToString();
    if (!auth.ToLower().StartsWith("basic "))
        return Unauthorized();

    var credentials = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(auth.Substring(6)));

    string userName = credentials.Split(':')[0];
    string password = credentials.Split(':')[1];

    // 用户名密码校验逻辑
}
解决方案

出现该问题的核心原因是,当前主流浏览器、多数HTTP客户端不会自动将URL中内嵌的user:password@格式凭证转换为标准Basic Auth请求头,这类凭证信息会被保留在URI的用户信息段中,.NET Core中可以直接通过Uri类解析请求地址提取对应内容,不需要手动拼接处理原始URL字符串。

修改后的完整校验逻辑如下:

[AllowAnonymous]
[HttpGet("dl2")]
public async Task<IActionResult> DownloadByCryptedIdBasicAuth(string codCat, string id)
{
    string userName;
    string password;
    var authHeader = Request.Headers["Authorization"].ToString();
    
    if (authHeader.ToLower().StartsWith("basic "))
    {
        // 处理标准Authorization头传递的Basic Auth凭证
        var encodedCred = authHeader.Substring(6).Trim();
        var rawCred = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(encodedCred));
        var credParts = rawCred.Split(new[] { ':' }, 2);
        userName = credParts[0];
        password = credParts.Length == 2 ? credParts[1] : string.Empty;
    }
    else
    {
        // 兜底处理URL内嵌的凭证
        var requestUri = new Uri(Request.GetDisplayUrl());
        if (string.IsNullOrWhiteSpace(requestUri.UserInfo))
        {
            return Unauthorized();
        }
        // Uri.UserInfo属性直接返回 username:password 格式的明文凭证,无需Base64解码
        var urlCredParts = requestUri.UserInfo.Split(new[] { ':' }, 2);
        userName = Uri.UnescapeDataString(urlCredParts[0]);
        password = urlCredParts.Length == 2 ? Uri.UnescapeDataString(urlCredParts[1]) : string.Empty;
    }

    // 原有用户名密码校验逻辑
}

注意事项

  • 拆分凭证时给Split方法传入计数参数2,避免密码本身包含冒号时被错误截断
  • URL中的用户名、密码可能经过URL编码,必须调用Uri.UnescapeDataString做解码,否则包含特殊字符的凭证会校验失败
  • URL内嵌明文凭证的方式安全性极低,凭证会直接暴露在浏览器历史记录、服务器访问日志、网络链路日志中,仅适合内部临时调试、低安全要求的公开资源下载场景使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.08 16:15:17