在 .NET 5 中使用证书进行 API 身份验证

作者 : 慕源网 本文共5775个字,预计阅读时间需要15分钟 发布时间: 2021-10-28 共205人阅读

介绍

在今天的文章中,我们将介绍使用证书来保护 .NET 5 中的 API 并为其提供身份验证。众所周知,安全性对于所有应用程序尤其是 API 尤为重要,因为它们暴露了我们的业务逻辑,供各种客户端使用网络。通过使用证书,我们可以确保每当对我们的 API 进行调用时,都会附有一个证书来确认调用者的身份,只有当我们识别出这个身份时,我们才允许 API 被处理并返回要提供的数据。

创建证书

第一步是从提供这些证书的认证机构公司(如 VeriSign 等)获取证书。这些证书将确认公司的身份,并确保发出这些证书的电话是真实的。出于本文的目的,我们不会使用商业证书,而是会生成我们自己的证书。

第一步是生成将安装在服务器上(我们的 API 所在的位置)的 CA(认证机构)证书,该证书将用于进一步生成将提供给将调用 API 的各种客户端的客户端证书. 然后,这些客户端会将此证书附加到每个调用中。回到服务器,我们将验证此证书,如果它看起来不错,我们将允许操作继续。

让我们先生成 CA 证书。以管理员身份打开“Power Shell”并运行以下命令:

New-SelfSignedCertificate -DnsName “localhost”, “localhost” -CertStoreLocation “cert:\LocalMachine\My” -NotAfter (Get-Date).AddYears(10) -FriendlyName “CAlocalhost” -KeyUsageProperty All -KeyUsage CertSign, CRLSign, DigitalSignature。

执行此命令后,您将看到此证书的指纹。请注意这一点,因为它将用于生成客户端证书。这是证书的唯一标识符。

在 .NET 5 中使用证书进行 API 身份验证

接下来,设置密码如下:

$mypwd = ConvertTo-SecureString -String “Server123” -Force -AsPlainText

在 .NET 5 中使用证书进行 API 身份验证

最后一步是为证书生成 PFX 文件。我们使用以下命令执行此操作,

Get-ChildItem -Path cert:\localMachine\my\05793D3304C6CE0F8C1A4B26E137BBFDDE2A81EE | Export-PfxCertificate -FilePath “C:\CloudItems\Learning\CSharpCorner\Article 62\cacert.pfx” -Password $mypwd

在 .NET 5 中使用证书进行 API 身份验证

现在,PFX 文件已经生成。在我们将 CA 证书添加到我们的机器证书之前,让我们从中生成客户端证书。然后,我们将向客户提供此证书以附加到每个请求中。

首先使用 CA 证书的指纹运行以下命令。

$rootcert = ( Get-ChildItem -Path cert:\LocalMachine\My\05793D3304C6CE0F8C1A4B26E137BBFDDE2A81EE )

在 .NET 5 中使用证书进行 API 身份验证

然后按照下面的命令,

New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname “localhost” -Signer $rootcert -NotAfter (Get-Date).AddYears(10) -FriendlyName “Clientlocalhost”

在 .NET 5 中使用证书进行 API 身份验证

这将使用 CA 证书创建客户端证书。记下指纹以备后用。

接下来,创建一个用于客户端证书的密码,如下所示,

$mypwd = ConvertTo-SecureString -String “Client123” -Force -AsPlainText,

在 .NET 5 中使用证书进行 API 身份验证

最后,使用客户端证书的指纹为客户端证书创建 PFX 文件,如下所示。

Get-ChildItem -Path cert:\localMachine\my\7ED035ABAB1B8CCDFF561935D3C55BE91EAB3DFB | Export-PfxCertificate -FilePath “C:\CloudItems\Learning\CSharpCorner\Article 62\clientcert.pfx” -Password $mypwd

在 .NET 5 中使用证书进行 API 身份验证

现在,我们拥有 CA 证书和客户端证书。

现在让我们将 CA 证书添加到我们的机器上。单击开始并键入“管理计算机证书”。你会看到下面的,

在 .NET 5 中使用证书进行 API 身份验证

选择“受信任的根证书颁发机构-证书-所有任务-导入”并将“cacert.pfx”添加到其中。

您将被要求提供密码。这里提供用于生成“cacert.pfx”文件的密码。导入完成后,您将在“受信任的根证书颁发机构-证书”中看到以下条目。

在 .NET 5 中使用证书进行 API 身份验证

