Documentation Index

Fetch the complete documentation index at: https://docs.document360.com/llms.txt

Use this file to discover all available pages before exploring further.

Clause de non-responsabilité: Cet article a été généré par traduction automatique.

Implémentez JWT dans votre application

Prev Next

Après avoir terminé la configuration JWT dans Document360, votre application a besoin d’une route backend pour gérer la dernière étape du flux de connexion.

Voici l’itinéraire :

  • Valide que l’utilisateur est déjà authentifié dans votre application
  • Envoie une requête sécurisée à l’URL de génération de code de Document360
  • Récupère un code d’autorisation à usage unique
  • Redirige l’utilisateur vers le site de la base de connaissances avec ce code

NOTE

Les lecteurs n’ont pas besoin d’un compte Document360 distinct. L’authentification est entièrement gérée via votre application. Un compte dans votre application suffit pour qu’un lecteur puisse accéder à la base de connaissances.


Exemples de code

Les exemples ci-dessous montrent comment implémenter la route d’authentification backend en C#, Node.js et Java.

C#

/// <summary>
/// Example endpoint to authenticate a user and retrieve a token from the identity server,
/// and redirect the user to the Knowledge Base (KB) using the token code.
/// </summary>
/// <param name="clientId">Client ID issued for your application</param>
/// <param name="clientSecret">Client secret associated with the client ID</param>
/// <returns>Redirects to the KB with the issued code</returns>
[HttpGet]
[Route("authenticate")]
public async Task<IActionResult> AuthenticateAsync(string clientId, string clientSecret)
{
    if (!HttpContext.User.Identity.IsAuthenticated)
    {
        // user is not authenticated, redirect to an error or login page
        return Unauthorized(new { message = "User not authenticated" });
    }

    // Ensure you have the correct client ID and secret from your Document360 JWT configuration
    var authToken = Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}");

    // Create an HttpClient instance
    using var httpClient = new HttpClient();

    // Set the Authorization header with Basic authentication
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));

    // Prepare the payload with user information
    var payload = new
    {
        username = User.Identity.Name,
        firstName = "FirstName", // Replace or customize as needed
        lastName = "LastName",
        emailId = "user@example.com", // Replace with actual user email
        readerGroupIds = new List<string> { "group1", "group2" }, // Replace with actual reader group IDs if needed (Optional)
        tokenValidity = 3600 // Token validity in seconds (Optional, default is 5 minutes)
    };

    var payloadContent = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");

    // Identity server token endpoint - replace with your actual URL
    string identityServerUrl = "codeGeneration endpoint, you can find that in JWT config portal";
    // KB login URL to redirect after successful token issuance
    string kbLoginUrl = "https://{your subdomain}.document360.io";

    var response = await httpClient.PostAsync(identityServerUrl, payloadContent);

    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();
        var tokenJson = JObject.Parse(content);
        // Extract the code from the response
        var tokenCode = (string)tokenJson.SelectToken("code");

        // Construct the KB login URL with code query parameter
        string finalRedirectUrl = $"{kbLoginUrl}?code={tokenCode}";

        return Redirect(finalRedirectUrl);
    }
    else
    {
        // Handle error response from the identity server
        var error = await response.Content.ReadAsStringAsync();
        return StatusCode((int)response.StatusCode, new { error = "Token request failed", details = error });
    }
}

Node.js

const express = require('express');
const https = require('https');
const axios = require('axios');
const app = express();

app.use(express.json());

const clientId = 'your-client-id';
const clientSecret = 'your-client-secret';
const codeGenerationUrl = 'https://identity.document360.net/jwt/generateCode';
const kbLoginUrl = 'https://your-subdomain.document360.net/jwt/authorize';

