Partilhar via


Obter um token para um aplicativo móvel que chama APIs da Web

Antes que seu aplicativo possa chamar APIs da Web protegidas, ele precisa de um token de acesso. Este artigo orienta você pelo processo para obter um token usando a Biblioteca de Autenticação da Microsoft (MSAL).

Definir um escopo

Ao solicitar um token, defina um escopo. O escopo determina quais dados seu aplicativo pode acessar.

A maneira mais fácil de definir um escopo é combinar as APIs da Web desejadas App ID URI com o escopo .default. Essa definição informa à plataforma de identidade da Microsoft que seu aplicativo requer todos os escopos definidos no portal.

Android

String[] SCOPES = {"https://graph.microsoft.com/.default"};

iOS

let scopes = ["https://graph.microsoft.com/.default"]

Obter tokens

Adquira tokens via MSAL

O MSAL permite que os aplicativos adquiram tokens de forma silenciosa e interativa. Quando você chama AcquireTokenSilent() ou AcquireTokenInteractive(), o MSAL retorna um token de acesso para os escopos solicitados. O padrão correto é fazer uma solicitação silenciosa e, em seguida, voltar para uma solicitação interativa.

Android

String[] SCOPES = {"https://graph.microsoft.com/.default"};
PublicClientApplication sampleApp = new PublicClientApplication(
                    this.getApplicationContext(),
                    R.raw.auth_config);

// Check if there are any accounts we can sign in silently.
// Result is in the silent callback (success or error).
sampleApp.getAccounts(new PublicClientApplication.AccountsLoadedCallback() {
    @Override
    public void onAccountsLoaded(final List<IAccount> accounts) {

        if (!accounts.isEmpty() && accounts.size() == 1) {
            // One account found, attempt silent sign-in.
            sampleApp.acquireTokenSilentAsync(SCOPES, accounts.get(0), getAuthSilentCallback());
        } else if (accounts.isEmpty()) {
            // No accounts found. Interactively request a token.
            sampleApp.acquireToken(getActivity(), SCOPES, getAuthInteractiveCallback());
        } else {
            // Multiple accounts found. Handle according to your app logic.
            // You may need to prompt the user to select an account.
        }
    }
});

[...]

// No accounts found. Interactively request a token.
// TODO: Create an interactive callback to catch successful or failed requests.
sampleApp.acquireToken(getActivity(), SCOPES, getAuthInteractiveCallback());

iOS

Primeiro, tente adquirir um token silenciosamente:


NSArray *scopes = @[@"https://graph.microsoft.com/.default"];
NSString *accountIdentifier = @"my.account.id";

MSALAccount *account = [application accountForIdentifier:accountIdentifier error:nil];

MSALSilentTokenParameters *silentParams = [[MSALSilentTokenParameters alloc] initWithScopes:scopes account:account];
[application acquireTokenSilentWithParameters:silentParams completionBlock:^(MSALResult *result, NSError *error) {

    if (!error)
    {
        // You'll want to get the account identifier to retrieve and reuse the account
        // for later acquireToken calls
        NSString *accountIdentifier = result.account.identifier;

        // Access token to call the web API
        NSString *accessToken = result.accessToken;
    }

    // Check the error
    if (error && [error.domain isEqual:MSALErrorDomain] && error.code == MSALErrorInteractionRequired)
    {
        // Interactive auth will be required, call acquireTokenWithParameters:error:
        return;
    }
}];

let scopes = ["https://graph.microsoft.com/.default"]
let accountIdentifier = "my.account.id"

guard let account = try? application.account(forIdentifier: accountIdentifier) else { return }
let silentParameters = MSALSilentTokenParameters(scopes: scopes, account: account)
application.acquireTokenSilent(with: silentParameters) { (result, error) in

    guard let authResult = result, error == nil else {

    let nsError = error! as NSError

    if (nsError.domain == MSALErrorDomain &&
        nsError.code == MSALError.interactionRequired.rawValue) {

            // Interactive auth will be required, call acquireToken()
            return
         }
         return
     }

    // You'll want to get the account identifier to retrieve and reuse the account
    // for later acquireToken calls
    let accountIdentifier = authResult.account.identifier

    // Access token to call the web API
    let accessToken = authResult.accessToken
}

Se o MSAL retornar MSALErrorInteractionRequired, tente adquirir tokens interativamente:

UIViewController *viewController = ...; // Pass a reference to the view controller that should be used when getting a token interactively
MSALWebviewParameters *webParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:viewController];
MSALInteractiveTokenParameters *interactiveParams = [[MSALInteractiveTokenParameters alloc] initWithScopes:scopes webviewParameters:webParameters];
[application acquireTokenWithParameters:interactiveParams completionBlock:^(MSALResult *result, NSError *error) {
    if (!error)
    {
        // You'll want to get the account identifier to retrieve and reuse the account
        // for later acquireToken calls
        NSString *accountIdentifier = result.account.identifier;

        NSString *accessToken = result.accessToken;
    }
}];
let viewController = ... // Pass a reference to the view controller that should be used when getting a token interactively
let webviewParameters = MSALWebviewParameters(authPresentationViewController: viewController)
let interactiveParameters = MSALInteractiveTokenParameters(scopes: scopes, webviewParameters: webviewParameters)
application.acquireToken(with: interactiveParameters, completionBlock: { (result, error) in

    guard let authResult = result, error == nil else {
        print(error!.localizedDescription)
        return
    }

    // Get access token from result
    let accessToken = authResult.accessToken
})