您现在已准备好设计您的解决方案。

在 Visual Studio 2019 中使用 C# 创建一个新的空 API 控制器项目。我使用免费的社区版。

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

接下来,添加一个名为“CertificateValidation”的新类并将以下代码添加到其中,

using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
namespace WebAppCerts {
    public class CertificateValidation {
        public bool ValidateCertificate(X509Certificate2 clientCertificate) {
            string[] allowedThumbprints = {
                "7ED035ABAB1B8CCDFF561935D3C55BE91EAB3DFB"
            };
            if (allowedThumbprints.Contains(clientCertificate.Thumbprint)) {
                return true;
            }
            return false;
        }
    }
}

您需要替换上面名为“allowedThumprints”的字符串数组中的客户端证书缩略图。

接下来,添加以下 Nugget 包。

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

接下来,更新 Startup.cs 文件如下,

using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebAppCerts {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
        public IConfiguration Configuration {
            get;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddControllers();
            services.AddTransient < CertificateValidation > ();
            services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate(options => {
                options.AllowedCertificateTypes = CertificateTypes.SelfSigned;
                options.Events = new CertificateAuthenticationEvents {
                    OnCertificateValidated = context => {
                            var validationService = context.HttpContext.RequestServices.GetService < CertificateValidation > ();
                            if (validationService.ValidateCertificate(context.ClientCertificate)) {
                                context.Success();
                            } else {
                                context.Fail("Invalid certificate");
                            }
                            return Task.CompletedTask;
                        },
                        OnAuthenticationFailed = context => {
                            context.Fail("Invalid certificate");
                            return Task.CompletedTask;
                        }
                };
            });
            services.AddSwaggerGen(c => {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "WebAppCerts", Version = "v1"
                });
            });
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAppCerts v1"));
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
            });
        }
    }
}

由于我们将使用 Kestrel 来运行此应用程序,因此让我们将其设置为使用证书。更新 Program.cs 文件如下,

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Hosting;
namespace WebAppCerts {
    public class Program {
        public static void Main(string[] args) {
            CreateHostBuilder(args).Build().Run();
        }
        public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => {
            webBuilder.UseStartup < Startup > ();
            webBuilder.ConfigureKestrel(o => {
                o.ConfigureHttpsDefaults(o => o.ClientCertificateMode = ClientCertificateMode.AllowCertificate);
            });
        });
    }
}

最后,让我们创建两个 Controller 端点。一个需要证书才能工作,另一个不需要。创建一个名为“TestController”的新空 API 控制器,如下所示,
在 .NET 5 中使用证书进行 API 身份验证

将以下代码添加到新控制器中,

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace WebAppCerts.Controllers {
    [Route("api/[controller]")]
    [ApiController]
    public class TestController: ControllerBase {
        [HttpGet]
        public string Get() => "The action works fine without a certificate";
        [Authorize]
        [HttpPost]
        public string Post() => "The action works fine only with a certificate";
    }
}

代码现在已经完成,我们将使用 Postman 对其进行测试。使用 Kestrel(项目名称)运行应用程序

在 .NET 5 中使用证书进行 API 身份验证

在 .NET 5 中使用证书进行 API 身份验证

现在让我们使用 Postman 进行测试,

在 .NET 5 中使用证书进行 API 身份验证

Get 操作工作正常,因为它不需要证书。

但是,POST 调用将给出 403 Forbidden 消息,因为它需要证书。

在 .NET 5 中使用证书进行 API 身份验证

让我们将客户端证书附加到 POST 请求。

在 .NET 5 中使用证书进行 API 身份验证

选择右上角的网格,然后选择“证书”并添加证书。

在这里,添加客户端证书如下:

在 .NET 5 中使用证书进行 API 身份验证

现在添加的证书如下,

在 .NET 5 中使用证书进行 API 身份验证

现在,当我们发出 POST 请求时,一切正常,如下所示,

在 .NET 5 中使用证书进行 API 身份验证

概括

在本文中,我们研究了如何为证书颁发机构生成自签名证书,以及如何从中生成客户端证书。接下来,我们了解了如何使用这些证书保护我们的 .NET 5 WEB API 端点。这提供了一种保护我们端点的方法。我使用 Postman 对其进行了测试,在以后的文章中,我将演示如何附加客户端证书并使用 .NET 5 客户端进行此调用。快乐编码!


慕源网 » 在 .NET 5 中使用证书进行 API 身份验证

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录