Roles
Roles are an extension of the session support in RemObjects SDK.
Sessions are a great way to store information per user/client, and with RemObjects SDK's Authentication and Login system, they already provide automated means to allow or restrict access to a service based on whether a user has authenticated herself, or not. However, the existing authentication system via the RequireSessions properties only enforced the requirement to log in to access certain services, but dcou;d not manage more granular access restrictions.
Roles expand on this, to allow more fine-grained control over what services or individual methods a given user can access, with very little extra code. A "role" is basically an attribute that each authenticated user (in other words, each active Session) can either have, or not have. If a specific role is present for the session, the session (or client, or user) can access all services or methods that have restricted to this role. If a session is does not have a given role, access to any such methods will be rejected.
Each role is represented by a unique name.
Defining Roles and Restrictions in Service Builder
Service Builder has been extended to provide a new Roles
field on each service and each service method. The Roles field is plain text, and can accept any comma-separated list of names, which each name representing a role that is needed to access the object.
Roles listed on service level will apply to calls to all methods of the service, while roles listed on an individual method will only be enforced for the method in questions. If more than one roles is set on service or method, a client will need to hold all
the listed roles i order to call the method. You can also an exclamation point ("!") character before a role name, to specify that a method or service is only accessible to sessions that do not
own that specific role.
If no roles are listed on neither service nor method, access will be granted to all clients (although a session will of course still be required, if RequireSession is set to true). This is essentially the default behavior of current RO servers, without roles.
Since roles are stored on a session basis, by very definition any service or method that is set to require (or reject) one or more roles will automatically require a session to be present, as well. As such, defining roles for a service implicitly sets RequireSession to true.
Enforcing Sessions in Code
Enforcement of roles defined in the schema is entirely handled by the RemObjects SDK framework, so no extra code is needed to enforce these restrictions. The frameworkwill also fire the new (On)ValidateRoles event, to allow you custom control over accepting or rejecting specific roles.
Of course your code can still access and check the presence of roles, at any time. if you want to implement restrictions beyond the method call level. For example, you might might define a method that is freely accessible, but will perform slightly different operations based on the roles the current client has; maybe an admin user will have access to more parts of your database than a regular user.
You can check the roles present for the current session by accessing the Roles
property on the Session object. It ill return an array of strings, identifying each role.
Setting Roles
Of course enforcing roles is of little use, unless sessions actually get assigned a certain set of roles, to begin with. This is usually done in your Login() handler (see Authentication and Login). Just as your login handler will already validate username and password and create (and possibly populate) the user's session, it should determine and set the list of roles that apply to this session. This can be done by reading roles from your user database, or by applying hardcoded rules.
Because roles are merely strings, names representing a specific concept
that you want to grant or deny access to, your application has full flexibility in defining, setting, and checking roles as you see fit.
Once the set of Roles for the session has beet determined, you can set it by assigning to the new Roles property on the Session object.
Usage
- Delphi:
Session.Roles := ['Role1','Role2'];