GUI Plugin

Développez un premier plugin de la GUI. Basé sur Spring Boot, cet exemple vous permettra de bien démarrer votre plugin.

Objectif

Ce module de formation a pour objectif de poser les bases du développement d’un plugin de la GUI sécurisé. Ce plugin pourra être consommé depuis et à travers FlowerDocs GUI. Il exposera un service consommant les services exposés par FlowerDocs Core.

Prérequis

Ce tutoriel est basé sur Maven et nécessite l’utilisation de l’Artifactory Arondor dans lequel sont déployées les librairies FlowerDocs.

Mise en place

Création du projet

A l’aide de votre IDE préféré, commencez par créer un nouveau projet Maven avec le POM suivant :

<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.flower.docs.samples</groupId>
    <artifactId>secured-gui-plugin</artifactId>
    <version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>com.flower.docs</groupId>
			<artifactId>flower-docs-starter-client</artifactId>
			<version>2.5.2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.3.0.RELEASE</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
							<goal>build-info</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<executable>true</executable>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Application Spring Boot

Cette application Spring Boot s’appuie sur le starter Spring Boot fourni par FlowerDocs.

Pour commencer, nous avons besoin d’une main class Spring Boot annotée avec l’annotation @SpringBootApplication :

package com.flower.samples;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.flower.docs.FlowerDocsClient;
import com.flower.docs.SecurityMode;

@SpringBootApplication
@FlowerDocsClient(security = SecurityMode.TOKEN)
public class SecuredGUIPlugin
{
	public static void main(String[] args)
	{
		SpringApplication.run(SecuredGUIPlugin.class, args);
	}
}

Ici l’annotation @FlowerDocsClient permet de configurer automatiquement :

  • le client Java permettant de consommer les web services exposés par FlowerDocs Core
  • la sécurisation des requêtes : un token est exigé pour consommer les @RestController exposés par l’application


Afin de configurer l’application, ajoutez ensuite le fichier application.properties dans le répertoire src/main/resources de votre projet :

Configuration

spring.application.name=secured-gui-plugin
server.port=2802
server.servlet.context-path=/secured
ws.url=http://localhost:8081/core/services


Les autres moyens de configuration offerts par le framework Spring Boot peuvent également être utilisés. Il est ainsi possible d’externaliser la configuration de l’application.

Développement du web service

Dans cet exemple, le web service permettra de compter le nombre de documents accessibles par l’utilisateur connecté. Le web service sera implémenté à l’aide de l’annotation Spring @RestController.

package com.flower.samples;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.flower.docs.domain.exception.FunctionalException;
import com.flower.docs.domain.exception.TechnicalException;
import com.flower.docs.domain.search.SearchRequest;
import com.flower.docs.service.api.document.DocumentService;

@RestController
public class FlowerRestController
{
	@Autowired
	private DocumentService documentService;

	@GetMapping("/count")
	public String count() throws TechnicalException, FunctionalException
	{
		return "documents: " + documentService.search(new SearchRequest()).getFound();
	}
}

Ici le service de gestion de documents documentService permet de déterminer le nombre total de documents.

Configuration du plugin

A l’aide de votre navigateur préféré, ouvrez la console d’administration FlowerDocs puis :

  • aller dans la section Configuration
  • ouvrir le menu Plugins
  • cliquer sur le bouton + pour démarrer la création d’un nouveau plugin
  • remplissez les informations demandées :
    • Chemin : /my-plugin/**
    • URL : http://localhost:2802/secured

Accès au plugin

Maintenant que votre plugin de la GUI a été configuré, vous pouvez accéder au endpoint /count à travers la GUI grâce à une l’URL : <gui>/plugins/<scope>/my-plugin/count.

Vous pouvez également tester le retour du service implémenté avec différents utilisateurs pour observer que le nombre de documents trouvés dépend de l’utilisateur connecté.


Etant donné que le plugin exige un token, l’accès direct via l’URL http://localhost:2802/secured/count est interdit.


Sans lien direct avec le module, cette section vous permet d’aller plus loin dans l’implémentation d’un client FlowerDocs.

Type de validation

L’annotation @FlowerDocsClient(security = SecurityMode.TOKEN) permet de sécuriser les requêtes reçues par l’application en exigeant un jeton utilisateur. Par défaut, un jeton reçu est validé en interrogeant FlowerDocs Core mais ce comportement peut être changé grâce à la propriété token.validation.type qui accepte les valeurs :

  • none : aucune validation du jeton au niveau du client. Le jeton fourni doit être lisible mais sa signature n’est pas validée. Ce mode doit donc être utilisé avec précaution par exemple dans le cas où toutes les requêtes reçues par le client FlowerDocs sont transmises à FlowerDocs Core. Dans ce cas, le token sera validé directement par FlowerDocs Core lors de la réception des requêtes.
  • local : la validation du jeton est réalisée par le client. Ce mode exige que le client dispose de la clé secrète (secret.key) utilisée pour vérifier les jetons.

Sécurité personnalisée

Dans ce module, une filtre HTTP intercepte chaque requête reçue et initialise le contexte utilisateur à partir du jeton fourni. Le mode de sécurité personnalisé (SecurityMode.CUSTOM) laisse la liberté aux développeurs d’implémenter leur propre mécanisme d’authentification.


La configuration de sécurité ci-dessous permet par exemple d’implémenter sa gestion de la sécurité en définissant un filtre HTTP permettant d’intercepter les requêtes entrantes.

package com.flower.samples;

import javax.servlet.Filter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.flower.docs.security.authentication.TokenAuthenticationFilter;

@Configuration
@Order(2)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    public void configure(HttpSecurity http) throws Exception
    {
        // @formatter:off
        http
            .addFilterBefore(customFilter(), BasicAuthenticationFilter.class)
            .authorizeRequests().anyRequest().authenticated();
        // @formatter:on
    }

    @Bean
    Filter customFilter() throws Exception
    {
        // Return custom HTTP filter
    }
}