Azure API - 使用客户端证书 + OAUTH 2.0 验证 APIS

Azure API - AUTHENTICATING APIS WITH A CLIENT CERTIFICATE + OAUTH 2.0

我已经通过使用客户端密钥创建令牌实现了 Oauth 2.0 Azure API 身份验证。 我正在尝试使用客户端证书而不是客户端密码来创建 OAuth 2.0 令牌。 您能否指导我如何使用客户端证书获取令牌? 实现相同所需的 C# 代码。

试试看here。它显示了如何通过 HTTP 请求获取带有证书的访问令牌。

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token 
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=<client-id>
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<An assertion (a JSON web token) that you need to create and sign with the certificate you registered as credentials for your application. >
&grant_type=client_credentials

C#:

1。使用 Azure.Identity

// Authenticate a service principal with a certificate

using Azure.Identity;

var certificate = new X509Certificate2("./app/certs/certificate.pfx");
var credential = new CertificateCredential(tenantId, clientId, certificate);

2。在 MSAL.NET

中使用 WithCertificate

博客:https://cmatskas.com/create-a-net-core-deamon-app-that-calls-msgraph-with-a-certificate/

using Microsoft.Graph;
using Microsoft.Identity.Client;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace DaemonConsole
{
    public class ClientCredentialsAuthProvider : IAuthenticationProvider
    {
        private readonly IConfidentialClientApplication msalClient;
        private readonly string[] scopes;

        public ClientCredentialsAuthProvider(AuthenticationConfig config)
        {
            scopes = new string[] { config.Scopes };

            msalClient = ConfidentialClientApplicationBuilder
                .Create(config.ClientId)
                .WithCertificate(ReadCertificateLocal(config.CertificateName))
                .WithAuthority(AadAuthorityAudience.AzureAdMyOrg, true)
                .WithTenantId(config.Tenant)
                .Build();
        }

        public async Task<string> GetAccessTokenAsync()
        {
            try
            {
                var result = await msalClient.AcquireTokenForClient(scopes)
                    .ExecuteAsync();

                return result.AccessToken;
            }
            catch (Exception exception)
            {
                Console.WriteLine($"Error getting access token: {exception.Message}");
                return null;
            }

        }

        // This is the required function to implement IAuthenticationProvider
        // The Graph SDK will call this function each time it makes a Graph
        // call.
        public async Task AuthenticateRequestAsync(HttpRequestMessage requestMessage)
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("bearer", await GetAccessTokenAsync());
        }

        private X509Certificate2 ReadCertificateLocal(string certificateName)
        {
            X509Certificate2 cert = null;

            using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = store.Certificates;
                X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
                X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certificateName, false);
                cert = signingCert.OfType<X509Certificate2>().OrderByDescending(c => c.NotBefore).FirstOrDefault();
            }
            return cert;
        }
    }
}