Zum Inhalt springen

Service Passwort zurücksetzen auf dem Fiori Launchpad

Es gibt einen schönen Hinweis 2565111 der das Problem betrifft, dass keine Passwort zurücksetzen Funktion auf dem Fiori Launchpad angeboten wird. Klingt sehr vielversprechend weil genau die Frage nämlich immer öfter kam. Dachte ich… im Hinweis steht nämlich drin:
“Kannst du gerne selbst umsetzen wenn du es brauchst” 🙂

Als Erstes die einfachen Dinge nämlich ein oData-Service für die Abwicklung im Backend, bzw. das wirkliche Zurücksetzen und neu generieren des Passwortes.

Der Entitätstyp des oData-Services ist sehr simpel.

Entitätstyp oData-Service

Über die SAPUI5-Anwendung sollen später E-Mailadresse und Benutzernamen zum Abgleich mitgegeben werden.

Die Implementierung der create_entityset sieht dann folgendermaßen aus:

    DATA lv_zeichen TYPE char80.
    DATA ls_data TYPE zfiori_rpw_s.
    DATA lt_mail_body TYPE soli_tab.
    DATA lv_password TYPE char20.
    DATA lt_return   TYPE TABLE OF bapiret2.
    DATA ls_address TYPE bapiaddr3.

    io_data_provider->read_entry_data(
      IMPORTING
        es_data = ls_data
    ).

"Sicherheitsprüfung - Mailadresse muss im Benutzerstamm gepflegt sein
    CALL FUNCTION 'BAPI_USER_GET_DETAIL'
      EXPORTING
        username = ls_data-uname
      IMPORTING
        address  = ls_address
      TABLES
        return   = lt_return.

    IF to_lower( ls_data-mail ) NE to_lower( ls_address-e_mail ). "Mailadresse falsch!!!
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = |Mailadressen Benutzerstammsatz und Request stimmen nicht überein|.
    ENDIF.

    "Neues Passwort generieren
    CONCATENATE
      'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      'abcdefghijklmnopqrstuvwxyz'
      '123456789@$%&/\()=+-#~[]{}'
      INTO lv_zeichen.

    CALL FUNCTION 'RSEC_GENERATE_PASSWORD'
      EXPORTING
        alphabet             = lv_zeichen
        alphabet_length      = 0
        force_init           = ' '
        output_length        = 20
        downwards_compatible = ' '
      IMPORTING
        output               = lv_password
      EXCEPTIONS
        some_error           = 1.

    "Ändere User PW
    CALL FUNCTION 'BAPI_USER_CHANGE'
      EXPORTING
        username  = ls_data-uname
        password  = CONV bapipwd( lv_password )
        passwordx = 'X'
      TABLES
        return    = lt_return.

    "Prüfe, ob User Change fehlerfrei erfolgt ist
    IF line_exists( lt_return[ type = 'E' ] ) OR line_exists( lt_return[ type = 'A' ] ).
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = |Fehler bei BAPI_USER_CHANGE|.
    ENDIF.


    "Entsperre Benutzer
    CLEAR lt_return.
    CALL FUNCTION 'BAPI_USER_UNLOCK'
      EXPORTING
        username = ls_data-uname
      TABLES
        return   = lt_return.
    "Prüfe, ob User Unlock fehlerfrei erfolgt ist
    IF line_exists( lt_return[ type = 'E' ] ) OR line_exists( lt_return[ type = 'A' ] ).
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = |Fehler bei BAPI_USER_UNLOCK|.
    ENDIF.

    "Mailversand
    DATA(lo_bcs_message) = NEW cl_bcs_message( ).
    lo_bcs_message->add_recipient(
      EXPORTING
        iv_address      = CONV #( ls_data-mail )
    ).
    lo_bcs_message->set_send_immediately( iv_immediately = abap_true ). "Soll sofort gesendet werden

    "Senderadresse aus Stammsatz des Servicebenutzers
    CALL FUNCTION 'BAPI_USER_GET_DETAIL'
      EXPORTING
        username = sy-uname
      IMPORTING
        address  = ls_address
      TABLES
        return   = lt_return.
    lo_bcs_message->set_sender(
      EXPORTING
        iv_address      = COND #( WHEN ls_address-e_mail IS NOT INITIAL THEN to_lower( ls_address-e_mail ) ELSE 'no-reply.fiori@dummy.de' )
    ).
    lo_bcs_message->set_subject( |Zurücksetzung des Kennworts| ).

    lt_mail_body = VALUE #(
         ( line = |<p>Guten Tag,| )
         ( line = |<p>Sie haben ihr Kennwort vergessen?<br>| )

         ( line = |<p>Ihr neues Kennwort lautet: { lv_password }</p>| )
         ( line = |<p>Mit freundlichen Grüßen<br></p>| )
    ).


    DATA(lt_mail_body_solix) = cl_bcs_convert=>soli_to_solix( it_soli = lt_mail_body  ).
    DATA(l_content_bin) = cl_bcs_convert=>solix_to_xstring( lt_mail_body_solix ).

    lo_bcs_message->set_main_doc(
      EXPORTING
        iv_contents_bin = l_content_bin
        iv_doctype      = 'htm'
    ).

    TRY.
        lo_bcs_message->send( ).
      CATCH cx_bcs_send.    "
    ENDTRY.

