Proteja sua API com o Spring Data MongoDB e o Microsoft EntraID
Avaliar este tutorial
Bem-vindo ao nosso tutorial prático, onde você aprenderá como construir uma API RESTful com o Spring Data MongoDB, fortalecido pela segurança do Microsoft Entra ID e OAuth2. Nesta viagem, guiaremos você pela criação de uma API de lista de tarefas simplificada, mostrando não apenas como configurá-la, mas também como protege-la de forma eficaz.
Este guia foi elaborado para fornecer as ferramentas e o conhecimento necessários para implementar uma API segura e funcional desde o início. Vamos mergulhar de cabeça e começar a construir algo incrível juntos!
- Java Development Kit (JDK) versão 17 ou superior
- Um aplicativo Spring Boot — você pode criar um projeto Maven com o Spring Initializr; há algumas dependências que você precisará:
- Spring Web
- Servidor de recursos OAuth2
- Azure Active Directory
- Selecione a versão 17 ou superior do Java e gere um JAR
Você pode acompanhar este tutorial e construir seu projeto enquanto lê ou pode clonar o repositório diretamente:
1 git clone git@github.com:mongodb-developer/java-spring-boot-secure-todo-app.git
Quando esses pré-requisitos estiverem em vigor, estamos prontos para começar a configurar nossa API RESTful segura do Spring Boot. Nosso primeiro passo será lançar a base com
application.properties
.1 spring.application.name=todo 2 spring.cloud.azure.active-directory.enabled=true 3 spring.cloud.azure.active-directory.profile.tenant-id=<YOUR-TENANT-ID> 4 spring.cloud.azure.active-directory.credential.client-id=<YOUR-APPLICATION-ID> 5 spring.security.oauth2.client.registration.azure.client-authentication-method=none 6 spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/<YOUR-TENANT-ID/v2.0 7 server.forward-headers-strategy=framework 8 springdoc.swagger-ui.use-root-path=true 9 springdoc.swagger-ui.oauth.use-pkce-with-authorization-code-grant=true 10 spring.security.oauth2.client.registration.azure.redirect-uri=http:<YOUR-APPLICATION-URL>/swagger-ui/oauth2-redirect.html 11 spring.data.mongodb.uri=<YOUR-MONGODB-CONNECTION-URI> 12 spring.data.mongodb.database=<YOUR-MONGODB-DATABASE>
spring.application.name=todo
Define o nome do seu aplicativo Spring Bootspring.cloud.azure.active-directory...
: Integra seu aplicativo com o Azure AD para autenticação e autorizaçãospring.security.oauth2.client.registration.azure.client-authentication-method=none
: especifica o método de autenticação para o cliente OAuth2 ; defini-lo comonone
é usado para clientes públicos, onde o segredo do cliente não é aplicávelspring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/<YOUR-TENANT-ID/v2.0
: Configura seu aplicativo como um servidor de recursos OAuth2 , validando tokens JWT emitidos pelo Azure ADserver.forward-headers-strategy=framework
: Configura como seu aplicativo lida com cabeçalhos encaminhados, o que é importante para aplicativos atrás de proxies ou balancers de carga, especialmente no que diz respeito à construção de URLs corretos para redirecionamentosspringdoc.swagger-ui...
: configurar a IU do Swagger, permitindo especificamente que ela seja executada no caminho raiz e use a chave de prova para troca de código (PKCE) com a concessão de código de autorização2 do OAuth
Crie um pacote chamado
model
e adicione a classe Todo. Aqui, teremos nosso POJO que mapeia para nossos documentos em nosso MongoDB database.1 package com.example.todo.model; 2 3 import org.springframework.data.annotation.Id; 4 import org.springframework.data.mongodb.core.mapping.Document; 5 6 7 public class Todo { 8 9 private String id; 10 private String title; 11 private boolean completed; 12 13 // Constructors, getters, and setters 14 }
Crie um pacote separado chamado
repository
com a interface TodoRepository
. Para facilitar nossa vida, vamos usar o MongoRepository. Isso nos permitirá usar as CRUD em nosso MongoDB database sem precisar configurar todo o nosso código boilerplate.1 package com.example.todo.model.repository; 2 3 import com.example.todo.model.Todo; 4 import org.springframework.data.mongodb.repository.MongoRepository; 5 6 public interface TodoRepository extends MongoRepository<Todo, String> { 7 }
Em seguida, crie um pacote
service
e uma classe TodoService. Isso conterá nossa lógica de negócios para nosso aplicativo.1 package com.example.todo.service; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Service; 5 6 import com.example.todo.model.Todo; 7 import com.example.todo.model.repository.TodoRepository; 8 9 import java.util.List; 10 import java.util.Optional; 11 12 13 public class TodoService { 14 15 private final TodoRepository todoRepository; 16 17 public TodoService(TodoRepository todoRepository) { 18 this.todoRepository = todoRepository; 19 } 20 21 public List<Todo> findAll() { 22 return todoRepository.findAll(); 23 } 24 25 public Optional<Todo> findById(String id) { 26 return todoRepository.findById(id); 27 } 28 29 public Todo save(Todo todo) { 30 return todoRepository.save(todo); 31 } 32 33 public void deleteById(String id) { 34 todoRepository.deleteById(id); 35 } 36 }
Para estabelecer seus endpoints de API, crie um pacote
controller
e uma classeTodoController . Há algumas coisas acontecendo aqui. Para cada um dos pontos de extremidade da API aos quais queremos restringir o acesso, usamos @PreAuthorize("hasAuthority('SCOPE_Todo.<SCOPE>')")
onde <SCOPE>
corresponde aos escopos que definiremos no Microsoft Entra ID.Também desativamos o CORS aqui. Em um aplicativo de produção, você desejará especificar quem pode acessar isso e provavelmente não apenas permitir todos, mas isso é bom para este tutorial.
1 package com.example.todo.controller; 2 3 import com.example.todo.model.Todo; 4 import com.example.todo.sevice.TodoService; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.security.access.prepost.PreAuthorize; 8 import org.springframework.security.core.Authentication; 9 import org.springframework.web.bind.annotation.*; 10 import java.util.List; 11 12 13 14 15 public class TodoController { 16 17 public TodoController(TodoService todoService) { 18 this.todoService = todoService; 19 } 20 21 22 public List<Todo> getAllTodos() { 23 return todoService.findAll(); 24 } 25 26 27 public Todo getTodoById( String id) { 28 return todoService.findById(id).orElse(null); 29 } 30 31 32 33 public Todo createTodo( Todo todo, Authentication authentication) { 34 return todoService.save(todo); 35 } 36 37 38 39 public Todo updateTodo( String id, Todo todo) { 40 return todoService.save(todo); 41 } 42 43 44 45 public void deleteTodo( String id) { 46 todoService.deleteById(id); 47 } 48 }
Agora, precisamos configurar nossa UI do MongoDB para nosso aplicativo. Crie um pacote do
config
e uma classeOpenApiConfiguration. Muito disso é padronizado, com base nos aplicativos de demonstração fornecidos por Springdoc.org. Estamos configurando um fluxo de autorização e especificando os escopos disponíveis em nosso aplicativo. Vamos criá-los em uma parte posterior deste aplicativo, mas preste atenção ao nome da API ao definir escopos (.addString("api://todo/Todo.User", "Access todo as a user")
. Você tem uma opção de configurar isso mais tarde, mas ela precisa ser a mesma no aplicativo e no Microsoft Entra ID.1 package com.example.todo.config; 2 3 import io.swagger.v3.oas.models.Components; 4 import io.swagger.v3.oas.models.OpenAPI; 5 import io.swagger.v3.oas.models.info.Info; 6 import io.swagger.v3.oas.models.security.OAuthFlow; 7 import io.swagger.v3.oas.models.security.OAuthFlows; 8 import io.swagger.v3.oas.models.security.Scopes; 9 import io.swagger.v3.oas.models.security.SecurityScheme; 10 11 import org.springframework.beans.factory.annotation.Value; 12 import org.springframework.context.annotation.Bean; 13 import org.springframework.context.annotation.Configuration; 14 15 16 17 class OpenApiConfiguration { 18 19 20 private String tenantId; 21 22 23 OpenAPI customOpenAPI() { 24 OAuthFlow authorizationCodeFlow = new OAuthFlow(); 25 authorizationCodeFlow.setAuthorizationUrl(String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/authorize", tenantId)); 26 authorizationCodeFlow.setRefreshUrl(String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenantId)); 27 authorizationCodeFlow.setTokenUrl(String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenantId)); 28 authorizationCodeFlow.setScopes(new Scopes() 29 .addString("api://todo/Todo.User", "Access todo as a user") 30 .addString("api://todo/Todo.Admin", "Access todo as an admin")); 31 OAuthFlows oauthFlows = new OAuthFlows(); 32 oauthFlows.authorizationCode(authorizationCodeFlow); 33 SecurityScheme securityScheme = new SecurityScheme(); 34 securityScheme.setType(SecurityScheme.Type.OAUTH2); 35 securityScheme.setFlows(oauthFlows); 36 return new OpenAPI() 37 .info(new Info().title("RESTful APIs for Todo")) 38 .components(new Components().addSecuritySchemes("Microsoft Entra ID", securityScheme)); 39 } 40 }
A última coisa que precisamos fazer é criar uma classeWebConfig em nosso pacote
config
. Aqui, só precisamos desabilitaro Cross-Site Request Forgery (CSRF).1 package com.example.todo.config; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 import org.springframework.security.web.SecurityFilterChain; 7 import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; 8 9 10 11 public class WebConfig { 12 13 14 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 15 http.csrf(AbstractHttpConfigurer::disable); 16 return http.build(); 17 } 18 }
Ao usar o OAuth para autenticação em um aplicativo da Web, a necessidade de tokens CSRF depende do contexto específico do seu aplicativo e de como o OAuth está sendo implementado.
Em nosso aplicativo, estamos usando um aplicativo de página única (SPAs) para interagir com nossa API. OAuth é frequentemente usado com tokens (como JWTs) obtidos por meio do fluxo de código de autorização OAuth com PKCE, portanto o CSRF não é necessário. Se o seu aplicativo ainda usar cookies (acesso à web tradicional) para manter o estado da sessão após o fluxo OAuth, implemente tokens CSRF para se proteger contra ataques CSRF. Para uma API que atende a um SPA, dependeremos de tokens de portador.
É hora de registrar um novo aplicativo com o Microsoft Entra ID (anteriormente conhecido como Azure Active Directory) e preparar tudo para proteger nossa API RESTful com autenticação e autorização OAuth2 . O Microsoft Entra ID é uma solução abrangente de gerenciamento de identidade e acesso (IAM) fornecida pela Microsoft. Ele abrange vários serviços projetados para ajudar a gerenciar e proteger o acesso a aplicativos, serviços e recursos na nuvem e em ambientes locais.
- Inicie sessão no portal do Azure. Se você tiver acesso a vários locatários, selecione o locatário no qual deseja registrar um aplicativo.
- Procure e selecione o serviçoMicrosoft Entra ID.
- Se ainda não tiver um, crie um aqui.
- No menu do lado esquerdo, em Manage (Gerenciar), selecione App registrations (Registros de aplicativos ) e New registration (Novo registro).
- Insira um nome para o seu aplicativo no campoNome. Para este tutorial, vamos nos limitar ao exemplo clássico de CRUD, uma API de lista de tarefas, então a chamaremos de .
TodoAPI
- Para Tipos de contas com suporte, selecione Contas em qualquer diretório organizacional (Qualquer diretório Microsoft Entra – Multitenant) e contas pessoais da Microsoft. Isso permitirá o conjunto mais amplo de entidades da Microsoft.
- Selecione Registrar para criar o aplicativo.
- Na páginaVisão geraldo aplicativo, procure o valor deID do aplicativo (cliente) e registre-o para uso posterior. Você precisa dele para configurar o arquivo
application.properties
para esse aplicativo. - Navegue até Gerenciar e clique em Expor uma API. Localize o URI do ID do aplicativo na parte superior da página e clique em Adicionar.
- Na telaEditar URI do ID do aplicativo, é necessário gerar um URI de ID do aplicativo distinto. Opte pelo padrão fornecido
api://{client ID}
ou escolha um nome descritivo comoapi://todo
antes de clicar em Salvar. - Go para Manage (Gerenciar), clique em Expose an API (Expor uma API), depois em Add a scope (Adicionar um escopo) e forneça os detalhes especificados:
- Em Nome do escopo, insira ToDo.User.
- Para Quem pode autorizar, selecione Administradores e usuários.
- Para o nome de exibição do consentimento do administrador, digite Create and edit ToDo data (Criar e editar dados de tarefas).
- Para Descrição de autorização do administrador, insira Permite que usuários autenticados criem e editem os dados do ToDo.
- Para o State, mantenha-o ativado.
- Selecione Adicionar escopo.
- Repita as etapas anteriores para adicionar os outros escopos: ToDo.Admin, que concederá ao usuário autenticado permissão para excluir. Agora que criamos nosso aplicativo e configuramos nosso EntraID, vamos ver como solicitar nosso token de acesso. Neste ponto, você pode carregar sua API para os aplicativos do Azure Spring, seguindo nosso tutorial deIntrodução aos aplicativos do Azure Spring e ao MongoDB Atlas, mas manteremos tudo em execução local para este tutorial.
As API RESTful servem como um servidor de recursos, protegido pelo Microsoft ID. Para obter um token de acesso, é necessário registrar um aplicativo diferente no Microsoft Entra ID e atribuir permissões ao aplicativo cliente.
Vamos registrar um segundo aplicativo no ID Microsoft Entra.
- Repita as etapas 1 a 6 acima, mas desta vez, nomeie seu aplicativo
TodoClient
. - Na páginaVisão geraldo aplicativo, procure o valor de ID do aplicativo (cliente). Registre para uso posterior. Você precisa dele para adquirir um token de acesso.
- Selecione Permissões de API e Adicione uma permissão.
- Em My APIs, selecione o aplicativo
TodoAPI
que você registrou anteriormente. Escolha as permissões que seu aplicativo cliente precisa para operar corretamente. Nesse caso, selecione as permissõesToDo.Admin e ToDo.User. Confirme sua seleção clicando em Adicionar permissões para aplicá-las ao seu aplicativoTodoClient
. - Selecione Conceder consentimento de administrador para
<YOUR-TENANT-NAME>
para conceder consentimento de administrador para as permissões que você adicionou.
Agora que temos a API criada e o aplicativo cliente registrado, é hora de criar nosso usuário para conceder permissão. Vamos criar um membro em nosso locatário do Microsoft Entra para interagir com nosso
TodoAPI
.- Navegue até seu ID Microsoft Entra e em Gerenciar, escolha Usuários.
- Clique em Novo usuário e depois em Criar novo usuário.
- Na seção Criar novo usuário, preencha Nome principal do usuário , Nomedeexibiçãoe Senha. O usuário precisará alterar isso após o primeiro login.
- Clique emRevisar + criar para examinar suas entradas. Pressione Criar para finalizar a criação do usuário.
Para conectar nosso aplicativo para este tutorial, usaremos o Swagger. Precisamos atualizar as configurações do OAuth2 para autorizar os usuários na interface do usuário do Swagger, permitindo que eles obtenham tokens de acesso por meio do aplicativo
TodoClient
.- Acesse seu locatário do Microsoft Entra ID e navegue até o aplicativo
TodoClient
que você registrou. - Clique em Gerenciar, depois em Autenticação, escolha Adicionar uma plataformae selecione Aplicativo de página única. Para fluxos híbridos e de concessão implícita, escolha tokens de acesso e tokens de ID.
- Na seção Redirecionar URIs, insira o URL ou ponto de extremidade do seu aplicativo seguido de
/swagger-ui/oauth2-redirect.html
como o URL de redirecionamento OAuth2 e clique em Configurar.
Navegue até a URL publicada do aplicativo e clique em Autorizar para iniciar o2 processo de autenticação OAuth . Na caixa de diálogo Autorizações disponíveis , insira
TodoClient
o ID do cliente do aplicativo na caixaclient_id , marque todas as opções no campoEscopos , deixe a caixa client_secret vazia e clique em Autorizar para prosseguir para a página de login do Microsoft Entra. Depois de entrar com o usuário mencionado anteriormente, você retornará à caixa de diálogo Autorizações disponíveis . Voila! Você deve ser saudado com sua tela de login bem-sucedida .Agora, devemos estar prontos para testar alguns de nossos endpoints seguros. Envie uma solicitação de postagem de amostra usando a interface do usuário do Swagger.
Se tudo estiver autorizado corretamente, seus dados agora devem estar em seu MongoDB database.
E aqui está: uma viagem desde os fundamentos da configuração de um ambiente MongoDB e Azure, passando pela criação de uma API RESTful segura com Spring Boot, até os testes com a UI do MongoDB. Este guia teve como objetivo armar você com as ferramentas para criar uma API de lista de tarefas robusta e segura, demonstrando o poder de combinar o Spring Data MongoDB com os recursos de segurança do Microsoft Entra ID e OAuth2.
Ao acompanhar, você viu como registrar e configurar seu aplicativo e cliente no Microsoft Entra ID, definir as permissões necessárias e até mesmo como configurar os usuários para interagir com sua API. Seus dados agora residem com segurança no MongoDB, acessados por meio de uma API cuidadosamente construída que respeita os padrões de segurança modernos.
Se você encontrou este tutorial útil ou interessante, confira o Centro do Desenvolvedor. Aprenda a hospedar a API que você acabou de criar nos aplicativos do Azure Spring em Introdução aos aplicativos do Azure Spring e ao MongoDB Atlas, ou leia mais sobre a proteção de dados com Como implementar a criptografia em nível de campo do lado do cliente (CSFLE) em Java com o Spring Data MongoDB.
Você está pronto para começar a construir com Atlas no Azure? Comece hoje mesmo gratuitamente a usar oMongoDB Atlas no Azure Marketplace
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.