如何在Blazor Web Assembly(WASM)中读取客户端证书数据?
解决方案
方法一:通过服务器端API中转获取证书信息
Blazor Web Assembly运行在浏览器客户端,无法直接访问系统或浏览器存储的客户端证书,借助后端API中转是内部认证场景下最稳妥的方案:
- 服务器端配置客户端证书支持
在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();
- 编写获取证书信息的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); } }
- 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让用户手动选择证书,但需用户主动授权:
- 编写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 }; } }
- 在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
相关产品推荐
相关产品推荐

