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

如何在Blazor Web Assembly(WASM)中读取客户端证书数据?

解决方案

方法一:通过服务器端API中转获取证书信息

Blazor Web Assembly运行在浏览器客户端,无法直接访问系统或浏览器存储的客户端证书,借助后端API中转是内部认证场景下最稳妥的方案:

  1. 服务器端配置客户端证书支持
    在ASP.NET Core 6的Program.cs中启用客户端证书验证逻辑:
var builder = WebApplication.CreateBuilder(args);
// 根据内部网络认证规则配置证书验证
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
    .AddCertificate(options =>
    {
        options.AllowedCertificateTypes = CertificateTypes.All;
        options.RevocationMode = X509RevocationMode.NoCheck; // 内部环境可按需调整
    });

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
  1. 编写获取证书信息的API接口
    在服务器端添加控制器,从HttpContext提取证书核心信息并返回:
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class CertificateController : ControllerBase
{
    [HttpGet("info")]
    public IActionResult GetCertificateInfo()
    {
        var certificate = HttpContext.Connection.ClientCertificate;
        if (certificate == null || !certificate.IsValid)
        {
            return BadRequest("未检测到有效客户端证书");
        }

        var certInfo = new
        {
            Subject = certificate.Subject,
            Issuer = certificate.Issuer,
            SerialNumber = certificate.SerialNumber,
            ValidFrom = certificate.NotBefore,
            ValidTo = certificate.NotAfter,
            Thumbprint = certificate.Thumbprint
        };

        return Ok(certInfo);
    }
}
  1. Blazor WASM中调用API获取数据
    注入HttpClient调用后端接口,接收证书信息:
@inject HttpClient Http

@if (_certInfo != null)
{
    <div>
        <p>证书主体:@_certInfo.Subject</p>
        <p>颁发者:@_certInfo.Issuer</p>
        <p>有效期:@_certInfo.ValidFrom 至 @_certInfo.ValidTo</p>
    </div>
}

@code {
    private CertificateInfo? _certInfo;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            _certInfo = await Http.GetFromJsonAsync<CertificateInfo>("api/certificate/info");
        }
        catch (Exception ex)
        {
            // 处理API调用失败或证书不存在的情况
        }
    }

    public class CertificateInfo
    {
        public string? Subject { get; set; }
        public string? Issuer { get; set; }
        public string? SerialNumber { get; set; }
        public DateTime ValidFrom { get; set; }
        public DateTime ValidTo { get; set; }
        public string? Thumbprint { get; set; }
    }
}

方法二:通过浏览器Web Crypto API直接读取证书(需用户交互)

如果不需要依赖服务器中转,可利用浏览器API让用户手动选择证书,但需用户主动授权:

  1. 编写JavaScript证书读取逻辑
    创建隔离JS文件(如CertificateReader.js),实现证书选择与读取:
export async function readClientCertificate() {
    try {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.cer,.crt,.pem';
        await new Promise(resolve => input.onchange = resolve);
        
        const file = input.files[0];
        const arrayBuffer = await file.arrayBuffer();
        
        // 如需解析完整X509字段,需引入pkijs等第三方库处理
        return { success: true, fileName: file.name };
    } catch (err) {
        return { success: false, error: err.message };
    }
}
  1. 在Blazor组件中调用JS函数
@inject IJSRuntime JSRuntime

<button @onclick="ReadCertificate">选择证书文件</button>
@if (_readResult != null)
{
    <p>@(_readResult.Success ? $"已读取证书:{_readResult.FileName}" : $"读取失败:{_readResult.Error}")</p>
}

@code {
    private CertificateReadResult? _readResult;

    private async Task ReadCertificate()
    {
        _readResult = await JSRuntime.InvokeAsync<CertificateReadResult>("readClientCertificate");
    }

    public class CertificateReadResult
    {
        public bool Success { get; set; }
        public string? FileName { get; set; }
        public string? Error { get; set; }
    }
}

注意事项

  • 方法一更适配内部已完成证书认证的场景,无需用户额外操作,服务器可直接获取到用户的客户端证书。
  • 服务器必须部署在HTTPS环境下,客户端证书验证仅在HTTPS连接中生效。
  • 内部网络中可根据安全需求调整证书吊销检查策略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:52:32