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.
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
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).
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.
Dans le menu contextuel, sélectionnez Dupliquer....
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.
Cliquez sur Next.
Confirmez l'ordre de transport et cliquez sur Terminer.
Activez la copie.
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
Affichez la définition de la table de base de données /LRN/CARRIER.
Appuyez sur Ctrl + Maj + A et saisissez /LRN/CARRIER dans la zone de recherche.
Cliquez sur OK.
Analysez le cas d'emploi pour cette table de base de données.
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.
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.
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.
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 DDLS/DF (Définition de données) et cliquez sur Appliquer.
Analysez le cas d'emploi pour la vue CDS /LRN/I_CARRIER.
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.
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.
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.
Ouvrez la définition du contrôle d'accès /LRN/I_CARRIER.
Dans la vue Recherche, double-cliquez sur /LRN/I_CARRIER (Contrôle d'accès).
Le nom de l'objet d'autorisation est le premier paramètre d'entrée pour la fonction pfcg_auth.
Les autres paramètres d'entrée fournissent des valeurs pour les zones d'autorisation de l'objet d'autorisation.
Ouvrez la définition de l'objet d'autorisation /LRN/CARR pour analyser la signification des valeurs d'activité.
Maintenez la touche Ctrl enfoncée et cliquez sur /LRN/CARR dans l'appel de la fonction pfcg_auth.
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
Ouvrez l'implémentation de la méthode constructeur de la classe locale LCL_CARRIER.
Revenez au code de votre classe globale ZCL_##_SOLUTION, où ## est votre numéro de groupe.
Développez ZCL_##_SOLUTION→LCL_CARRIER dans la vue Structure et cliquez sur CONSTRUCTEUR.
Ajustez l'instruction SELECT. Dans la clause FROM, remplacez la table de base de données /LRN/CARRIER par la vue CDS ci-dessus.
Adaptez le code comme suit :
123
SELECT SINGLE
FROM /LRN/I_Carrier
Corrigez les erreurs de syntaxe. Remplacez les noms de zones de table par les noms d'éléments de vue CDS correspondants.
Adaptez le code comme suit :
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 ).
Activez et testez votre classe globale comme application de console.
Appuyez sur Ctrl + F3.
Appuyez sur F9.
Dans votre classe globale, modifiez la valeur de la constante locale c_carrier_id en UA.
Passez à l'onglet Classe globale.
Adaptez le code comme suit :
12
CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'UA'.
Activez et testez votre classe globale comme application de console.
Appuyez sur Ctrl + F3.
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
Ouvrez l'implémentation de la méthode constructeur de la classe locale LCL_CARRIER.
Assurez-vous que votre classe globale ZCL_##_SOLUTION est ouverte dans l'éditeur, où ## est votre numéro de groupe.
Développez ZCL_##_SOLUTION→LCL_CARRIER dans la vue Structure et cliquez sur CONSTRUCTEUR.
Adaptez l'instruction SELECT pour lire à nouveau à partir de la table de base de données /LRN/CARRIER.
Adaptez le code comme suit :
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 ).
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.
Adaptez le code comme suit :
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.
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.
Adaptez le code comme suit :
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.
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.
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.
Dans la liste des solutions rapides suggérées, sélectionnez Ajouter déclaration de retrait.
Par conséquent, la définition de la méthode du constructeur doit maintenant ressembler à ceci :
123456
METHODS constructor
IMPORTING
i_carrier_id TYPE /dmo/carrier_id
RAISING
cx_abap_invalid_value
cx_abap_auth_check_exception.
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.
Adaptez le code comme suit :
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.
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.
Adaptez le code comme suit :
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.
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.
Appuyez sur Ctrl + F3.
Appuyez sur F9.
Dans votre classe globale, remplacez la valeur de la constante locale c_carrier_id par LH.
Passez à l'onglet Classe globale.
Adaptez le code comme suit :
12
CONSTANTS c_carrier_id TYPE /dmo/carrier_id VALUE 'LH'.
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.
Appuyez sur Ctrl + F3.
Appuyez sur F9.