Analyse et test du code
Utilisation correcte des types de données et des conversions de types
Traitement des zones de caractères
Utilisation du Pushdown de code dans ABAP SQL
Amélioration de la performance des tables internes
Implémentation des contrôles des autorisations
Conception d'un code orienté objet efficace
Définition et utilisation des classes d'exception
Ajout de documentation au code ABAP

Utilisation de l'instruction AUTHORITY-CHECK

Objective

After completing this lesson, you will be able to utilisez l'instruction AUTHORITY-CHECK.

Instruction AUTHORITY-CHECK

Pour effectuer un contrôle des autorisations explicitement, vous utilisez l'instruction AUTHORITY-CHECK. Vous y indiquez l'objet d'autorisation par rapport auquel vous voulez effectuer un contrôle, ainsi que les valeurs requises. L'AUTHORITY-CHECK effectue ici un contrôle par rapport à l'objet /DMO/TRVL et requiert que l'utilisateur dispose d'une autorisation contenant la valeur US pour la zone /DMO/CNTRY et 03 pour la zone ACTVT.

Comment vérifier le résultat du contrôle des autorisations

Contrairement aux contrôles d'autorisation filtrés fournis avec les contrôles d'accès CDS, l'instruction AUTHORITY-CHECK n'empêche pas les utilisateurs de voir les données pour lesquelles ils n'ont pas d'autorisation.

AUTHORITY-CHECK place un code retour dans la zone système sy-subrc. En contrôlant la valeur de sy-subrc immédiatement après le contrôle des autorisations, vous pouvez déterminer si le contrôle a réussi ou non.

Si le contrôle des autorisations a réussi, sy-subrc a la valeur 0. Les autres valeurs de sy-subrc signifient que le contrôle a échoué :

  • La valeur 4 signifie que l'utilisateur dispose d'une autorisation pour l'objet correspondant, mais pas des valeurs correctes.
  • La valeur 12 signifie que l'utilisateur n'a aucune autorisation pour l'objet correspondant.

Si le contrôle des autorisations échoue, vous devez vous assurer vous-même que l'utilisateur ne peut pas accéder aux données.

Dans l'exemple, le contrôle des autorisations requiert que l'utilisateur dispose d'une autorisation pour le pays "US". Comme ce n'est pas le cas pour notre utilisateur, sy-subrc est différent de zéro après le contrôle des autorisations. Dans ce cas, l'application affiche le texte Aucune autorisation.

Comment utiliser l'instruction AUTHORITY-CHECK

Regardez cette vidéo pour savoir comment utiliser l'instruction Authority-Check.

Implémenter contrôles des autorisations

Vous réalisez que votre code permet aux utilisateurs d'accéder à des données qu'ils ne sont pas autorisés à voir. Pour modifier cela, vous devez d'abord laisser votre code lire à partir des entités de vue CDS pour lesquelles des contrôles d'accès CDS sont définis. Vous implémentez ensuite un contrôle des autorisations explicite pour pouvoir distinguer les données que l'utilisateur n'est pas autorisé à voir et les données qui n'existent pas du tout.

Modèle :

  • /LRN/CL_S4D401_ITS_SEC_KEY (classe globale)

Solution :

  • /LRN/CL_S4D401_ACS_AUTH_CHECK (classe globale)

Tâche 1: Copier modèle (facultatif)

Copiez la classe de modèle /LRN/CL_S4D401_ITS_SEC_KEY. Si vous avez terminé l'exercice précédent, vous pouvez ignorer cette tâche et continuer à modifier votre classe ZCL_##_SOLUTION.

