07 – Keycloak com Quarkus.io

Pré-requisitos

Configuração Keycloak

  • Iniciar o Keycloak com port-offset de 100:
$ cd bin

$ ./standalone.sh -Djboss.socket.binding.port-offset=100
  • Criar novo Realm quarkus
  • Criar uma Role ‘user’ e uma ‘admin’
  • Criar um usuário novo ‘user1’ com a Role ‘user’
  • Criar um novo Client clicando no menu Client e depois Create:
    • Client ID: quarkus-app
    • Client Protocol: openid-connect
    • Access Type: confidential
    • Valid Redirect URIs: http://localhost:8080/
    • Save

Configuração Quarkus.io

  • Criar o projeto quarkus com Keycloak e Resteasy-jsonb de extensions
mvn io.quarkus:quarkus-maven-plugin:0.20.0:create \

    -DprojectGroupId=br.com.pedrohos \

    -DprojectArtifactId=keycloak-quarkus \

    -Dextensions="keycloak, resteasy-jsonb"
  • Importar na sua IDE preferida
  • Criar classe usuário com o conteúdo a seguir:
asdasdsa
package br.com.pedrohos;
import org.keycloak.KeycloakSecurityContext;
public class Usuario {
    
    private final String nome;

    public Usuario(KeycloakSecurityContext context) {
        this.nome = context.getToken().getPreferredUsername();
    }
    
    public String getNome() {
        return nome;
   }
}
  • Criar classe MyResource.java com o conteudo a seguir
package br.com.pedrohos;

import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.KeycloakSecurityContext;

@Path("/api")
public class MyResource {

    @Inject
    KeycloakSecurityContext keycloakSecurityContext;

    @GET
    @Path("/me")
    @RolesAllowed("user")
    @Produces(MediaType.APPLICATION_JSON)
    @NoCache
    public Usuario minhasInfos() {
        return new Usuario(keycloakSecurityContext);
    }

    @GET
    @Path("/admin")
    @RolesAllowed("admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String admin() {
        return "Admin infos";
    }
}
  • salvar a instalação do client do keycloak em src/main/resources

exemplo:

{
  "realm": "quarkus",
  "auth-server-url": "http://localhost:8180/auth",
  "ssl-required": "external",
  "resource": "quarkus-app",
  "credentials": {
    "secret": "secret"
  },

  "confidential-port": 0
}
  • Executar a aplicação:
./mvnw clean compile quarkus:dev

Testando aplicação

 

  • Recuperar Token
export access_token=$(\
    curl -X POST http://localhost:8180/auth/realms/quarkus/protocol/openid-connect/token \
    --user quarkus-app:secret \
    -H 'content-type: application/x-www-form-urlencoded' \
    -d 'username=user1&password=1234&grant_type=password' | jq --raw-output '.access_token' \

 )
  • Acessar endpoints
curl -v -X GET \
  http://localhost:8080/api/me \
  -H "Authorization: Bearer "$access_token
curl -v -X GET \
  http://localhost:8080/api/admin \
  -H "Authorization: Bearer "$access_token

 

06 – Keycloak com Spring boot

Pré-requisitos

Configuração Keycloak

  • Iniciar o Keycloak com port-offset de 100:
$ cd bin

$ ./standalone.sh -Djboss.socket.binding.port-offset=100
  • Criar uma Role ‘user’
  • Criar um usuário novo com a Role ‘user’
  • Criar um novo Client clicando no menu Client e depois Create:

Configuração Spring Boot

  • Acessar: https://start.spring.io e criar um novo projeto com:
    • Maven Project
    • Java Language
    • Spring Boot 2.1.7
    • group: br.com.pedrohos
    • Artifact: keycloak-springboot
    • Dependencies: Spring Web Starter e Thymeleaf
  • Importar na sua IDE preferida
  • Criar uma classe WebController.java com o conteudo:
package br.com.pedrohos.keycloakspringboot.controllers;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class WebController {

    @GetMapping(path = "/")
    public String index() {
        return "index";
    }

    @GetMapping(path = "/private")
    public String secure(Model model) {
        model.addAttribute("message", "This is a private page!");
        return "secure";
    }
}

 

  • Criar o resources/templates/index.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Public Page</title>
    </head>
    <body>
        <h1>This is a public page</h1>
        <p>Get your greeting <a href="/private">here</a></p>
     </body>
</html>
  • Criar o resources/templates/secure.html:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head> 
    <title>Secure Page</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="${message}" />
</body>
</html>

 

  • Editar o resources/application.properties
keycloak.auth-server-url=http://localhost:8180/auth

keycloak.realm=master

keycloak.resource=springboot-app

keycloak.public-client=true

keycloak.security-constraints[0].authRoles[0]=user

keycloak.security-constraints[0].securityCollections[0].patterns[0]=/private/*
  • Editar o pom.xml
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.keycloak.bom</groupId>
				<artifactId>keycloak-adapter-bom</artifactId>
				<version>6.0.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependency>
	     <groupId>org.keycloak</groupId>
	     <artifactId>keycloak-spring-boot-starter</artifactId>
	</dependency>
  • Iniciar o projeto:
mvn clean spring-boot:run

04 – Configurando Banco de Dados MySQL

Pré-requisitos

  • Java 1.8+
  • MySQL 8+ instalado
  • Keycloak instalado (ver vídeo 02)

Configuração

  1. Fazer o Download do MySQL Connector 8+
  2. Criar um novo usuário no mysql
CREATE USER 'keycloak'@'%' IDENTIFIED WITH mysql_native_password BY 'Keycloak@123';

Você precisa criar o usuário com tipo mysql_native_password se não terá um erro de “Unable to load authentication plugin ‘caching_sha2_password’

  • Criar um novo Database chamado keycloak
CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Crie o database com CHARACTER SET utf8 COLLATE uft8_unicode_ci ser não vai pegar o erro:  ERROR [org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider] (ServerService Thread Pool — 63) Change Set META-INF/jpa-changelog-1.9.1.xml::1.9.1::keycloak failed.  Error: (conn=16) Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs [Failed SQL: ALTER TABLE keycloak.REALM MODIFY CERTIFICATE VARCHAR(4000)]

  • Dar previlégios ao usuário
GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'%';
  • Iniciar o Keycloak
$ cd bin

$ ./standalone.sh
  • Iniciar o jboss-cli.sh
$ sh jboss-cli.sh
  • Adicionar o módulo
module add --name=com.mysql --dependencies=javax.api,javax.transaction.api --resources=/opt/oracle/mysql-connector-java-8.0.17/mysql-connector-java-8.0.17.jar --module-root-dir=modules/system/layers/keycloak/
  • Conectar no jboss-cli
connect
  • Criar um novo Driver
/subsystem=datasources/jdbc-driver=com.mysql:add(driver-name=com.mysql,driver-module-name=com.mysql,xa-datasource-class=com.mysql.cj.jdbc.MysqlXADataSource)
  • Remover Datasource H2
/subsystem=datasources/data-source=KeycloakDS: remove()
  • Criar um novo Datasource
data-source add --name=KeycloakDS --jndi-name=java:jboss/datasources/KeycloakDS --enabled=true --max-pool-size=30 --password=Keycloak@123 --user-name=keycloak --driver-name=com.mysql --use-java-context=true --connection-url=jdbc:mysql://localhost:3306/keycloak?useSSL=false
  • Mostrar o SPI connectionsJpa:
<spi name="connectionsJpa">
                <provider name="default" enabled="true">
                    <properties>
                        <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
                        <property name="initializeEmpty" value="true"/>
                        <property name="migrationStrategy" value="update"/>
                        <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
                    </properties>
                </provider>
            </spi>

 

03 – Adicionando segurança em uma aplicação Rest no Wildfly

Pré-requisitos

Iniciar o Keycloak

$ cd bin
$ ./standalone.sh -Djboss.socket.binding.port-offset=100

Configuração Wildfly 17

$ curl https://download.jboss.org/wildfly/17.0.1.Final/wildfly-17.0.1.Final.zip --output wildfly-17.0.1.Final.zip
  • Unzip
$ unzip -q wildfly-17.0.1.Final.zip
  • Acessar pasta do Wildfly
$ cd wildfly-17.0.1.Final/
$ curl https://downloads.jboss.org/keycloak/6.0.1/adapters/keycloak-oidc/keycloak-wildfly-adapter-dist-6.0.1.zip --output keycloak-wildfly-adapter-dist-6.0.1.zip 
  • unzip do adapter: 
$ unzip -q keycloak-wildfly-adapter-dist-6.0.1.zip 
  • Instalar o adapter no Wildfly
$ cd bin/
$ ./jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
  • Iniciar o Wildfly
$ ./standalone.sh

Configuração do projeto

 

  • Fazer o clone do projeto no github ou fazer o download
$ git clone https://github.com/pedro-hos/keycloak-pocs
  • executar o comando maven para compilar e fazer o deploy do mesmo
$ mvn clean wildfly:deploy
  • Editar o pom.xml com o seguinte conteúdo:
</properties>

(...)

    <version.keycloak>6.0.1</version.keycloak>

</properties>

(...)

<dependencyManagement>

        <dependencies>

            <dependency>

               <groupId>org.keycloak.bom</groupId>

               <artifactId>keycloak-adapter-bom</artifactId>

               <version>${version.keycloak}</version>

               <type>pom</type>

               <scope>import</scope>

           </dependency>

           <dependency>

               <groupId>org.keycloak</groupId>

               <artifactId>keycloak-test-helper</artifactId>

               <version>${version.keycloak}</version>

               <scope>test</scope>

           </dependency>

           <dependency>

               <groupId>org.keycloak.bom</groupId>

               <artifactId>keycloak-spi-bom</artifactId>

               <version>${version.keycloak}</version>

               <type>pom</type>

               <scope>import</scope>

           </dependency>

(...)
  • Editar o arquivo src/main/webapp/WEB-INF/web.xml com o seguinte conteúdo:
<security-constraint>
<web-resource-collection>

            <web-resource-name>secured</web-resource-name>

            <url-pattern>/secured</url-pattern>

        </web-resource-collection>

        <auth-constraint>

            <role-name>user</role-name>

        </auth-constraint>

    </security-constraint>

    <security-constraint>

        <web-resource-collection>

            <web-resource-name>admin</web-resource-name>

            <url-pattern>/admin</url-pattern>

        </web-resource-collection>

        <auth-constraint>

            <role-name>admin</role-name>

        </auth-constraint>

    </security-constraint>

    <login-config>

        <auth-method>KEYCLOAK</auth-method>

    </login-config>

    <security-role>

        <role-name>user</role-name>

    </security-role>

    <security-role>

        <role-name>admin</role-name>

    </security-role>

 

Configuração no Keycloak

 

  1. Acessar http://localhost:8180/auth e fazer login com seu admin
  2. Criar um novo Client clicando no menu Client e depois Create:
    1. Client ID: service-jaxrs
    2. Client Protocol: openid-connect
    3. Valid Redirect URIs: http://localhost:8080/service/
    4. Save
    5. Mudar o Access Type para public
  3. Fazer o Download da instalação clicando na aba instalação e depois selecionar Keycloak OIDC JSON salvando o arquivo na pasta config/ no root do projeto
  4. Criar Role em Roles, com nome user.
  5. Criar um usuário de em Users e dar um nome e add as roles

Deploy e testes

  • Deploy da aplicação
$ mvn clean wildfly:deploy
  • executar o comando a seguir:
curl -v -X GET http://localhost:8080/service/public

curl -v -X GET http://localhost:8080/service/secured

curl -v -X GET http://localhost:8080/service/admin
  • Pegar a chave
export access_token=$(curl -X POST http://localhost:8180/auth/realms/master/protocol/openid-connect/token -H 'content-type: application/x-www-form-urlencoded' -d 'username=pedro&password=1234&grant_type=password&client_id=service-jaxrs' | jq --raw-output '.access_token')
  • ver a chave
echo $access_token

 

  • Fazer o curl passando o token
curl -v -X GET http://localhost:8080/service/secured -H "Authorization: bearer $access_token"

curl -v -X GET http://localhost:8080/service/admin -H "Authorization: Bearer "$access_token

02 – Instalando o Keycloak

  • Faça o download do keycloak:
curl https://downloads.jboss.org/keycloak/6.0.1/keycloak-6.0.1.zip --output keycloak-6.0.1.zip
  • Unzip 
unzip keycloak-6.0.1.zip
  • Adicionando um novo usuário admin
./add-user-keycloak.sh -r master -u admin -p admin
  • Iniciando o Keycloak
./standalone.sh 
  • Acessar: http://localhost:8080/auth
  • Criar um novo Realm
  • Criar uma nova Role
  • Criar um novo usuário e associar com a Role criada
  • Fazer login com o usuário criado
  • Modificar algumas configurações de Realm