Escolha um provedor de autenticação do Microsoft Graph com base no cenário
Artigo
Os provedores de autenticação implementam o código necessário para adquirir um token usando a MSAL (Biblioteca de Autenticação da Microsoft), manipular alguns erros potenciais para casos como consentimento incremental, senhas expiradas e acesso condicional e, em seguida, definir o cabeçalho de autorização de solicitação HTTP. A tabela a seguir lista os provedores que correspondem aos cenários de diferentes tipos de aplicativo.
Os snippets de código a seguir foram escritos com as versões mais recentes de seus respectivos SDKs. Se você encontrar erros do compilador com esses snippets, certifique-se de ter as versões mais recentes. As seguintes bibliotecas do Azure Identity fornecem os provedores de autenticação usados:
Os desenvolvedores do .NET precisam adicionar o pacote Azure.Identity .
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// For authorization code flow, the user signs into the Microsoft
// identity platform, and the browser is redirected back to your app
// with an authorization code in the query parameters
var authorizationCode = "AUTH_CODE_FROM_REDIRECT";
// using Azure.Identity;
var options = new AuthorizationCodeCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
// https://learn.microsoft.com/dotnet/api/azure.identity.authorizationcodecredential
var authCodeCredential = new AuthorizationCodeCredential(
tenantId, clientId, clientSecret, authorizationCode, options);
var graphClient = new GraphServiceClient(authCodeCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID"; // or "common" for multi-tenant apps
final String clientSecret = "YOUR_CLIENT_SECRET";
final String authorizationCode = "AUTH_CODE_FROM_REDIRECT";
final String redirectUrl = "YOUR_REDIRECT_URI";
final String[] scopes = new String[] { "User.Read" };
final AuthorizationCodeCredential credential = new AuthorizationCodeCredentialBuilder()
.clientId(clientId).tenantId(tenantId).clientSecret(clientSecret)
.authorizationCode(authorizationCode).redirectUrl(redirectUrl).build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
O SDK php do Microsoft Graph não usa bibliotecas MSAL, mas autenticação personalizada. Nesse caso, AuthorizationCodeContext().
$scopes = ['User.Read'];
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
$tenantId = 'common';
// Values from app registration
$clientId = 'YOUR_CLIENT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
$redirectUri = 'YOUR_REDIRECT_URI';
// For authorization code flow, the user signs into the Microsoft
// identity platform, and the browser is redirected back to your app
// with an authorization code in the query parameters
$authorizationCode = 'AUTH_CODE_FROM_REDIRECT';
// Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext
$tokenContext = new AuthorizationCodeContext(
$tenantId,
$clientId,
$clientSecret,
$authorizationCode,
$redirectUri);
$graphClient = new GraphServiceClient($tokenContext, $scopes);
scopes = ['User.Read']
# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'common'
# Values from app registration
client_id = 'YOUR_CLIENT_ID'
client_secret = 'YOUR_CLIENT_SECRET'
redirect_uri = 'YOUR_REDIRECT_URI'
# For authorization code flow, the user signs into the Microsoft
# identity platform, and the browser is redirected back to your app
# with an authorization code in the query parameters
authorization_code = 'AUTH_CODE_FROM_REDIRECT'
# azure.identity.aio
credential = AuthorizationCodeCredential(
tenant_id=tenant_id,
client_id=client_id,
authorization_code=authorization_code,
redirect_uri=redirect_uri,
client_secret=client_secret)
graph_client = GraphServiceClient(credential, scopes) # type: ignore
Usar @azure/MSAL-browser para aplicativos de navegador
// @azure/msal-browser
const pca = new PublicClientApplication({
auth: {
clientId: 'YOUR_CLIENT_ID',
authority: `https://login.microsoft.online/${'YOUR_TENANT_ID'}`,
redirectUri: 'YOUR_REDIRECT_URI',
},
});
// Authenticate to get the user's account
const authResult = await pca.acquireTokenPopup({
scopes: ['User.Read'],
});
if (!authResult.account) {
throw new Error('Could not authenticate');
}
// @microsoft/microsoft-graph-client/authProviders/authCodeMsalBrowser
const authProvider = new AuthCodeMSALBrowserAuthenticationProvider(pca, {
account: authResult.account,
interactionType: InteractionType.Popup,
scopes: ['User.Read'],
});
const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
Usar @azure/identity para aplicativos do lado do servidor
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var tenantId = "YOUR_TENANT_ID";
var clientCertificate = new X509Certificate2("MyCertificate.pfx");
// using Azure.Identity;
var options = new ClientCertificateCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientcertificatecredential
var clientCertCredential = new ClientCertificateCredential(
tenantId, clientId, clientCertificate, options);
var graphClient = new GraphServiceClient(clientCertCredential, scopes);
Usando um segredo do cliente
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var tenantId = "YOUR_TENANT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// using Azure.Identity;
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID";
final String clientCertificatePath = "MyCertificate.pem";
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
final String[] scopes = new String[] {"https://graph.microsoft.com/.default"};
final ClientCertificateCredential credential = new ClientCertificateCredentialBuilder()
.clientId(clientId).tenantId(tenantId).pemCertificate(clientCertificatePath)
.build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
Usando um segredo do cliente
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID";
final String clientSecret = "YOUR_CLIENT_SECRET";
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
final String[] scopes = new String[] { "https://graph.microsoft.com/.default" };
final ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId(clientId).tenantId(tenantId).clientSecret(clientSecret).build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
O SDK php do Microsoft Graph não usa bibliotecas MSAL, mas autenticação personalizada. Nesse caso, ClientCredentialContext().
Usando um certificado de cliente
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
$scopes = ['https://graph.microsoft.com/.default'];
// Values from app registration
$clientId = 'YOUR_CLIENT_ID';
$tenantId = 'YOUR_TENANT_ID';
// Certificate details
$certificatePath = 'PATH_TO_CERTIFICATE';
$privateKeyPath = 'PATH_TO_PRIVATE_KEY';
$privateKeyPassphrase = 'PASSPHRASE';
// Microsoft\Kiota\Authentication\Oauth\ClientCredentialCertificateContext
$tokenContext = new ClientCredentialCertificateContext(
$tenantId,
$clientId,
$certificatePath,
$privateKeyPath,
$privateKeyPassphrase);
$graphClient = new GraphServiceClient($tokenContext, $scopes);
Usando um segredo do cliente
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
$scopes = ['https://graph.microsoft.com/.default'];
// Values from app registration
$clientId = 'YOUR_CLIENT_ID';
$tenantId = 'YOUR_TENANT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
// Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext
$tokenContext = new ClientCredentialContext(
$tenantId,
$clientId,
$clientSecret);
$graphClient = new GraphServiceClient($tokenContext, $scopes);
# The client credentials flow requires that you request the
# /.default scope, and pre-configure your permissions on the
# app registration in Azure. An administrator must grant consent
# to those permissions beforehand.
scopes = ['https://graph.microsoft.com/.default']
# Values from app registration
tenant_id = 'YOUR_TENANT_ID'
client_id = 'YOUR_CLIENT_ID'
certificate_path = 'YOUR_CERTIFICATE_PATH'
# azure.identity.aio
credential = CertificateCredential(
tenant_id=tenant_id,
client_id=client_id,
certificate_path=certificate_path)
graph_client = GraphServiceClient(credential, scopes) # type: ignore
# The client credentials flow requires that you request the
# /.default scope, and pre-configure your permissions on the
# app registration in Azure. An administrator must grant consent
# to those permissions beforehand.
scopes = ['https://graph.microsoft.com/.default']
# Values from app registration
tenant_id = 'YOUR_TENANT_ID'
client_id = 'YOUR_CLIENT_ID'
client_secret = 'YOUR_CLIENT_SECRET'
# azure.identity.aio
credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret)
graph_client = GraphServiceClient(credential, scopes) # type: ignore
Usando um certificado de cliente
// @azure/identity
const credential = new ClientCertificateCredential(
'YOUR_TENANT_ID',
'YOUR_CLIENT_ID',
'YOUR_CERTIFICATE_PATH',
);
// @microsoft/microsoft-graph-client/authProviders/azureTokenCredentials
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
scopes: ['https://graph.microsoft.com/.default'],
});
const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
Usando o segredo de um cliente
// @azure/identity
const credential = new ClientSecretCredential(
'YOUR_TENANT_ID',
'YOUR_CLIENT_ID',
'YOUR_CLIENT_SECRET',
);
// @microsoft/microsoft-graph-client/authProviders/azureTokenCredentials
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
// The client credentials flow requires that you request the
// /.default scope, and pre-configure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
scopes: ['https://graph.microsoft.com/.default'],
});
const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// using Azure.Identity;
var options = new OnBehalfOfCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
// This is the incoming token to exchange using on-behalf-of flow
var oboToken = "JWT_TOKEN_TO_EXCHANGE";
var onBehalfOfCredential = new OnBehalfOfCredential(
tenantId, clientId, clientSecret, oboToken, options);
var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID"; // or "common" for multi-tenant apps
final String clientSecret = "YOUR_CLIENT_SECRET";
final String[] scopes = new String[] {"https://graph.microsoft.com/.default"};
// This is the incoming token to exchange using on-behalf-of flow
final String oboToken = "JWT_TOKEN_TO_EXCHANGE";
final OnBehalfOfCredential credential = new OnBehalfOfCredentialBuilder()
.clientId(clientId).tenantId(tenantId).clientSecret(clientSecret)
.userAssertion(oboToken).build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
O SDK php do Microsoft Graph não usa bibliotecas MSAL, mas autenticação personalizada. Nesse caso, OnBehalfOfContext().
$scopes = ['https://graph.microsoft.com/.default'];
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
$tenantId = 'common';
// Values from app registration
$clientId = 'YOUR_CLIENT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
// This is the incoming token to exchange using on-behalf-of flow
$oboToken = 'JWT_TOKEN_TO_EXCHANGE';
// Microsoft\Kiota\Authentication\Oauth\OnBehalfOfContext
$tokenContext = new OnBehalfOfContext(
$tenantId,
$clientId,
$clientSecret,
$oboToken);
$graphClient = new GraphServiceClient($tokenContext, $scopes);
scopes = ['https://graph.microsoft.com/.default']
# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'common'
# Values from app registration
client_id = 'YOUR_CLIENT_ID'
client_secret = 'YOUR_CLIENT_SECRET'
# This is the incoming token to exchange using on-behalf-of flow
obo_token = 'JWT_TOKEN_TO_EXCHANGE'
# azure.identity.aio
credential = OnBehalfOfCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret,
user_assertion=obo_token)
graph_client = GraphServiceClient(credential, scopes) # type: ignore
O fluxo de Autenticação Implícita não é recomendado devido a suas desvantagens. Clientes públicos, como aplicativos nativos e aplicativos de página única, agora devem usar o fluxo de código de autorização com a extensão PKCE. Referência.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new DeviceCodeCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
ClientId = clientId,
TenantId = tenantId,
// Callback function that receives the user prompt
// Prompt contains the generated device code that user must
// enter during the auth process in the browser
DeviceCodeCallback = (code, cancellation) =>
{
Console.WriteLine(code.Message);
return Task.FromResult(0);
},
};
// https://learn.microsoft.com/dotnet/api/azure.identity.devicecodecredential
var deviceCodeCredential = new DeviceCodeCredential(options);
var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID"; // or "common" for multi-tenant apps
final String[] scopes = new String[] {"User.Read"};
final DeviceCodeCredential credential = new DeviceCodeCredentialBuilder()
.clientId(clientId).tenantId(tenantId).challengeConsumer(challenge -> {
// Display challenge to the user
System.out.println(challenge.getMessage());
}).build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
scopes = ['User.Read']
# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'common'
# Values from app registration
client_id = 'YOUR_CLIENT_ID'
# azure.identity
credential = DeviceCodeCredential(
tenant_id=tenant_id,
client_id=client_id)
graph_client = GraphServiceClient(credential, scopes)
O fluxo integrado do Windows permite que os computadores Windows adquiram um token de acesso quando ingressados em domínio silenciosamente. Para obter detalhes, consulte Autenticação do Windows integrado.
No Azure.Identity momento, o pacote não dá suporte à autenticação integrada ao Windows. Em vez disso, crie um provedor de token de acesso personalizado usando o MSAL.
Provedor de token de acesso
public class IntegratedWindowsTokenProvider : IAccessTokenProvider
{
private readonly IPublicClientApplication publicClient;
/// <summary>
/// Initializes a new instance of the <see cref="IntegratedWindowsTokenProvider"/> class.
/// </summary>
/// <param name="clientId">The client ID from the app registration in Azure.</param>
/// <param name="tenantId">The tenant ID from the app registration in Azure.</param>
public IntegratedWindowsTokenProvider(string clientId, string tenantId)
{
// From MSAL (Microsoft.Identity.Client)
publicClient = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.Build();
AllowedHostsValidator = new AllowedHostsValidator();
}
/// <summary>
/// Gets an <see cref="AllowedHostsValidator"/> that validates if the
/// target host of a request is allowed for authentication.
/// </summary>
public AllowedHostsValidator AllowedHostsValidator { get; }
/// <inheritdoc/>
public async Task<string> GetAuthorizationTokenAsync(
Uri uri,
Dictionary<string, object>? additionalAuthenticationContext = null,
CancellationToken cancellationToken = default)
{
var scopes = new[] { "User.Read" };
var result = await publicClient
.AcquireTokenByIntegratedWindowsAuth(scopes)
.ExecuteAsync(cancellationToken);
return result.AccessToken;
}
}
Criar o cliente
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
var authenticationProvider = new BaseBearerTokenAuthenticationProvider(
new IntegratedWindowsTokenProvider(clientId, tenantId));
var graphClient = new GraphServiceClient(authenticationProvider);
return graphClient;
O fluxo interativo é usado por aplicativos móveis (Xamarin e UWP) e aplicativos de área de trabalho para chamar o Microsoft Graph em nome de um usuário. Para obter detalhes, confira Adquirir tokens interativamente.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new InteractiveBrowserCredentialOptions
{
TenantId = tenantId,
ClientId = clientId,
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
// MUST be http://localhost or http://localhost:PORT
// See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core
RedirectUri = new Uri("http://localhost"),
};
// https://learn.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential
var interactiveCredential = new InteractiveBrowserCredential(options);
var graphClient = new GraphServiceClient(interactiveCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID"; // or "common" for multi-tenant apps
final String redirectUrl = "YOUR_REDIRECT_URI";
final String[] scopes = new String[] {"User.Read"};
final InteractiveBrowserCredential credential = new InteractiveBrowserCredentialBuilder()
.clientId(clientId).tenantId(tenantId).redirectUrl(redirectUrl).build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new UsernamePasswordCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var userName = "adelev@contoso.com";
var password = "Password1!";
// https://learn.microsoft.com/dotnet/api/azure.identity.usernamepasswordcredential
var userNamePasswordCredential = new UsernamePasswordCredential(
userName, password, tenantId, clientId, options);
var graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);
final String clientId = "YOUR_CLIENT_ID";
final String tenantId = "YOUR_TENANT_ID"; // or "common" for multi-tenant apps
final String userName = "YOUR_USER_NAME";
final String password = "YOUR_PASSWORD";
final String[] scopes = new String[] {"User.Read"};
final UsernamePasswordCredential credential = new UsernamePasswordCredentialBuilder()
.clientId(clientId).tenantId(tenantId).username(userName).password(password)
.build();
if (null == scopes || null == credential) {
throw new Exception("Unexpected error");
}
final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
scopes = ['User.Read']
# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'common'
# Values from app registration
client_id = 'YOUR_CLIENT_ID'
# User name and password
username = 'adelev@contoso.com'
password = 'Password1!'
# azure.identity
credential = UsernamePasswordCredential(
tenant_id=tenant_id,
client_id=client_id,
username=username,
password=password)
graph_client = GraphServiceClient(credential, scopes)
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulte https://aka.ms/ContentUserFeedback.