Étapes

  1. Copiez la classe /LRN/CL_S4D401_ITS_SEC_KEY dans une classe de votre propre package (nom proposé : ZCL_##_SOLUTION, ## correspondant à votre numéro de groupe).

    1. Dans l'explorateur de projets, cliquez avec le bouton droit de la souris sur la classe /LRN/CL_S4D401_ITS_SEC_KEY pour ouvrir le menu contextuel.

    2. Dans le menu contextuel, sélectionnez Dupliquer....

    3. Saisissez le nom de votre package dans la zone Package. Dans la zone Nom, saisissez ZCL_##_SOLUTION, où ## représente votre numéro de groupe.

    4. Cliquez sur Next.

    5. Confirmez l'ordre de transport et cliquez sur Terminer.

  2. Activez la copie.

    1. Appuyez sur Ctrl + F3 pour activer la classe.

Tâche 2: Analyse des autorisations

À partir de la table de base de données /LRN/CARRIER, recherchez le contrôle d'accès CDS qui protège les données du transporteur contre tout accès non autorisé. Analysez le contrôle d'accès CDS pour déterminer les autorisations dont un utilisateur a besoin pour afficher les données du transporteur.

Étapes

  1. Affichez la définition de la table de base de données /LRN/CARRIER.

    1. Appuyez sur Ctrl + Maj + A et saisissez /LRN/CARRIER dans la zone de recherche.

    2. Cliquez sur OK.

  2. Analysez le cas d'emploi pour cette table de base de données.

    1. Dans la définition de la table de base de données /LRN/CARRIER, cliquez avec le bouton droit de la souris sur /lrn/carrier et sélectionnez Accéder au cas d'emploi. Vous pouvez également cliquer sur /lrn/carrier et appuyer sur Ctrl + Maj + G.

    2. Dans la boîte de dialogue Sélectionner types d'objets, assurez-vous qu'au moins Définition de données de type d'objet est sélectionnée, puis cliquez sur Terminer.

    3. Dans la vue Rechercher sous l'éditeur, cliquez sur l'icône en forme d'entonnoir pour ouvrir la boîte de dialogue de filtre.

    4. Placez le curseur dans la zone Type(s) d'objet et appuyez sur Ctrl + Espace pour ouvrir une boîte de dialogue d'aide à la saisie.

    5. Dans la liste de propositions, sélectionnez DDLS/DF (Définition de données) et cliquez sur Appliquer.

  3. Analysez le cas d'emploi pour la vue CDS /LRN/I_CARRIER.

    1. Dans la vue Recherche, cliquez avec le bouton droit de la souris sur /LRN/I_CARRIER (Définition de données) et sélectionnez Accéder au cas d'emploi. Vous pouvez également cliquer sur /LRN/I_CARRIER (Définition de données) et appuyer sur Ctrl + Maj + G.

    2. Dans la boîte de dialogue Sélectionner types d'objets, assurez-vous qu'au moins le type d'objetContrôle d'accès est sélectionné, puis cliquez sur Terminer.

    3. Si la vue Recherche sous l'éditeur affiche trop d'occurrences, cliquez sur l'icône en forme d'entonnoir pour ouvrir la boîte de dialogue de filtre. Placez le curseur dans la zone Type(s) d'objet et appuyez sur Ctrl + Espace pour ouvrir une boîte de dialogue d'aide à la saisie. Dans la liste de propositions, sélectionnez DCLS/DL (Access Control), puis Apply.

  4. Ouvrez la définition du contrôle d'accès /LRN/I_CARRIER.

    1. Dans la vue Recherche, double-cliquez sur /LRN/I_CARRIER (Contrôle d'accès).

    2. Le nom de l'objet d'autorisation est le premier paramètre d'entrée pour la fonction pfcg_auth.

    3. Les autres paramètres d'entrée fournissent des valeurs pour les zones d'autorisation de l'objet d'autorisation.

  5. Ouvrez la définition de l'objet d'autorisation /LRN/CARR pour analyser la signification des valeurs d'activité.

    1. Maintenez la touche Ctrl enfoncée et cliquez sur /LRN/CARR dans l'appel de la fonction pfcg_auth.

    2. Les valeurs d'activité possibles sont répertoriées sous Activités autorisées.

Tâche 3: Utiliser le contrôle d'accès CDS

Dans la méthode constructeur de la classe locale LCL_CARRIER, remplacez la table de base de données /LRN/CARRIER par la vue CDS /LRN/I_CARRIER, qui est protégée par le contrôle d'accès CDS /LRN/I_CARRIER. Testez le code avec des ID de transporteurs différents comme entrée du constructeur.

Étapes

  1. Ouvrez l'implémentation de la méthode constructeur de la classe locale LCL_CARRIER.

    1. Revenez au code de votre classe globale ZCL_##_SOLUTION, où ## est votre numéro de groupe.

    2. Développez ZCL_##_SOLUTIONLCL_CARRIER dans la vue Structure et cliquez sur CONSTRUCTEUR.

  2. Ajustez l'instruction SELECT. Dans la clause FROM, remplacez la table de base de données /LRN/CARRIER par la vue CDS ci-dessus.

    1. Adaptez le code comme suit :

      ABAP
      123
      SELECT SINGLE * FROM /lrn/carrier FROM /LRN/I_Carrier
  3. Corrigez les erreurs de syntaxe. Remplacez les noms de zones de table par les noms d'éléments de vue CDS correspondants.

    1. Adaptez le code comme suit :

      ABAP
      1234567891011
      * SELECT SINGLE * FROM /lrn/carrier * FIELDS concat_with_space( carrier_id, name, 1 ), currency_code * WHERE carrier_id = @i_carrier_id * INTO ( @me->name, @me->currency_code ). SELECT SINGLE FROM /LRN/I_Carrier FIELDS concat_with_space( AirlineID, Name, 1 ), CurrencyCode WHERE AirlineID = @i_carrier_id INTO ( @me->name, @me->currency_code ).
  4. Activez et testez votre classe globale comme application de console.

    1. Appuyez sur Ctrl + F3.

    2. Appuyez sur F9.

  5. Dans votre classe globale, modifiez la valeur de la constante locale c_carrier_id en UA.

    1. Passez à l'onglet Classe globale.

    2. Adaptez le code comme suit :

      ABAP
      12
      * CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'LH'. CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'UA'.
  6. Activez et testez votre classe globale comme application de console.

    1. Appuyez sur Ctrl + F3.

    2. Appuyez sur F9.

Tâche 4: Implémentation d'une instruction AUTHORITY-CHECK

Dans la méthode du constructeur de la classe locale LCL_CARRIER, implémentez une instruction AUTHORITY-CHECK et déclenchez l'exception CX_ABAP_AUTH_CHECK_EXCEPTION si le transporteur aérien existe mais que l'utilisateur n'est pas autorisé pour ce transporteur.

Étapes

  1. Ouvrez l'implémentation de la méthode constructeur de la classe locale LCL_CARRIER.

    1. Assurez-vous que votre classe globale ZCL_##_SOLUTION est ouverte dans l'éditeur, où ## est votre numéro de groupe.

    2. Développez ZCL_##_SOLUTIONLCL_CARRIER dans la vue Structure et cliquez sur CONSTRUCTEUR.

  2. Adaptez l'instruction SELECT pour lire à nouveau à partir de la table de base de données /LRN/CARRIER.

    1. Adaptez le code comme suit :

      ABAP
      1234567891011
      * SELECT SINGLE * FROM /LRN/I_Carrier * FIELDS concat_with_space( AirlineID, Name, 1 ), CurrencyCode * WHERE AirlineID = @i_carrier_id * INTO ( @me->name, @me->currency_code ). SELECT SINGLE FROM /lrn/carrier FIELDS concat_with_space( carrier_id, name, 1 ), currency_code WHERE carrier_id = @i_carrier_id INTO ( @me->name, @me->currency_code ).
  3. Implémentez une instruction AUTHORITY-CHECK qui est exécutée si l'accès en lecture a réussi, c'est-à-dire si l'exception CX_ABAP_INVALID_VALUE n'a pas été déclenchée. Utilisez l'objet d'autorisation, les zones d'autorisation et les valeurs ci-dessus.

    1. Adaptez le code comme suit :

      ABAP
      123456789101112
      IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_abap_invalid_value. ENDIF. AUTHORITY-CHECK OBJECT '/LRN/CARR' ID '/LRN/CARR' FIELD i_carrier_id ID 'ACTVT' FIELD '03'. IF sy-subrc <> 0. ENDIF.
  4. Si l'utilisateur ne dispose pas de l'autorisation d'affichage pour l'ID de compagnie aérienne demandé, déclenchez l'exception CX_ABAP_AUTH_CHECK_EXCEPTION.

    1. Adaptez le code comme suit :

      ABAP
      12345678
      AUTHORITY-CHECK OBJECT '/LRN/CARR' ID '/LRN/CARR' FIELD i_carrier_id ID 'ACTVT' FIELD '03'. IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_abap_auth_check_exception. ENDIF.
  5. Utilisez un correctif rapide pour ajouter l'exception CX_ABAP_AUTH_CHECK_EXCEPTION à la clause RAISING de la définition de la méthode constructeur.

    1. Dans l'instruction RAISE EXCEPTION, cliquez sur cx_abap_auth_check_exception et appuyez sur Ctrl + 1. Vous pouvez également cliquer sur l'icône en forme d'ampoule à gauche de la ligne de code avec l'avertissement syntaxique.

    2. Dans la liste des solutions rapides suggérées, sélectionnez Ajouter déclaration de retrait.

    3. Par conséquent, la définition de la méthode du constructeur doit maintenant ressembler à ceci :

      ABAP
      123456
      METHODS constructor IMPORTING i_carrier_id TYPE /dmo/carrier_id RAISING cx_abap_invalid_value cx_abap_auth_check_exception.
  6. Dans votre classe globale, étendez la structure de contrôle TRY … ENDTRY avec un bloc CATCH pour la nouvelle exception CX_ABAP_AUTH_CHECK_EXCEPTION. Éditez un texte approprié pour indiquer que l'utilisateur n'est pas autorisé à afficher le transporteur.

    1. Adaptez le code comme suit :

      ABAP
      123456789
      TRY. DATA(carrier) = NEW lcl_carrier( i_carrier_id = c_carrier_id ). out->write( name = `Carrier Overview` data = carrier->get_output( ) ). CATCH cx_abap_invalid_value. out->write( |Carrier { c_carrier_id } does not exist| ). CATCH cx_abap_auth_check_exception. out->write( |No authorization to display carrier { c_carrier_id }| ). ENDTRY.
  7. De même, étendez la structure de contrôle TRY … ENDTRY dans la méthode class_setup de votre classe de test unitaire locale. Utilisez la même implémentation que dans le bloc Catch pour l'exception CX_ABAP_INVALID_VALUE.

    Remarque

    Il ne s'agit que d'une solution de contournement. Plus tard dans ce cours, vous apprendrez à gérer plusieurs exceptions dans le même bloc Catch.
    1. Adaptez le code comme suit :

      ABAP
      1234567
      TRY. the_carrier = NEW lcl_carrier( i_carrier_id = some_flight_data-carrier_id ). CATCH cx_abap_invalid_value. cl_abap_unit_assert=>fail( `Unable to instantiate lcl_carrier` ). CATCH cx_abap_auth_check_exception. cl_abap_unit_assert=>fail( `Unable to instantiate lcl_carrier` ). ENDTRY.
  8. Activez et testez votre classe globale comme application de console. Assurez-vous que votre code affiche le nouveau texte sur la console : aucune autorisation d'affichage du transporteur UA.

    1. Appuyez sur Ctrl + F3.

    2. Appuyez sur F9.

  9. Dans votre classe globale, remplacez la valeur de la constante locale c_carrier_id par LH.

    1. Passez à l'onglet Classe globale.

    2. Adaptez le code comme suit :

      ABAP
      12
      * CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'UA'. CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'LH'.
  10. Activez et testez votre classe globale comme application de console. Assurez-vous que le code affiche les détails du transporteur et du vol comme précédemment.

    1. Appuyez sur Ctrl + F3.

    2. Appuyez sur F9.