MSAL para iOS e macOS suporta vários modificadores para obter um token interativamente ou silenciosamente:

Parâmetros obrigatórios em MSAL.NET

AcquireTokenInteractive tem apenas um parâmetro obrigatório: scopes. O scopes parâmetro enumera cadeias de caracteres que definem os escopos para os quais um token é necessário. Se o token for para o Microsoft Graph, você poderá encontrar os escopos necessários na referência de API de cada API do Microsoft Graph. Na referência, vá para a seção "Permissões".

Por exemplo, para listar os contatos do usuário, use o escopo "User.Read", "Contacts.Read". Para obter mais informações, veja Referência de permissões do Microsoft Graph.

No Android, você pode especificar a atividade pai ao criar o aplicativo usando PublicClientApplicationBuildero . Se você não especificar a atividade pai naquele momento, poderá especificá-la posteriormente usando .WithParentActivityOrWindow como na seção a seguir. Se você especificar a atividade pai, o token voltará para essa atividade pai após a interação. Se você não especificá-lo, a chamada lançará .ExecuteAsync() uma exceção.

Parâmetros opcionais específicos em MSAL.NET

As seções a seguir explicam os parâmetros opcionais no MSAL.NET.

ComPrompt

O WithPrompt() parâmetro controla a interatividade com o usuário especificando um prompt.

Imagem mostrando os campos na estrutura Prompt. Esses valores constantes controlam a interatividade com o usuário definindo o tipo de prompt exibido pelo parâmetro WithPrompt().

A classe define as seguintes constantes:

  • SelectAccount força o serviço de token de segurança (STS) a apresentar a caixa de diálogo de seleção de conta. A caixa de diálogo contém as contas para as quais o usuário tem uma sessão. Você pode usar essa opção quando quiser permitir que o usuário escolha entre identidades diferentes. Esta opção leva a MSAL a enviar prompt=select_account para o provedor de identidade.

    A SelectAccount constante é o padrão, e efetivamente fornece a melhor experiência possível com base nas informações disponíveis. As informações disponíveis podem incluir conta, presença de uma sessão para o usuário e assim por diante. Não altere esse padrão, a menos que você tenha um bom motivo para fazê-lo.

  • Consent Permite solicitar o consentimento do usuário, mesmo que o consentimento tenha sido concedido antes. Nesse caso, o MSAL envia prompt=consent para o provedor de identidade.

    Talvez você queira usar a constante em aplicativos focados em segurança, Consent onde a governança da organização exige que os usuários vejam a caixa de diálogo de consentimento sempre que usarem o aplicativo.

  • ForceLogin Permite que o serviço solicite credenciais ao usuário, mesmo que o prompt não seja necessário.

    Essa opção pode ser útil se a aquisição de token falhar e você quiser permitir que o usuário entre novamente. Nesse caso, o MSAL envia prompt=login para o provedor de identidade. Talvez você queira usar essa opção em aplicativos focados em segurança, nos quais a governança da organização exige que o usuário entre sempre que acessar partes específicas do aplicativo.

  • Never destina-se apenas ao .NET 4.5 e ao Tempo de Execução do Windows (WinRT). Essa constante não avisará o usuário, mas tentará usar o cookie armazenado na visualização oculta da Web incorporada. Para obter mais informações, consulte Usando navegadores da Web com MSAL.NET.

    Se essa opção falhar, lançará AcquireTokenInteractive uma exceção para notificá-lo de que uma interação da interface do usuário é necessária. Em seguida, use outro Prompt parâmetro.

  • NoPrompt não envia um prompt para o provedor de identidade.

    Esta opção é útil apenas para políticas de perfil de edição no Azure Ative Directory B2C. Para obter mais informações, consulte Especificidades B2C.

ComExtraScopeToConsent

Use o WithExtraScopeToConsent modificador em um cenário avançado em que você deseja que o usuário forneça consentimento prévio para vários recursos. Você pode usar esse modificador quando não quiser usar o consentimento incremental, que normalmente é usado com o MSAL.NET ou a plataforma de identidade da Microsoft. Para obter mais informações, consulte Ter o consentimento do usuário antecipadamente para vários recursos.

Aqui está um exemplo de código:

var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
                     .WithExtraScopeToConsent(scopesForVendorApi)
                     .ExecuteAsync();
Outros parâmetros opcionais

Para saber mais sobre os outros parâmetros opcionais do AcquireTokenInteractive, consulte a documentação de referência do AcquireTokenInteractiveParameterBuilder.

Adquira tokens através do protocolo

Não recomendamos o uso direto do protocolo para obter tokens. Se o fizer, a aplicação não suportará alguns cenários que envolvem início de sessão único (SSO), gestão de dispositivos e Acesso Condicional.

Ao usar o protocolo para obter tokens para aplicativos móveis, faça duas solicitações:

  • Obtenha um código de autorização.
  • Troque o código por um token.

Obter um código de autorização

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=<CLIENT_ID>
&response_type=code
&redirect_uri=<ENCODED_REDIRECT_URI>
&response_mode=query
&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2F.default
&state=12345

Obtenha acesso e atualize o token

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

client_id=<CLIENT_ID>
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=<ENCODED_REDIRECT_URI>
&grant_type=authorization_code

Próximos passos