Autenticar com o Azure AD e o OpenID ConnectAuthenticate using Azure AD and OpenID Connect

Código de exemplo do GitHubGitHub Sample code

A aplicação de inquéritos utiliza o protocolo OpenID Connect (OIDC) para autenticar utilizadores com o Azure Active Directory (Azure AD).The Surveys application uses the OpenID Connect (OIDC) protocol to authenticate users with Azure Active Directory (Azure AD). A aplicação de inquéritos usa o ASP.NET Core, que tem o middleware incorporado para OIDC.The Surveys application uses ASP.NET Core, which has built-in middleware for OIDC. O diagrama seguinte mostra o que acontece quando o utilizador inicia sessão, num alto nível.The following diagram shows what happens when the user signs in, at a high level.

Fluxo de autenticação

  1. O utilizador clica no botão "iniciar sessão" na aplicação.The user clicks the "sign in" button in the app. Esta ação é manipulada por um controlador MVC.This action is handled by an MVC controller.
  2. Devolve de controlador MVC uma ChallengeResult ação.The MVC controller returns a ChallengeResult action.
  3. O middleware intercepta a ChallengeResult e cria uma resposta 302, que redireciona o utilizador para a página de início de sessão do Azure AD.The middleware intercepts the ChallengeResult and creates a 302 response, which redirects the user to the Azure AD sign-in page.
  4. O utilizador é autenticado com o Azure AD.The user authenticates with Azure AD.
  5. O Azure AD envia um token de ID para a aplicação.Azure AD sends an ID token to the application.
  6. O middleware valida o token de ID.The middleware validates the ID token. Neste momento, o utilizador já é autenticado dentro do aplicativo.At this point, the user is now authenticated inside the application.
  7. O middleware redireciona o utilizador para a aplicação.The middleware redirects the user back to application.

Registar a aplicação com o Azure ADRegister the app with Azure AD

Para ativar o OpenID Connect, o fornecedor de SaaS registra o aplicativo dentro de seu próprio inquilino do Azure AD.To enable OpenID Connect, the SaaS provider registers the application inside their own Azure AD tenant.

Para registar a aplicação, siga os passos em integrar aplicações com o Azure Active Directory, na secção adicionar uma aplicação.To register the application, follow the steps in Integrating Applications with Azure Active Directory, in the section Adding an Application.

Ver execute a aplicação de inquéritos para obter os passos específicos para a aplicação de inquéritos.See Run the Surveys application for the specific steps for the Surveys application. Tenha em atenção o seguinte:Note the following:

  • Para uma aplicação multi-inquilino, tem de configurar explicitamente a opção de vários inquilinos.For a multitenant application, you must configure the multi-tenanted option explicitly. Isto permite que outras organizações para aceder à aplicação.This enables other organizations to to access the application.

  • O URL de resposta é o URL em que o Azure AD irá enviar respostas de OAuth 2.0.The reply URL is the URL where Azure AD will send OAuth 2.0 responses. Ao usar o ASP.NET Core, isso precisa corresponder ao caminho que configurou o middleware de autenticação (consulte a secção seguinte).When using the ASP.NET Core, this needs to match the path that you configure in the authentication middleware (see next section).

Configurar o middleware de autenticaçãoConfigure the auth middleware

Esta secção descreve como configurar o middleware de autenticação no ASP.NET Core para a autenticação multi-inquilino com OpenID Connect.This section describes how to configure the authentication middleware in ASP.NET Core for multitenant authentication with OpenID Connect.

No seu classe de startup, adicione o middleware de OpenID Connect:In your startup class, add the OpenID Connect middleware:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions {
    ClientId = configOptions.AzureAd.ClientId,
    ClientSecret = configOptions.AzureAd.ClientSecret, // for code flow
    Authority = Constants.AuthEndpointPrefix,
    ResponseType = OpenIdConnectResponseType.CodeIdToken,
    PostLogoutRedirectUri = configOptions.AzureAd.PostLogoutRedirectUri,
    SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
    TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },
    Events = new SurveyAuthenticationEvents(configOptions.AzureAd, loggerFactory),
});

Tenha em atenção que algumas definições são obtidas a partir de opções de configuração de tempo de execução.Notice that some of the settings are taken from runtime configuration options. Eis o que significa que as opções de middleware:Here's what the middleware options mean:

  • ClientId.ClientId. ID de cliente o aplicativo, que obteve quando registou a aplicação no Azure AD.The application's client ID, which you got when you registered the application in Azure AD.
  • Autoridade.Authority. Para uma aplicação multi-inquilino, defina esta opção como https://login.microsoftonline.com/common/.For a multitenant application, set this to https://login.microsoftonline.com/common/. Este é o URL para o Azure AD comuns ponto final, que permite que os utilizadores de qualquer inquilino do Azure AD para iniciar sessão.This is the URL for the Azure AD common endpoint, which enables users from any Azure AD tenant to sign in. Para obter mais informações sobre o ponto de extremidade comum, consulte nesta mensagem de blogue.For more information about the common endpoint, see this blog post.
  • Na TokenValidationParameters, defina ValidateIssuer como falso.In TokenValidationParameters, set ValidateIssuer to false. Isso significa que a aplicação será responsável por validar o valor de emissor no token de ID.That means the app will be responsible for validating the issuer value in the ID token. (O middleware valida ainda o token em si.) Para obter mais informações sobre como validar o emissor, consulte validação de emissor.(The middleware still validates the token itself.) For more information about validating the issuer, see Issuer validation.
  • PostLogoutRedirectUri.PostLogoutRedirectUri. Especifique um URL para redirecionar os utilizadores após o fim de sessão. Isso deve ser uma página que permite pedidos anónimos — normalmente a home page.Specify a URL to redirect users after the sign out. This should be a page that allows anonymous requests — typically the home page.
  • SignInScheme.SignInScheme. Defina esta opção como CookieAuthenticationDefaults.AuthenticationScheme.Set this to CookieAuthenticationDefaults.AuthenticationScheme. Esta definição significa que quando o utilizador é autenticado, as afirmações de utilizador são armazenadas localmente num cookie.This setting means that after the user is authenticated, the user claims are stored locally in a cookie. Esse cookie é como o usuário permaneça com sessão iniciada durante a sessão de browser.This cookie is how the user stays logged in during the browser session.
  • Eventos.Events. Retornos de chamada do evento; ver eventos de autenticação.Event callbacks; see Authentication events.

Adicione também o middleware de autenticação de Cookie para o pipeline.Also add the Cookie Authentication middleware to the pipeline. Este middleware é responsável por escrever as afirmações de utilizador para um cookie e, em seguida, ler o cookie durante o carregamentos subseqüentes de página.This middleware is responsible for writing the user claims to a cookie, and then reading the cookie during subsequent page loads.

app.UseCookieAuthentication(new CookieAuthenticationOptions {
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    AccessDeniedPath = "/Home/Forbidden",
    CookieSecure = CookieSecurePolicy.Always,

    // The default setting for cookie expiration is 14 days. SlidingExpiration is set to true by default
    ExpireTimeSpan = TimeSpan.FromHours(1),
    SlidingExpiration = true
});

Iniciar o fluxo de autenticaçãoInitiate the authentication flow

Para iniciar o fluxo de autenticação no ASP.NET MVC, devolver um ChallengeResult do contoller:To start the authentication flow in ASP.NET MVC, return a ChallengeResult from the contoller:

[AllowAnonymous]
public IActionResult SignIn()
{
    return new ChallengeResult(
        OpenIdConnectDefaults.AuthenticationScheme,
        new AuthenticationProperties
        {
            IsPersistent = true,
            RedirectUri = Url.Action("SignInCallback", "Account")
        });
}

Isso faz com que o middleware devolver uma resposta (encontrado) 302, que redireciona para o ponto final de autenticação.This causes the middleware to return a 302 (Found) response that redirects to the authentication endpoint.

Sessões de início de sessão do utilizadorUser login sessions

Conforme mencionado, quando o utilizador inicia sessão pela primeira vez, o middleware de autenticação de Cookie escreve as afirmações de utilizador para um cookie.As mentioned, when the user first signs in, the Cookie Authentication middleware writes the user claims to a cookie. Depois disso, os pedidos HTTP são autenticados ao ler o cookie.After that, HTTP requests are authenticated by reading the cookie.

Por predefinição, o middleware de cookie escreve um cookie de sessão, que obtém uma vez eliminado o usuário fecha o navegador.By default, the cookie middleware writes a session cookie, which gets deleted once the user closes the browser. Da próxima vez que o usuário a seguir visitar o site, terá de iniciar sessão novamente.The next time the user next visits the site, they will have to sign in again. No entanto, se definir IsPersistent como true no ChallengeResult, o middleware escreve um cookie persistente, para que o usuário permaneça com sessão iniciada depois de fechar o navegador.However, if you set IsPersistent to true in the ChallengeResult, the middleware writes a persistent cookie, so the user stays logged in after closing the browser. Pode configurar a expiração de cookies; ver controlar as opções de cookie.You can configure the cookie expiration; see Controlling cookie options. Cookies persistentes são mais convenientes para o utilizador, mas podem ser inadequadas para alguns aplicativos (Digamos, um aplicativo bancário) em que deseja que o utilizador iniciar sessão sempre.Persistent cookies are more convenient for the user, but may be inappropriate for some applications (say, a banking application) where you want the user to sign in every time.

Sobre o middleware de OpenID ConnectAbout the OpenID Connect middleware

O middleware de ligação OpenID no ASP.NET oculta a maioria dos detalhes de protocolo.The OpenID Connect middleware in ASP.NET hides most of the protocol details. Esta secção contém algumas observações a respeito da implementação, o que pode ser útil para entender o fluxo de protocolo.This section contains some notes about the implementation, that may be useful for understanding the protocol flow.

Em primeiro lugar, vamos examinar o fluxo de autenticação em termos do ASP.NET (ignorar os detalhes do fluxo de protocolo OIDC entre a aplicação e o Azure AD).First, let's examine the authentication flow in terms of ASP.NET (ignoring the details of the OIDC protocol flow between the app and Azure AD). O diagrama seguinte mostra o processo.The following diagram shows the process.

Fluxo de início de sessão

Neste diagrama, existem dois controladores do MVC.In this diagram, there are two MVC controllers. O controlador de conta processa pedidos de início de sessão e o controlador Home serve a página home.The Account controller handles sign-in requests, and the Home controller serves up the home page.

Este é o processo de autenticação:Here is the authentication process:

  1. O usuário clica no botão "Iniciar sessão" e o browser envia um pedido GET.The user clicks the "Sign in" button, and the browser sends a GET request. Por exemplo: GET /Account/SignIn/.For example: GET /Account/SignIn/.
  2. O retorna de controlador de conta um ChallengeResult.The account controller returns a ChallengeResult.
  3. O middleware OIDC devolve uma resposta de HTTP 302, redirecionando para o Azure AD.The OIDC middleware returns an HTTP 302 response, redirecting to Azure AD.
  4. O browser envia o pedido de autenticação para o Azure ADThe browser sends the authentication request to Azure AD
  5. O utilizador inicia sessão com o Azure AD, e do Azure AD envia uma resposta de autenticação.The user signs in to Azure AD, and Azure AD sends back an authentication response.
  6. O middleware OIDC cria um principal de afirmações e passa-o para o middleware de autenticação de Cookie.The OIDC middleware creates a claims principal and passes it to the Cookie Authentication middleware.
  7. O middleware de cookie serializa o principal de afirmações e define um cookie.The cookie middleware serializes the claims principal and sets a cookie.
  8. O middleware OIDC redireciona para o URL de retorno de chamada do aplicativo.The OIDC middleware redirects to the application's callback URL.
  9. O navegador segue o redirecionamento, enviar o cookie na solicitação.The browser follows the redirect, sending the cookie in the request.
  10. O middleware de cookie desserializa o cookie para um principal de afirmações e define HttpContext.User igual ao principal de afirmações.The cookie middleware deserializes the cookie to a claims principal and sets HttpContext.User equal to the claims principal. O pedido é encaminhado para um controlador MVC.The request is routed to an MVC controller.

Tíquete de autenticaçãoAuthentication ticket

Se a autenticação for bem-sucedida, o middleware OIDC cria um tíquete de autenticação, que contém um principal de afirmações que contém as afirmações do utilizador.If authentication succeeds, the OIDC middleware creates an authentication ticket, which contains a claims principal that holds the user's claims. Pode acessar o pedido de suporte dentro de AuthenticationValidated ou TicketReceived eventos.You can access the ticket inside the AuthenticationValidated or TicketReceived event.

Nota

Até que o fluxo de autenticação completa é concluído, HttpContext.User ainda se aplica um principal de anónimo não o usuário autenticado.Until the entire authentication flow is completed, HttpContext.User still holds an anonymous principal, not the authenticated user. O principal de anónimo têm uma coleção de declarações vazio.The anonymous principal has an empty claims collection. Após a conclusão de autenticação e desserializa o middleware de cookie de redirecionamentos de aplicação, o cookie de autenticação e conjuntos de HttpContext.User para um principal de afirmações que representa o usuário autenticado.After authentication completes and the app redirects, the cookie middleware deserializes the authentication cookie and sets HttpContext.User to a claims principal that represents the authenticated user.

Eventos de autenticaçãoAuthentication events

Durante o processo de autenticação, o middleware de OpenID Connect gera uma série de eventos:During the authentication process, the OpenID Connect middleware raises a series of events:

  • RedirectToIdentityProvider.RedirectToIdentityProvider. Chamado imediatamente antes do middleware redireciona para o ponto final de autenticação.Called right before the middleware redirects to the authentication endpoint. Pode usar esse evento para modificar o URL de redirecionamento; Por exemplo, para adicionar parâmetros do pedido.You can use this event to modify the redirect URL; for example, to add request parameters. Ver adicionando a solicitação de consentimento do admin para obter um exemplo.See Adding the admin consent prompt for an example.
  • AuthorizationCodeReceived.AuthorizationCodeReceived. Chamada com o código de autorização.Called with the authorization code.
  • TokenResponseReceived.TokenResponseReceived. Chamado após o middleware obtém um acesso token do IDP, mas antes que sejam validados.Called after the middleware gets an access token from the IDP, but before it is validated. Aplica-se apenas ao fluxo de código de autorização.Applies only to authorization code flow.
  • TokenValidated.TokenValidated. Chamado após o middleware valida o token de ID.Called after the middleware validates the ID token. Neste momento, o aplicativo tem um conjunto de declarações validados sobre o utilizador.At this point, the application has a set of validated claims about the user. Pode usar esse evento para realizar uma validação adicional sobre as declarações, ou para transformar afirmações.You can use this event to perform additional validation on the claims, or to transform claims. Ver trabalhar com declarações.See Working with claims.
  • UserInformationReceived.UserInformationReceived. Chamados se o middleware obtém o perfil de utilizador do ponto final de informações de utilizador.Called if the middleware gets the user profile from the user info endpoint. Aplica-se apenas ao fluxo de código de autorização e apenas quando GetClaimsFromUserInfoEndpoint = true nas opções de middleware.Applies only to authorization code flow, and only when GetClaimsFromUserInfoEndpoint = true in the middleware options.
  • TicketReceived.TicketReceived. Chamado quando a autenticação é concluída.Called when authentication is completed. Este é o último evento, partindo do princípio de que a autenticação for concluída com êxito.This is the last event, assuming that authentication succeeds. Depois deste evento é processado, o usuário está conectado a aplicação.After this event is handled, the user is signed into the app.
  • AuthenticationFailed.AuthenticationFailed. Chamado se a autenticação falhar.Called if authentication fails. Utilize este evento para lidar com falhas de autenticação — por exemplo, ao redirecionar para uma página de erro.Use this event to handle authentication failures — for example, by redirecting to an error page.

Para fornecer retornos de chamada para esses eventos, defina o eventos opção no middleware.To provide callbacks for these events, set the Events option on the middleware. Existem duas formas diferentes de declarar os manipuladores de eventos: Inline com lambdas ou numa classe que deriva OpenIdConnectEvents.There are two different ways to declare the event handlers: Inline with lambdas, or in a class that derives from OpenIdConnectEvents. A segunda abordagem é recomendada se seus retornos de chamada do evento tem qualquer lógica substancial, para que eles não desorganizam a sua classe de inicialização.The second approach is recommended if your event callbacks have any substantial logic, so they don't clutter your startup class. Nossa implementação de referência usa essa abordagem.Our reference implementation uses this approach.

Pontos finais de ligação do OpenIDOpenID connect endpoints

O Azure AD suporta deteção de ligação do OpenID, na qual o fornecedor de identidade (IDP) retorna um documento de metadados JSON de um ponto final bem conhecido.Azure AD supports OpenID Connect Discovery, wherein the identity provider (IDP) returns a JSON metadata document from a well-known endpoint. O documento de metadados contém informações como:The metadata document contains information such as:

  • O URL do ponto final de autorização.The URL of the authorization endpoint. Isso é onde a aplicação redireciona para autenticar o utilizador.This is where the app redirects to authenticate the user.
  • O URL do ponto de extremidade "terminar sessão", em que a aplicação direciona-o para terminar o utilizador.The URL of the "end session" endpoint, where the app goes to log out the user.
  • O URL para obter as chaves de assinatura, o cliente utiliza para validar os tokens OIDC que obtém a partir do IDP.The URL to get the signing keys, which the client uses to validate the OIDC tokens that it gets from the IDP.

Por predefinição, o middleware OIDC sabe como obter estes metadados.By default, the OIDC middleware knows how to fetch this metadata. Definir o autoridade opção no middleware e o middleware constrói o URL para os metadados.Set the Authority option in the middleware, and the middleware constructs the URL for the metadata. (Pode substituir o URL de metadados, definindo a MetadataAddress opção.)(You can override the metadata URL by setting the MetadataAddress option.)

Fluxos de ligação do OpenIDOpenID connect flows

Por predefinição, o middleware OIDC utiliza o fluxo de híbrida com o modo de resposta de postagem de formulário.By default, the OIDC middleware uses hybrid flow with form post response mode.

  • Fluxo de híbrida significa que o cliente pode obter um token de ID e um código de autorização no mesmo ida e volta para o servidor de autorização.Hybrid flow means the client can get an ID token and an authorization code in the same round-trip to the authorization server.
  • Modo de resposta de postagem de formulário significa que o servidor de autorização utiliza um pedido HTTP POST para enviar o código de autorização e de token de ID para a aplicação.Form post reponse mode means the authorization server uses an HTTP POST request to send the ID token and authorization code to the app. Os valores são form-urlencoded (tipo de conteúdo = "application/x-www-form-urlencoded").The values are form-urlencoded (content type = "application/x-www-form-urlencoded").

Quando o middleware OIDC redireciona para o ponto final de autorização, o URL de redirecionamento inclui todos os parâmetros de cadeia de caracteres de consulta necessários ao OIDC.When the OIDC middleware redirects to the authorization endpoint, the redirect URL includes all of the query string parameters needed by OIDC. Para o flow híbrida:For hybrid flow:

  • client_id.client_id. Este valor é definido ClientId opçãoThis value is set in the ClientId option
  • âmbito = "openid profile", o que significa que é um pedido OIDC e Queremos que o perfil do usuário.scope = "openid profile", which means it's an OIDC request and we want the user's profile.
  • response_type = "código id_token".response_type = "code id_token". Esta ação Especifica o fluxo de híbrida.This specifies hybrid flow.
  • response_mode = "form_post".response_mode = "form_post". Esta ação Especifica a resposta de postagem de formulário.This specifies form post response.

Para especificar um fluxo diferente, defina o ResponseType propriedade sobre as opções.To specify a different flow, set the ResponseType property on the options. Por exemplo:For example:

app.UseOpenIdConnectAuthentication(options =>
{
    options.ResponseType = "code"; // Authorization code flow

    // Other options
}

SeguinteNext