app.get('/authenticate', async (req, res) => {
  try {
    const isAuthenticated = true; // Replace with your actual auth logic

    if (!isAuthenticated) {
      return res.status(401).json({ message: 'User not authenticated' });
    }

    const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

    const payload = {
      username: 'john.doe',
      firstName: 'John',
      lastName: 'Doe',
      emailId: 'john.doe@example.com',
      readerGroupIds: ['group1', 'group2'],
      tokenValidity: 3600
    };

    const response = await axios.post(
      codeGenerationUrl,
      payload,
      {
        headers: {
          'Authorization': `Basic ${authHeader}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        httpsAgent: new https.Agent({ maxVersion: 'TLSv1.2' })
      }
    );

    const tokenCode = response.data?.code;

    if (!tokenCode) {
      return res.status(500).json({ message: 'No code received from Document360' });
    }

    console.log("Redirecting to:", `${kbLoginUrl}?code=${tokenCode}`);
    return res.redirect(`${kbLoginUrl}?code=${tokenCode}`);

  } catch (error) {
    return res.status(500).json({
      message: 'JWT SSO failed',
      details: error.response?.data || error.message
    });
  }
});

Java

import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.nio.charset.StandardCharsets;
import java.util.*;

@RestController
public class JwtSsoController {

    private final String clientId = "your-client-id";
    private final String clientSecret = "your-client-secret";
    private final String codeGenerationUrl = "https://identity.document360.io/api/jwt/generate-code";
    private final String kbLoginUrl = "https://your-subdomain.document360.io/jwt/authorize";

    @GetMapping("/authenticate")
    public ResponseEntity<?> authenticate() {
        // Example: Check if user is authenticated in your system
        boolean isAuthenticated = true; // Replace with actual logic
        if (!isAuthenticated) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("User not authenticated");
        }

        // Create Basic Auth header
        String auth = clientId + ":" + clientSecret;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Basic " + encodedAuth);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        // Construct payload
        Map<String, Object> payload = new HashMap<>();
        payload.put("username", "john.doe");
        payload.put("firstName", "John");
        payload.put("lastName", "Doe");
        payload.put("emailId", "john.doe@example.com");
        payload.put("readerGroupIds", Arrays.asList("group1", "group2"));
        payload.put("tokenValidity", 3600);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(payload, headers);
        RestTemplate restTemplate = new RestTemplate();

        try {
            ResponseEntity<Map> response = restTemplate.postForEntity(codeGenerationUrl, request, Map.class);

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                String tokenCode = (String) response.getBody().get("code");

                if (tokenCode == null || tokenCode.isEmpty()) {
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .body("No code returned from Document360");
                }

                // Redirect to the KB site with code
                String redirectUrl = UriComponentsBuilder.fromHttpUrl(kbLoginUrl)
                        .queryParam("code", tokenCode)
                        .toUriString();

                HttpHeaders redirectHeaders = new HttpHeaders();
                redirectHeaders.setLocation(java.net.URI.create(redirectUrl));
                return new ResponseEntity<>(redirectHeaders, HttpStatus.FOUND);

            } else {
                return ResponseEntity.status(HttpStatus.BAD_GATEWAY)
                        .body("Failed to get code from Document360: " + response.getStatusCode());
            }

        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("JWT SSO error: " + ex.getMessage());
        }
    }
}

Liste de contrôle des développeurs

Avant de lancer la mise en ligne, vérifiez ce qui suit :

  • Enregistrez l’URL de connexion, l’URL de rappel et l’URL de génération de code dans vos paramètres JWT.
  • Stockez le secret client de manière sécurisée. Il n’est exposé qu’une seule fois au moment de la création.
  • Implémentez la logique backend pour appeler l’URL de génération de code en utilisant HTTP Basic Auth.
  • Signez le JWT dans votre backend en utilisant votre secret client. Ne jamais exposer la logique de signes côté client.
  • Imposez HTTPS à tous les points de terminaison impliqués dans le flux d’authentification.
  • Tester le comportement de la session, l’expiration du token et le renouvellement automatique de la session avant la mise en ligne.
  • Surveillez les journaux backend pour détecter les erreurs 401, qui indiquent généralement des codes d’autorisation expirés ou des incompatibilités de jetons.

Redirection vers une page spécifique après la connexion

Par défaut, après la connexion, les lecteurs sont redirigés vers la page d’accueil de votre base de connaissances.

  • Si votre page d’accueil n’est pas publiée, les lecteurs sont redirigés vers la /docs page.
  • Pour rediriger les lecteurs vers une autre page de votre base de connaissances, configurez la redirection en suivant le schéma d’URL suivant.

Motif URL

https://<Knowledge base URL>/jwt/authorize?code=<code>&redirectUrl=<redirect path>

Paramètres

  • <Knowledge base URL>: l’URL principale de votre site de base de connaissances.
  • <code>: le code généré par le point de terminaison de génération de code Document360.
  • <redirect path>: l’URL où vous souhaitez que les lecteurs atterrissent après la connexion.

Exemple

https://example.document360.io/jwt/authorize?code=FOTaS_SW6dLGytQXvrG_rRFGhyPvrDDrgxJAZzYvJcY&redirectUrl=/docs/5-basic-things-to-get-started

NOTE

Document360 enverra l’URL de Redirection vers redirectPath le point de terminaison de connexion. Lorsque le point de terminaison de connexion redirige vers la base de connaissances avec le code d’authentification, il doit retourner l’URL de redirection comme redirectUrl paramètre.

Dans KB Site 2.0, la redirection est gérée via des cookies au lieu du redirectUrl paramètre. Si votre implémentation JWT est basée sur la redirection de chaînes de requête utilisant ce redirectUrl paramètre, l’approche basée sur les cookies ne prend pas en charge ce paramètre. Vous devrez peut-être mettre à jour votre implémentation ou contacter le support pour plus de précisions.