Friday, December 10, 2010

RLS in Displaymethoden auf Berichten (AX 4.0)

X++ Select-Statements sind per Standard so eingestellt, dass sie die Sicherheit auf Datensatzebene (RLS) ignorieren. Über die Eigenschaft recordLevelSecurity kann aber dieses Feature ein- oder ausgeschaltet werden. Die Eigenschaft kann aber auch dazu verwendet werden, den aktuellen Status des Features zu ermitteln.

Select-Anweisungen innerhalb von Display-Methoden verhalten sich jedoch ein wenig anders. Und zwar ist für jede Select-Anweisung die Sicherheit auf Datensatzebene aktiviert, welche aus dem Aufrufstapel einer Display-Methode stammt. Allerdings ist über die Abfrage der Eigenschaft recordLevelSecurity nicht ermittelbar ob das Feature nun aktiviert ist oder nicht. Ein Aufruf von recordLevelSecurity gibt in einer solchen Situation stets false zurück was vermeintlicherweise zu der Annahme führen könnte, dass die Sicherheit auf Datensatzebene nicht aktiv ist obwohl sie das ist.

display showEmplName()
{
    EmplTable emplTable;
    EmplName name;
    ;
    info(strfmt("%1", emplTable.recordLevelSecurity())); // this will return false, but actually it's true!

    select firstonly Name from emplTable 
        where emplTable.EmplId == reportTable.emplId; // the record will use RLS (yeah, it's magic)

name = emplTable.Name;

    return name;
}

Auch so ist die Sicherheit auf Datensatzebene aktiv - ohne dass eine explizite Änderung der Eigschaft recordLevelSecurity erfolgt:
display showEmplName()
{
    EmplName name;
    ;
    name = EmplTable::find(reportTable.EmplId); // the select inside the find method will use RLS even you haven't activate this

    return name;
}


Will man nun sicherstellen, dass die Sicherheit auf Datensatzebene wirklich deaktiviert ist, muss man explizit die Eigenschaft nocheinmal setzen.

display showEmplName()
{
    EmplTable emplTable;
    EmplName name;
    ;
    emplTable.recordLevelSecurity(false); // this will really free from RLS   

    select firstonly Name from emplTable 
        where emplTable.EmplId == reportTable.emplId;

    name = emplTable.Name;

    return name;
}


Dieses Problem betrifft AX 4.0. In AX 2009 tritt das Phänomen nicht mehr auf; die Sicherheit auf Datensatzebene bleibt deaktiviert bis sie explizit aktiviert wird.

No comments:

Post a Comment