I am trying to implement authorization in a Delphi XE DataSnap application. I broke this down into a very simple example, but still do not see the effects of the TRoleAuth attribute for a method or class.
Here is a simple DSServerMethods class that includes the generated sample methods. The class has been decorated with the guest and anyone authorized roles, and the unwelcome denied role. The ReverseString method has been decorated with the readonly denied role:
type
[TRoleAuth('guest,anyone','unwelcome')]
TMyDSServerMethods = class(TDSServerModule)
DataSetProvider1: TDataSetProvider;
...
public
{ Public declarations }
function EchoString(Value: string): string;
[TRoleAuth('','readonly')]
function ReverseString(Value: string): string;
...
end;
I am assigning roles on the OnUserAuthenticate method. For example, I have a user for whom I am assigning the readonly role from OnUserAuthenticate, a role which I believe should deny that user permission to execute the ReverseString function.
From what I understand, my code should compare the user's roles against the EventObject.AuthorizedRoles and EventObject.DeniedRoles TStrings from the OnUserAuthorize method of the TDSAuthenticationManager, and set the valid formal parameter of this method accordingly.
Here is a simple OnUserAuthorize method I am using for tesing. When I step into it using the debugger in response to a user with the readonly role attempting to invoke ReverseString, EventObject.AuthorizedRoles and EventObject.DeniedRoles are both nil, and EventObject.Roles contains the readonly role.
procedure TServerContainer1.DSAuthenticationManager1UserAuthorize(
Sender: TObject; EventObject: TDSAuthorizeEventObject;
var valid: Boolean);
begin
outputdebugstring(PChar(Eventobject.UserName));
if EventObject.UserRoles <> nil then
outputdebugstring(PChar(eventobject.UserRoles.Text));
if EventObject.AuthorizedRoles <> nil then
outputdebugstring(PChar(eventobject.AuthorizedRoles.Text));
if EventObject.DeniedRoles <> nil then
outputdebugstring(PChar(eventobject.DeniedRoles.Text));
valid := True;
end;
Am I missing the point, or is there a property that I need to set somewhere to enable the TRoleAuth attribute to function?
= = = = = = = = = = Edit: Mat DeLong provided the answer. The DSAuth unit (where the TRoleAuth custom attribute class is declared) was missing from the interface section of the unit in which the DSServerModule descendant was defined.