使用证书的Azure AD OAuth 2.0身份验证代码令牌交换

时间:2019-05-31 15:57:42

标签: azure oauth-2.0 azure-active-directory

用于令牌交换的OAuth2身份验证代码的文档显示了使用client_id和client_secret发出请求。但是,有没有办法针对Azure应用程序使用基于证书的身份验证来实现此目的?

1 个答案:

答案 0 :(得分:3)

是的,您可以使用证书而不是客户机密来获取令牌。这是“客户证书授予”的一部分。

Azure AD V1端点

这是详细的代码示例-它使用自签名证书并使用Azure AD V1终结点

Authenticating to Azure AD in daemon apps with certificates

certCred = new ClientAssertionCertificate(clientId, cert);
result = await authContext.AcquireTokenAsync(todoListResourceId, certCred);

如果您要直接进行基于REST的调用(不使用ADAL库),请参考以下示例。您可以在Microsoft Docs上阅读有关每个参数的更多详细信息:

Access token request with a certificate

POST /<tenant_id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

resource=https%3A%2F%contoso.onmicrosoft.com%2Ffc7664b4-cdd6-43e1-9365-c2e1c4e1b3bf&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg&grant_type=client_credentials

Azure AD V2端点

使用MSAL.NET库,您可以这样做。此处显示了客户端机密和证书凭据的变体。 (否则将覆盖证书)

更多详细信息,请点击此处-Client credential flows in MSAL.NET

// Even if this is a console application here, a daemon application is a confidential client application
IConfidentialClientApplication app;

#if !VariationWithCertificateCredentials
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
           .WithTenantId("{tenantID}")
           .WithClientSecret(config.ClientSecret)
           .Build();
#else
// Building the client credentials from a certificate
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
    .WithTenantId("{tenantID}")
    .WithCertificate(certificate)
    .Build();
#endif

// With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the
// application permissions need to be set statically (in the portal or by PowerShell), and then granted by
// a tenant administrator
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

AuthenticationResult result = null;
try
{
 result = await app.AcquireTokenForClient(scopes)
                   .ExecuteAsync();
}
catch(MsalServiceException ex)
{
 // Case when ex.Message contains:
 // AADSTS70011 Invalid scope. The scope has to be of the form "https://resourceUrl/.default"
 // Mitigation: change the scope to be as expected
}

如果您有兴趣进行直接基于REST的校准(不使用MSAL库),请参考以下示例。有关详细信息,请参见Microsoft Docs:

Access token request with a certificate

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials