Compartilhar via


Proteger aplicativos Java Spring Boot usando funções e declarações de função

Este artigo apresenta um aplicativo Web Java Spring Boot que usa a biblioteca de clientes Microsoft Entra ID Spring Boot Starter para Java para autenticação, autorização e aquisição de token. O aplicativo usa o protocolo OpenID Connect para conectar usuários e restringir o acesso a algumas rotas usando funções de aplicativo Microsoft Entra ID (funções de aplicativo) para autorização.

As funções de aplicativo, assim como os grupos de segurança, são meios populares para implementar a autorização. Usando o RBAC (controle de acesso baseado em função) com funções de aplicativo e declarações de função, você pode impor políticas de autorização com segurança com o mínimo de esforço. Outra abordagem é usar grupos Microsoft Entra ID e declarações de grupo. Os grupos Microsoft Entra ID e as funções de aplicativos não são mutuamente exclusivos. Você pode usá-los para fornecer controle de acesso refinado.

Para assistir a um vídeo que aborda um cenário parecido, consulte Implementar autorização nos seus aplicativos usando funções de aplicativo, grupos de segurança, escopos e funções de diretório.

Para obter mais informações sobre como os protocolos funcionam neste cenário e em outros cenários, consulte Autenticação vs. autorização.

O diagrama a seguir mostra a topologia do aplicativo:

Diagrama que mostra a topologia do aplicativo.

O aplicativo usa a biblioteca de clientes do Microsoft Entra ID Spring Boot Starter para Java para conectar um usuário e obter um token de ID do Microsoft Entra ID. O token de ID contém a declaração de funções. O aplicativo inspeciona o valor dessa declaração para determinar quais páginas o usuário está autorizado a acessar.

Esse tipo de autorização é implementado usando o RBAC. Com o RBAC, o administrador concede permissões a funções, não a usuários ou grupos individuais. O administrador pode então atribuir funções a diferentes usuários e grupos para controlar quem tem acesso a determinado conteúdo e funcionalidade.

Este aplicativo de exemplo define as duas funções de aplicativo a seguir:

  • PrivilegedAdmin Autorizado a acessar as páginas Somente Administradores e Usuários regulares.
  • RegularUser Autorizado a acessar a página de Usuários regulares.

Essas funções de aplicativo são definidas no portal do Azure, no manifesto de registro do aplicativo. Quando um usuário entra no aplicativo, o Microsoft Entra ID emite uma declaração de funções para cada função concedida individualmente ao usuário na forma de associação de função.

Você pode atribuir usuários e grupos a funções por meio do portal do Azure.

Observação

As declarações de função não estão presentes para usuários convidados em um locatário se o ponto de extremidade https://login.microsoftonline.com/common/ for usado como autoridade para conectar usuários. Você precisa entrar com um usuário em um ponto de extremidade locatário como https://login.microsoftonline.com/tenantid.

Pré-requisitos

Recomendações

  • Alguma familiaridade com o Spring Framework.
  • Alguma familiaridade com o terminal Linux/OSX.
  • jwt.ms para inspecionar seus tokens.
  • Fiddler para monitorar sua atividade de rede e solução de problemas.
  • Siga o Blog do Microsoft Entra para ficar up-to-date com os desenvolvimentos mais recentes.

Configurar o exemplo

As seções a seguir mostram como configurar o aplicativo de exemplo.

Clone ou baixe o repositório de exemplo.

Para clonar o exemplo, abra uma janela do Bash e use o seguinte comando:

git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 4-spring-web-app/3-Authorization-II/roles

Como alternativa, navegue até o repositório ms-identity-msal-java-samples, baixe-o como um arquivo .zip e extraia-o para o disco rígido.

Importante

Para evitar limitações de comprimento de caminho de arquivo no Windows, clone ou extraia o repositório em um diretório próximo à raiz do disco rígido.

Registrar o aplicativo de exemplo com seu locatário do Microsoft Entra ID

Há um projeto neste exemplo. As seções a seguir mostram como registrar o aplicativo usando o portal do Azure.

Escolha o locatário do Microsoft Entra ID no qual você deseja criar seus aplicativos

Siga as etapas a seguir para escolher o locatário:

  1. Entre no portal do Azure.

  2. Se sua conta estiver presente em mais de um locatário do Microsoft Entra ID, selecione seu perfil no canto do portal do Azure e selecione Mudar diretório para alterar sua sessão para o locatário desejado do Microsoft Entra ID.

Registrar o aplicativo (java-spring-webapp-roles)

Para registrar o aplicativo, use estas etapas:

  1. Navegue até o portal do Azure e selecione Microsoft Entra ID.

  2. Selecione Registros de aplicativo no painel de navegação e selecione Novo registro.

  3. Na página Registrar um aplicativo que aparece, insira as seguintes informações de registro do aplicativo:

    • Na seção Nome, insira um nome de aplicativo relevante para exibição aos usuários do aplicativo: por exemplo, java-spring-webapp-roles.
    • Em Tipos de contas com suporte, selecione Contas somente neste diretório organizacional.
    • Na seção URI de redirecionamento (opcional), selecione Web na caixa de combinação e insira o seguinte URI de redirecionamento: http://localhost:8080/login/oauth2/code/.
  4. Selecione Registrar para criar o aplicativo.

  5. Na página de registro do aplicativo, localize e copie o valor do ID do aplicativo (cliente) para uso posterior. Use esse valor no(s) arquivo(s) de configuração do aplicativo.

  6. Na página de registo do aplicativo, selecione Segredos de certificados & no painel de navegação para abrir a página em que possa gerar segredos e carregar certificados.

  7. Na seção Segredos do Cliente, escolha Novo Segredo do Cliente.

  8. Insira uma descrição, por exemplo, segredo do aplicativo.

  9. Selecione uma das durações disponíveis: Em 1 ano, Em 2 anos ou Nunca expira.

  10. Selecione Adicionar. O valor gerado é exibido.

  11. Copie e salve o valor gerado para uso nas etapas posteriores. Esse valor é necessário para os arquivos de configuração do código. Esse valor não é exibido novamente e você não pode recuperá-lo por outros meios. Portanto, salve-o no portal do Azure antes de navegar para qualquer outra tela ou painel.

Definir as funções de aplicativos

Use as etapas a seguir para definir as funções do aplicativo:

  1. Ainda no mesmo registo do aplicativo, selecione Funções do aplicativo no painel de navegação.

  2. Selecione Criar função do aplicativo e insira os seguintes valores:

    • Para Nome de exibição, insira um nome adequado, por exemplo, PrivilegedAdmin.
    • Para Tipos de membro permitidos, escolha Usuário.
    • Em Valor, insira PrivilegedAdmin.
    • Para Descrição, insira PrivilegedAdmins que podem visualizar a Página do administrador.
  3. Selecione Criar função do aplicativo e insira os seguintes valores:

    • Em Nome de exibição, insira um nome adequado, por exemplo, RegularUser.
    • Para Tipos de membro permitidos, escolha Usuário.
    • Em Valor, insira RegularUser.
    • Em Descrição, insira RegularUsers que podem visualizar a Página do usuário.
  4. Selecione Aplicar para salvar as alterações.

Atribuir usuários a funções de aplicativos

Siga as diretrizes aqui para adicionar usuários à função de aplicativo definida anteriormente: Atribuir usuários e grupos a funções.


Configure o aplicativo (java-spring-webapp-roles) para usar o registro do aplicativo

Use as seguintes etapas para configurar o aplicativo:

Observação

Nas etapas a seguir, ClientID é o mesmo que Application ID ou AppId.

  1. Abrir o projeto no seu IDE.

  2. Abra o arquivo src\main\resources\application.yml .

  3. Localize o espaço reservado Enter_Your_Tenant_ID_Here e substitua o valor existente pela ID de locatário do Microsoft Entra.

  4. Localize o espaço reservado Enter_Your_Client_ID_Here e substitua o valor existente pelo ID do aplicativo ou clientId do aplicativo java-spring-webapp-roles copiado do portal do Azure.

  5. Localize o espaço reservado Enter_Your_Client_Secret_Here e substitua o valor existente pelo valor que você salvou durante a criação do java-spring-webapp-roles copiado do portal do Azure.

  6. Abra o arquivo src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootapplication/Sample.Controller.java.

  7. Localize as referências às funções de aplicativos PrivilegedAdmin e RegularUser neste arquivo. Se necessário, altere-os para refletirem os nomes das funções de aplicativo escolhidas nas etapas anteriores.

Execute o exemplo

As seções a seguir mostram como implantar o exemplo no Aplicativos de Contêiner do Azure.

Pré-requisitos

  • Uma conta do Azure. Crie uma conta gratuita se ainda não tiver a sua. Você precisa da permissão Contributor ou Owner na assinatura do Azure para continuar. Para obter mais informações, confira Atribuir funções do Azure usando o portal do Azure.
  • O CLI do Azure.
  • A extensão, versão 0.3.47 ou superior da CLI dos Aplicativos de Contêiner do Azure. Para instalar a versão mais recente, use o comando az extension add --name containerapp --upgrade --allow-preview.
  • O Java Development Kit, versão 17 ou superior.
  • O Maven.

Preparar o projeto Spring

Use as etapas a seguir para preparar o projeto:

  1. Use o comando Maven a seguir para criar o projeto:

    mvn clean verify
    
  2. Execute o projeto de exemplo localmente usando o seguinte comando:

    mvn spring-boot:run
    

Instalação

Para entrar no Azure usando a CLIl, execute o comando a seguir e siga os prompts para concluir o processo de autenticação.

az login

Para garantir que você esteja executando a versão mais recente da CLI, execute o comando “upgrade”.

az upgrade

Em seguida, instale ou atualize a extensão dos Aplicativos de Contêiner do Azure para a CLI.

Se você receber erros sobre parâmetros ausentes ao executar comandos az containerapp na CLI do Azure, verifique se você tem a versão mais recente da extensão dos Aplicativos de Contêiner do Azure instalada.

az extension add --name containerapp --upgrade

Observação

A partir de maio de 2024, as extensões da CLI do Azure já não permitem funcionalidades de versão prévia do recurso por padrão. Para acessar as versões prévias dos recursos dos Aplicativos de Contêiner, instale a extensão Aplicativos de Contêiner com --allow-preview true.

az extension add --name containerapp --upgrade --allow-preview true

Agora que a extensão ou módulo atual está instalado, registre os namespaces Microsoft.App e Microsoft.OperationalInsights.

Observação

Os recursos dos Aplicativos de Contêiner do Azure migraram do namespace Microsoft.Web para o namespace Microsoft.App. Consulte a migração de namespace de Microsoft.Web para Microsoft.App em março de 2022 para obter mais detalhes.

az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights

Criar o ambiente de Aplicativos de Contêiner do Azure

Agora que a configuração da CLI do Azure foi concluída, você pode definir as variáveis de ambiente que são usadas ao longo deste artigo.

Defina as variáveis a seguir no shell bash.

export RESOURCE_GROUP="ms-identity-containerapps"
export LOCATION="canadacentral"
export ENVIRONMENT="env-ms-identity-containerapps"
export API_NAME="ms-identity-api"
export JAR_FILE_PATH_AND_NAME="./target/ms-identity-spring-boot-webapp-0.0.1-SNAPSHOT.jar"

Crie um grupos de recursos.

az group create  \
    --name $RESOURCE_GROUP \
    --location $LOCATION \

Criar um ambiente com um espaço de trabalho da Análise de logs gerado automaticamente.

az containerapp env create \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION

Mostrar o domínio padrão do ambiente do aplicativo de contêiner. Anote esse domínio para usar em seções posteriores.

az containerapp env show \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --query properties.defaultDomain

Preparar o aplicativo para implantação

Ao implantar seu aplicativo nos Aplicativos de Contêiner do Azure, a URL de redirecionamento é alterada para a URL de redirecionamento da instância do aplicativo implantado nos Aplicativos de Contêiner do Azure. Use as etapas a seguir para alterar essas configurações no arquivo application.yml:

  1. Navegue até o arquivo src\main\resources\application.yml do aplicativo e altere o valor de post-logout-redirect-uri para o nome de domínio do aplicativo implantado, conforme mostrado no exemplo a seguir. Substitua <API_NAME> e <default-domain-of-container-app-environment> pelos valores atuais. Por exemplo, com o domínio padrão para o ambiente do Aplicativo de Contêiner do Azure da etapa anterior e ms-identity-api para o nome do aplicativo, você usaria https://ms-identity-api.<default-domain> para o valor post-logout-redirect-uri.

    post-logout-redirect-uri: https://<API_NAME>.<default-domain-of-container-app-environment>
    
  2. Depois de salvar esse arquivo, use o seguinte comando para recompilar o aplicativo:

    mvn clean package
    

Importante

O arquivo application.yml do aplicativo atualmente contém o valor do segredo do cliente no parâmetro client-secret. Não é recomendável manter esse valor nesse arquivo. Você também pode estar correndo risco se confirmar o arquivo em um repositório Git. Para obter a abordagem recomendada, consulte Gerenciar segredos nos Aplicativos de Contêiner do Azure.

Atualizar seu registro de aplicativo do Microsoft Entra ID

Como o URI de redirecionamento é alterado para o aplicativo implantado nos Aplicativos de Contêiner do Azure, você também precisa alterar o URI de redirecionamento no registro do aplicativo Microsoft Entra ID. Use as seguintes etapas para fazer essa alteração:

  1. Navegue até a página de registros de aplicativo da plataforma de identidade da Microsoft para desenvolvedores.

  2. Use a caixa de pesquisa para procurar o registro do aplicativo. Por exemplo, java-servlet-webapp-authentication.

  3. Abra o registro do aplicativo selecionando seu nome.

  4. Selecione Autenticação no menu.

  5. Na seção Web - URIs de redirecionamento, selecione Adicionar URI.

  6. Preencha o URI do aplicativo, anexando /login/oauth2/code/, por exemplo, https://<containerapp-name>.<default domain of container app environment>/login/oauth2/code/.

  7. Selecione Salvar.

Implantar o aplicativo

Implante o pacote JAR nos Aplicativos de Contêiner do Azure.

Observação

Se necessário, você pode especificar a versão do JDK nas variáveis de ambiente de build do Java. Para obter mais informações, confira Compilar variáveis de ambiente para Java em Aplicativos de Contêiner do Azure.

Agora você pode implantar o arquivo WAR com o comando da CLI az containerapp up.

az containerapp up \
    --name $API_NAME \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION \
    --environment $ENVIRONMENT \
    --artifact <JAR_FILE_PATH_AND_NAME> \
    --ingress external \
    --target-port 8080 \
    --query properties.configuration.ingress.fqdn

Observação

A versão padrão do JDK é 17. Se você precisar alterar a versão do JDK para compatibilidade com o seu aplicativo, poderá usar o argumento --build-env-vars BP_JVM_VERSION=<YOUR_JDK_VERSION> para ajustar o número de versão.

Para obter mais variáveis de ambiente de compilação, consulte Compilar variáveis de ambiente para Java em Aplicativos de Contêiner do Azure.

Validar o aplicativo

Neste exemplo, o comando containerapp up inclui o argumento --query properties.configuration.ingress.fqdn, que retorna o FQDN (nome de domínio totalmente qualificado), também conhecido como URL do aplicativo. Use as seguintes etapas para verificar o log do aplicativo a fim de investigar qualquer problema de implantação:

  1. Acesse a URL do aplicativo de saída na página Saídas da seção Implantação.

  2. No painel de navegação da página Visão geral da instância de Aplicativos de Contêiner do Azure, selecione Logs para verificar os logs do aplicativo.

Explorar o exemplo

Use as seguintes etapas para explorar o exemplo:

  1. Observe o status de conectado ou desconectado exibido no centro da tela.
  2. Selecione o botão contextual no canto. Esse botão lê Entrar quando você executa o aplicativo pela primeira vez. Como alternativa, selecione detalhes do token , somente administradores ou usuários regulares. Como essas páginas são protegidas e exigem autenticação, você é redirecionado automaticamente para a página de entrada.
  3. Na próxima página, siga as instruções e conecte-se com uma conta no locatário do Microsoft Entra ID.
  4. Na tela de consentimento, observe os escopos que estão sendo solicitados.
  5. Após a conclusão bem-sucedida do fluxo de entrada, você deverá ser redirecionado para a página inicial, que mostra o status de entrada ou uma das outras páginas, dependendo do botão que acionou o fluxo de entrada.
  6. Observe que o botão contextual agora diz Sair e exibe seu nome de usuário.
  7. Se você estiver na página inicial, selecione Detalhes do token de ID para ver algumas das declarações decodificadas do token de ID, incluindo funções.
  8. Selecione Somente administradores para visualizar o /admin_only. Somente usuários com função PrivilegedAdmin de aplicativo podem visualizar esta página. Caso contrário, uma mensagem de falha de autorização será exibida.
  9. Selecione Usuários regulares para visualizar a página /regular_user. Somente usuários com função de aplicativo RegularUser ou PrivilegedAdmin podem visualizar esta página. Caso contrário, uma mensagem de falha de autorização será exibida.
  10. Use o botão no canto para sair. A página de status reflete o novo estado.

Observações sobre o código

Este exemplo apresenta como usar a biblioteca de clientes do Microsoft Entra ID Spring Boot Starter para Java para conectar usuários ao seu locatário do Microsoft Entra ID. O exemplo também usa o Spring Oauth2 Client e os iniciadores da inicialização do Spring Web. O exemplo usa declarações do token de ID obtido do Microsoft Entra ID para exibir os detalhes do usuário conectado e para restringir o acesso a algumas páginas usando a declaração de funções para autorização.

Conteúdos

A tabela a seguir mostra o conteúdo da pasta do projeto de exemplo:

