Um guia rápido para usar Keycloak com Spring Boot
1. Visão geral
Neste artigo, cobriremos os fundamentos da configuração de um servidor Keycloak, comoconnect a Spring Boot application para ele e como usá-lo com Spring Security.
2. O que é Keycloak?
Keycloak é uma solução de gerenciamento de identidade e acesso de código aberto voltada para aplicativos e serviços modernos.
O Keycloak oferece recursos como logon único (SSO), corretagem de identidade e logon social, federação de usuários, adaptadores de clientes, um console de administração e um console de gerenciamento de contas. Para saber mais sobre o Keycloak, visiteofficial page.
Em nosso tutorial, usaremos o Admin Console do Keycloak para configurar e, em seguida, conectar-se ao Spring Boot usando o Keycloak Client Adapter.
3. Configurando um servidor Keycloak
3.1. Baixar e instalar o Keycloak
Existem várias distribuições para escolher.
No entanto, neste tutorial, usaremos a versão autônoma.
BaixeKeycloak-3.3.0.Final Standalone server distribution da fonte oficial.
Depois de baixar a distribuição do servidor autônomo, podemos descompactar e iniciar o Keycloak do terminal:
unzip keycloak-3.3.0.Final.zip
cd keycloak-3.3.0.Final/bin
./standalone.sh -Djboss.socket.binding.port-offset=100
Após executar./standalone.sh, o Keycloak iniciará seus serviços. Assim que virmos uma linha contendoKeycloak 3.3.0.Final (WildFly Core 3.0.1.Final) iniciada, saberemos que sua inicialização foi concluída.
Abra um navegador e visitehttp://localhost:8180. Seremos redirecionados parahttp://localhost:8180/auth para criar um login administrativo:
Vamos criar um usuário chamado “initial1” com a senha “zaq1!QAZ“.
Agora vemos “Welcome to Keycloak”:
Agora podemos prosseguir para o Console Administrativo.
3.2. Criando um Reino
Vamos navegar nosso mouse no canto superior esquerdo para descobrir o botão“Create a Realm”:
Estamos chamando-o de “SpringBootKeycloak“:
3.3. Criando um cliente
Agora vamos navegar para a página Clientes. Como podemos ver na imagem abaixo,Keycloak comes with Clients that are already built in:
Mas precisamos adicionar um cliente ao nosso aplicativo, então clicamos em "Criar". Chamaremos o novo cliente de “login-app“:
Na próxima tela, para este tutorial, vamos deixar todos os padrões, exceto o “campo URIs de redirecionamento válidos”. Seremos redirecionados para a porta8081:
3.4. Criação de uma função e um usuário
Keycloak usa o acesso baseado em função. Portanto, cada usuário deve ter uma função.
Precisamos navegar para a página "Função":
Em seguida, adicionamos a função “user”:
Agora temos uma função que pode ser atribuída aos usuários, mas ainda não há usuários. Então, vamos à página "Usuários" e adicione um:
Adicionamos o usuário“user1”:
Depois que o usuário for criado, veremos esta página:
Agora podemos ir para a guia "Credenciais". Definiremos a senha para “[email protected]”:
Navegamos para a guia "Mapeamentos de funções". Atribuiremos a função do usuário:
3.5. Criando uma página de logon personalizada
O Keycloak fornece uma API REST para gerar e atualizar tokens de acesso. Podemos facilmente usar essa API para criar nossa própria página de login.
Primeiro, precisamos adquirir um token de acesso da Keycloak enviando uma solicitação POST para este URL:
http://localhost:8180/auth/realms/master/protocol/openid-connect/token
A solicitação deve ter este corpo JSON:
{
'client_id': 'your_client_id',
'username': 'your_username',
'password': 'your_password',
'grant_type': 'password'
}
Em resposta, obteremos umaccess_token e umrefresh_token.
O token de acesso deve ser usado em cada solicitação a um recurso protegido por Keycloak, simplesmente colocando-o no cabeçalhoAuthorization:
headers: {
'Authorization': 'Bearer' + access_token
}
Depois que o token de acesso expirar, podemos atualizá-lo enviando uma solicitação POST para o mesmo URL acima, mas contendo o token de atualização em vez do nome de usuário e senha:
{
'client_id': 'your_client_id',
'refresh_token': refresh_token_from_previous_request,
'grant_type': 'refresh_token'
}
Isso responderá com um novoaccess_token erefresh_token.
4. Criando um aplicativo de inicialização Spring
4.1. Dependências
As dependências mais recentes do Spring Boot Keycloak Starter podem ser encontradason Maven Central.
The Keycloak Spring Boot adaptercapitalizes on Spring Boot’s auto-configuration, então tudo o que precisamos fazer é adicionar o iniciador Keycloak Spring Boot ao nosso projeto.
Dentro do elemento XML das dependências, precisamos do seguinte para executar o Keycloak com o Spring Boot:
org.keycloak
keycloak-spring-boot-starter
Após o elemento XML de dependências, precisamos especificardependencyManagement para Keycloak:
org.keycloak.bom
keycloak-adapter-bom
3.3.0.Final
pom
import
Os seguintes contêineres incorporados são suportados agora e não requerem nenhuma dependência extra se estiver usando Spring Boot Keycloak Starter:
-
Tomcat
-
Ressaca
-
Jetty
4.2. Páginas da Web do Thymeleaf
Estamos usando o Thymeleaf para nossas páginas da web.
Temos três páginas:
-
external.html – uma página da web voltada para o exterior para o público
-
customers.html - uma página interna que terá seu acesso restrito apenas a usuários autenticados com a função "usuário".
-
layout.html - um layout simples, consistindo em dois fragmentos, que é usado tanto para a página externa quanto para a interna
O código para os modelos do Thymeleaf éavailable on Github.
4.3. Controlador
O controlador da web mapeia os URLs internos e externos para os modelos apropriados do Thymeleaf:
@GetMapping(path = "/")
public String index() {
return "external";
}
@GetMapping(path = "/customers")
public String customers(Model model) {
addCustomers();
model.addAttribute("customers", customerDAO.findAll());
return "customers";
}
Para o caminho/customers, estamos recuperando todos os clientes de um repositório e adicionando o resultado como um atributo paraModel. Mais tarde, iteramos através dos resultados no Thymeleaf.
4.4. Configuração Keycloak
Esta é a configuração básica obrigatória:
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloak
keycloak.resource=login-app
keycloak.public-client=true
Como lembramos, iniciamos o Keycloak na porta8180, portanto, o caminho especificado emkeycloak.auth-server-url. Nós inserimos o nome da região que criamos no console administrativo do Keycloak.
O valor que especificamos emkeycloak.resource corresponde ao cliente que nomeamos no console de administração.
Aqui estão as restrições de segurança que usaremos:
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
O estado de restrições de segurança acima garante que cada solicitação para/customers/* só será autorizada se quem está solicitando for um usuário autenticado com a função "usuário".
4.5. Demonstração
Agora, estamos prontos para testar nosso aplicativo. Para executar um aplicativo Spring Boot, podemos iniciá-lo facilmente através de um IDE como o Spring Tool Suite (STS) ou executar este comando no terminal:
mvn clean spring-boot:run
Visitamoslocalhost:8081:
Agora clicamos em “customers” para entrar na intranet, que é o local das informações confidenciais.
Podemos ver que fomos redirecionados para a autenticação por meio do Keycloak para ver se estamos autorizados a visualizar este conteúdo:
Assim que autenticamos e nossa autorização é verificada pelo Keycloak, somos redirecionados para a página de clientes restritos:
Agora terminamos a configuração de conexão do Spring Boot ao Keycloak e demonstramos como funciona.
Agora vamos revisar como usar o Spring Security em conjunto com nosso aplicativo existente.
5. Spring Security
Existe um adaptador de segurança Keycloak Spring e éalready included in our Spring Boot Keycloak Starter dependency. Veremos agora como integrar Spring Security com Keycloak.
5.1. Dependência
Para usar o Spring Security com Spring Boot, devemos adicionar esta dependência:
org.springframework.boot
spring-boot-starter-security
1.5.3
A última versão do Spring Boot Starter Security pode ser encontradaon Maven Central.
5.2. Classe de Configuração
Keycloak fornece umKeycloakWebSecurityConfigurerAdapter como uma classe base conveniente para criar uma instânciaWebSecurityConfigurer, o que é conveniente porque uma classe de configuração que estendeWebSecurityConfigurerAdapter é necessária para qualquer aplicativo protegido pelo Spring Security:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(
AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider
= keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/customers*")
.hasRole("user")
.anyRequest()
.permitAll();
}
}
Observe o código acima:
-
configureGlobal: executa tarefasSimpleAuthorityMapper para garantir que as funções não tenham o prefixoROLE_
-
keycloakConfigResolver: define que queremos usar o suporte ao arquivo de propriedades do Spring Boot em vez dokeycloak.json padrão
5.3. application.properties
Como configuramos as restrições de segurança com Spring Security, podemos remover as restrições de segurança anteriores que colocamos emapplication.properties.
Agora vamos adicionar isso ao nossoapplication.properties:
keycloak.principal-attribute=preferred_username
5.4. Controlador
Para usar o nome de usuário de um usuário, estamos atualizando nosso controlador para injetarPrincipal:
@GetMapping(path = "/customers")
public String customers(Principal principal, Model model){
addCustomers();
model.addAttribute("customers", customerDAO.findAll());
model.addAttribute("username", principal.getName());
return "customers";
}
5.5. Thymeleaf
No contêiner div, adicionaremos esta linha para saudar o usuário:
Hello, --name--.
6. Conclusão
Neste tutorial, configuramos um servidor Keycloak e o usamos com um aplicativo de inicialização Spring.
Também vimos como configurar o Spring Security e usá-lo em conjunto com o Keycloak. Uma versão funcional do código mostrado neste artigo está disponívelover on Github.