Entscheidend ist hier der Abgleich der Mailadresse mit dem Benutzerstamm aus Sicherheitsgründen, die Generierung eines neuen Passwortes und das Hinterlegen ebendieses im Benutzerstamm. Danach wird es noch per Mail versendet.

Passend wird natürlich noch eine SAPUI5-Anwendung für das Frontend erstellt. Der entscheidende Teil ist hier einfach nur der Aufruf des oData-Service mit den entsprechenden Daten und eine Ausgabe der Meldung.

sap.ui.define(["sap/ui/core/mvc/Controller", "sap/m/MessageBox", "sap/m/MessageToast"], function (e, r, t) {
    "use strict"; return e.extend("zflprpw.controller.Main", {
        resetPassword: function () {

            var e = this.getView().byId("uname_input").getValue(); var n = this.ge +
                tView().byId("mail_input").getValue(); if (e === "" || n === "") { 
                    r.error("Bitte Benutzername und E-Mail eingeben"); return } 
                    var i = /^\w+[\w-+\.]*\@\w+([-\.]\w+)*\.[a-zA-Z]{2,}$/; 
                    if (!n.match(i)) { r.error("Bitte eine korrekte Mailadresse eingeben"); return } 
                    var a = {}; a.U + name=e; a.Mail = n; var s = this.getOwnerComponent().getModel(); s.create("/UserdataSet", a, 
                    { method: "POST", success: function (e) { t.show("E-Mail wurde gesendet") }, 
                    error: function (e) { r.error("Fehler beim Zurücksetzen des Kennworts") } })
                }, back: function () {
            window.history + .go(-1)
        }
    })
});

Letztendlich muss die entsprechende SAPUI5-Anwendung im SICF-Service für das Fiori Launchpad hinterlegt werden.
Hier ist auch entscheidend, dass für den Aufruf des “Passwort zurücksetzen”-Service ein entsprechender Systembenutzer im Service hinterlegt ist, damit dieser ohne Anmeldung aufgerufen werden kann.
Dabei wird kein CSRF-Token gesetzt. D.h. im Service sollte auch der Paramater ~CHECK_CSRF_TOKEN auf 0 gesetzt sein. (Gui-Konfiguration im SICF-Service)

Sollte man mehrere Mandanten im Frontend haben kann man auch einfach über externe Aliasse arbeiten.

Facebooktwitterpinterestlinkedinmail
Published inFiori LaunchpadoDataSAP EntwicklungSAP UI

Ein Kommentar

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert