Nesta parte 2, criamos a aplicação e testamos seu login e o logout via Keycloak. Nosso container de aplicação será o Wildfly 15.
Criando e publicando MyWebApp
MyWebApp é uma aplicação maven com JSF e uma página inicial index.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>My App</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid>
<h1>Welcome to My APP!</h1>
<h:commandButton value="LOGOUT" action="#{indexMB.logout()}" />
</h:panelGrid>
</h:form>
</h:body>
</html>
E o managed bean IndexMB:
package acme.view;
import javax.enterprise.inject.Model;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.KeycloakSecurityContext;
@Model
public class IndexMB {
public String logout() throws ServletException {
System.out.println("Logout!.....");
HttpServletRequest req = (HttpServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest();
KeycloakSecurityContext context = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
System.out.println("-------- realm name: "+context.getRealm());
req.logout();
return null;
}
}
Abaixo o arquivo de configuração pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.acme</groupId>
<artifactId>MyWebApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-core -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>5.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax/javaee-api -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>myapp</finalName>
</build>
</project>
E o arquivo web.xml em WEB-INF. Nele é necessário especificar o método de autenticação como KEYCLOAK:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>myapp</display-name>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- Keycloak confs -->
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Developer</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK</auth-method>
<realm-name>TeamSecurity</realm-name>
</login-config>
<security-role>
<role-name>Developer</role-name>
</security-role>
</web-app>
Na pasta WEB-INF colocamos o arquivo keycloak.json que foi gerado pelo console admin do Keycloak na parte 1 deste post. O código completo do projeto se encontra no github.Frameworks de Autorização e Autenticação
O Keycloak trabalha com 2 formas de autenticação: OpenID Connect e o SAML 2.0.
OpenID Connect (OIDC) é uma camada de autenticação e identificação de usuário no topo do framework OAuth 2.0. O OAuth 2.0 trabalha com autorizações (o quê pode ser acessado), enquanto o OIDC define um fluxo de autenticação de usuários (quem está acessando).
SAML 2.0 é um padrão de troca de informações entre partes sobre autorização e autenticação por meio de um arquivo XML digitalmente assinado.
Quando for segurar uma aplicação pelo Keycloak a primeira coisa a decidir é qual mecanismo de autenticação e autorização você ira usar. Na maioria dos casos recomenda-se o OIDC, o qual será usado neste post.
Client Adapters
São bibliotecas que tornam mais fácil segurar aplicações e serviços com o Keycloak. Há vários adpaters diferentes dependendo de qual plataforma sua aplicação esteja rodando. Se for uma aplicação Java, existem adpaters para o Wildfly, Tomcat, Spring Boot, Jetty, etc. Há ainda outros adapaters para Java Script, Node.js, Python, iOS, entre outras. Veja a relação completa aqui.
Como nosso container é o WildFly, vamos utilizar seu respectivo adapter para o OIDC. Baixe o arquivo keycloak-wildfly-adapter-dist-5.0.0.zip. Descompacte seu conteúdo (pastas bin, docs e modules) na pasta raiz do Wildfly.
Após descompactar o arquivo, execute o seguinte comando dentro do diretório raiz do Wildfly:
wildfly-15.0.1.Final$ ./bin/jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
Esse script edita os arquivos de configuração do Wildfly para que ele fique ciente do método de autenticação do Keycloak referenciados no web.xml.Os próximos passos são:
1 Subir o Keycloak
keycloak-5.0.0$ ./bin/standalone.sh -Djboss.socket.binding.port-offset=100
Após executar o comando, acesse o Keycloak em http://localhost:8180/auth/.2 Subir o WildFly
wildfly-15.0.1.Final$ ./bin/standalone.sh
Após executar o comando, acesse o Wildfly em http://localhost:9990.3 Empacotar a aplicação
~/workspace/MyWebApp$ mvn install
Nesse caso utilizamos o Maven. Como alternativa, você pode construir a aplicação utilizando as ferramentas de alguma IDE. O comando acima gera o arquivo myapp.war dentro da pasta target. Copie a URL do arquivo.4 Publicar myapp.war no Wildfly
Para fazer o deploy da aplicação, vamos utilizar o cliente do Wildfly jboss-cli.sh, que se encontra dentro da pasta bin do Wildfly (ou jboss-cli.bat se for Windows). Execute o seguintes comandos, substituindo o caminho de myapp.war de acordo com o seu ambiente:
~/Servers/wildfly-15.0.1.Final$ ./bin/jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9990 /] deploy /home/rafael/workspace/MyWebApp/target/myapp.war
Não esqueça de substituir o caminho até myapp.war de acordo com o seu ambiente.Pronto! Aplicação foi publicada e possui um mecanismo de autenticação totalmente desacoplado. Para testar acesse a aplicação em http://localhost:8080/myapp. Você vai bater de frente com a seguinte página:
Logue com o usuário que você criou na parte 1 deste post, para o qual foi atribuida a role Developer.
Após logar, você será direcionado para a página da aplicação:
Clique em logout. E o Keycloak vai encerrar sua sessão e você é novamente redirecionado para a página de login.
Servidor de Sessão
O Keycloak também funciona como um servidor de sessão. Acesse myapp de um browser diferente e em seguida logue com o admin na console de administração do Keycloak.
No realm TemSecurity, no menu client, escolha o client MyWebApp, e depois clique na aba Sessions:
Você verá que o keycloak lista o usuário que você criou com 2 sessões ativas. Clique no usuário, e você poderá derrubá-lo a partir do console do Keycloak.
O Keycloak é uma solução muito interessante que fornece autenticação como microserviço, ou seja, não há dependência entre os componentes internos da aplicação e os processos de autenticação, autorização e manipulação dos dados do usuário. Nenhuma linha de código para login/logout foi escrita e a aplicação já está totalmente segurada.
referências:
https://www.keycloak.org/documentation.html
"Determinarás tu algum negócio, e ser-te-á firme, e a luz brilhará em teus caminhos."
Jó 22:28