Arquivo/pasta Descrição
pom.xml Dependências de aplicativo.
src/main/resources/templates/ Modelos Thymeleaf para IU.
src/main/resources/application.yml Configuração da biblioteca do aplicativo e do Microsoft Entra ID Boot Starter.
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ Esse diretório contém o ponto de entrada do aplicativo principal, o controlador e as classes de configuração.
.../MsIdentitySpringBootWebappApplication.java Classe principal.
.../SampleController.java Controlador com mapeamentos de ponto de extremidade.
.../SecurityConfig.java Configuração de segurança: por exemplo, quais rotas exigem autenticação.
.../Utilities.java Classe Utilitário: por exemplo, declarações de token de ID de filtro.
CHANGELOG.md Lista de alterações no exemplo.
CONTRIBUTING.md Diretrizes para contribuir com o exemplo.
LICENÇA` A licença para o exemplo.

Declarações de token de ID

Para extrair detalhes do token, o aplicativo usa o objeto do Spring Security AuthenticationPrincipal e OidcUser em um mapeamento de solicitação, conforme mostra o exemplo a seguir. Consulte o Controlador de Exemplo para obter todos os detalhes de como esse aplicativo usa declarações de token de ID.

import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
//...
@GetMapping(path = "/some_path")
public String tokenDetails(@AuthenticationPrincipal OidcUser principal) {
    Map<String, Object> claims = principal.getIdToken().getClaims();
}

Processar uma declaração de funções no token de ID

A declaração de funções do token inclui os nomes das funções às quais o usuário conectado está atribuído, conforme mostrado no exemplo a seguir:

{
  ...
  "roles": [
    "PrivilegedAdmin",
    "RegularUser",]
  ...
}

Uma maneira comum de acessar os nomes de função está documentada na seção Declarações de token de ID.

O Microsoft Entra ID Boot Starter v3.3 e superior também analisa a declaração de funções automaticamente e adiciona cada função ao Authoritiesdo usuário conectado, prefixando cada uma com a cadeia de caracteres APPROLE_. Essa configuração permite que os desenvolvedores usem funções de aplicativo com anotações de condição de mola PrePost usando o método hasAuthority. Por exemplo, você pode localizar as seguintes condições @PreAuthorize demonstradas em SampleController.java:

@GetMapping(path = "/admin_only")
@PreAuthorize("hasAuthority('APPROLE_PrivilegedAdmin')")
public String adminOnly(Model model) {
    // restrict to users who have PrivilegedAdmin app role only
}
@GetMapping(path = "/regular_user")
@PreAuthorize("hasAnyAuthority('APPROLE_PrivilegedAdmin','APPROLE_RegularUser')")
public String regularUser(Model model) {
    // restrict to users who have any of RegularUser or PrivilegedAdmin app roles
}

O código a seguir obtém uma lista completa de autoridades para um determinado usuário:

@GetMapping(path = "/some_path")
public String tokenDetails(@AuthenticationPrincipal OidcUser principal) {
   Collection<? extends GrantedAuthority> authorities = principal.getAuthorities();
}

Para entrar, o aplicativo faz uma solicitação ao ponto de extremidade de entrada do Microsoft Entra ID configurado automaticamente pela biblioteca cliente Spring Boot Starter do Microsoft Entra ID para Java, conforme mostra o exemplo a seguir:

<a class="btn btn-success" href="/oauth2/authorization/azure">Sign In</a>

Para desconectar, o aplicativo faz uma solicitação POST para o ponto de extremidade logout, conforme mostra o exemplo a seguir:

<form action="#" th:action="@{/logout}" method="post">
  <input class="btn btn-warning" type="submit" value="Sign Out" />
</form>

Elementos de IU dependentes de autenticação

O aplicativo tem uma lógica simples nas páginas de modelo da IU para determinar o conteúdo a ser exibido com base no fato de o usuário estar autenticado, conforme mostra o exemplo a seguir, usando as marcas Spring Security Thymeleaf:

<div sec:authorize="isAuthenticated()">
  this content only shows to authenticated users
</div>
<div sec:authorize="isAnonymous()">
  this content only shows to not-authenticated users
</div>

Proteger rotas com AADWebSecurityConfigurerAdapter

Por padrão, o aplicativo protege as páginas Detalhes do token de ID, Somente administradores e Usuários regulares para que apenas usuários conectados possam acessá-las. O aplicativo configura essas rotas da propriedade app.protect.authenticated do arquivo application.yml. Para configurar os requisitos específicos do seu aplicativo, você pode estender AADWebSecurityConfigurationAdapter em uma de suas classes. Para obter um exemplo, consulte a classe SecurityConfig deste aplicativo, mostrada no código a seguir:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends AADWebSecurityConfigurerAdapter{
  @Value( "${app.protect.authenticated}" )
  private String[] protectedRoutes;

    @Override
    public void configure(HttpSecurity http) throws Exception {
    // use required configuration form AADWebSecurityAdapter.configure:
    super.configure(http);
    // add custom configuration:
    http.authorizeRequests()
      .antMatchers(protectedRoutes).authenticated()     // limit these pages to authenticated users (default: /token_details, /admin_only, /regular_user)
      .antMatchers("/**").permitAll();                  // allow all other routes.
    }
}

Mais informações

Para obter mais informações sobre como os protocolos OAuth 2.0 funcionam neste cenário e em outros cenários, consulte Cenários de autenticação para o Microsoft Entra ID.