|
This topic describes more advanced aspects of writing role mapping and authorization policies. The following topics are covered here:
All policies, simple or complex, follow the same standard syntax:
GRANT|DENY|DELEGATE (privilege|role, resource, subject, delegator) IF constraint;
You can extend the policy syntax to encompass very complex situations by grouping policies and adding constraints.
For more information, see the following topics:
You are not limited to one role, privilege, resource or subject per policy. You may specify sets by enclosing them in brackets [ ] and separating the individual items with commas. For example:
GRANT(any, //app/policy/MyApp, [//user/ORG/USER21/, //user/ORG/USER22/]);
A constraint is a statement that limits when or under what circumstances permission is granted, denied or delegated. All constraints start with the keyword IF. Simple constraints usually contain two values separated by an operator. The following example shows an authorization policy with a simple constraint:
GRANT(//priv/any, //app/policy/MyApp, //sgrp/ORG/allusers/) IF purchaseAmount < 2000;
In this policy, any user of the resource MyApp who is in the ORG directory is allowed to spend any amount less than $2000.
Constraints are very useful because they allow your application to have different responses based on dynamic application, data, business environment, or real-time conditions. For example, you might use a constraint to grant a user access to a resource only during certain hours of the day.
When checking if a value is within an attribute, the constraint must be written as: <value> in [attribute]. For example if checking to see that the requested resource name is in a list of userentitlements, you would say:
To limit the user in the previous example to having privileges only in December and January, you would add the constraint:
IF month IN [december, january]
To limit the user to accessing the application from a computer with a particular static IP address, you would add the constraint:
IF clientip = 207.168.100.1
Several types of attributes are provided that are automatically computed for you (see Declarations).
Once a grant result is determined at runtime by the ASI Authorizer (also called the Authorization and Role Mapping Engine (ARME)) for a particular resource, the rest of the applicable GRANT policies, which may contain additional constraints, are ignored. Therefore, if your business logic requires the evaluation of multiple constraints, you must combine them into a complex constraint using an AND operator to achieve the desired result. For example, given the following two policies:
GRANT(//priv/any, //app/policy/MyApp, //sgrp/ORG/allusers/) IF purchaseAmount < 2000;GRANT(//priv/any, //app/policy/MyApp, //sgrp/ORG/allusers/) IF month IN [december, january];
The conditions under which allusers would be granted access would be determined by which policy the ASI Authorizer evaluates first. If the goal is to grant access only if both constraints are true, you must combine these policies into one policy using the AND operator as follows:
GRANT(//priv/any, //app/policy/MyApp, //sgrp/ORG/allusers/) IF purchaseAmount < 2000 AND month IN [december, january];For more information on combining multiple constraints into one policy, see Boolean Operators.
The following topics provide more information on constraints:
Constraints support the comparison operators listed in Table 4-1.
There are two comparison operators, LIKE and NOTLIKE, that are used to perform regular expression matching on attribute values or string literals. This is typically used for pattern matching on resource names. For example, the following policy provides the GET access privilege to all JPGs in a web application (//app/policy/MyWebApp).
GRANT(//priv/GET, //app/policy/MyWebApp, //role/webusers)
IF sys_obj LIKE '.*\.JPG';
The regular expression syntax follows certain policies.
Any character that is not a special character matches itself. Special characters are:
+ * ? . [ ] ^ $
A backslash (\) followed by any special character matches the literal character. For example:
"\*u"
A period (.) matches any character. For example:
".ush"
matches any string containing the set of characters, such as "Lush" or "Mush".
A set of brackets ([]) indicates a one-character regular expression matching any of the characters in the set. For example:
"[abc]"
matches either "a", "b", or "c".
A dash (-) indicates a range of characters. For example:
"[0-9]"
A caret (^) at the beginning of a set indicates that any character outside of the set matches. For example:
"[^abc]"
matches any character other than "a", "b", or "c" not including an empty string.
The following policies are used to build a multi-character regular expressions.
Parentheses (( )) indicate that two regular expressions are combined into one. For example:
(ma)+
matches one or more instances of "mad's".
The OR character ( | ) indicates a choice of two regular expressions. For example:
bell(y|ies)
matches either "belly" or "bellies".
A single-character regular expression followed by an asterisk (*) matches zero or more occurrences of the regular expression. For example:
"[0-9]*"
matches any sequence of digits or an empty string.
A single-character regular expression followed by an plus sign (+) matches one or more occurrences of the regular expression. For example:
"[0-9]+"
matches any sequence of digits but not an empty string.
A single-character regular expression followed by a question mark (?) matches either zero or one occurrence of the regular expression. For example:
"[0-9]?"
matches any single digit or an empty string.
A concatenation of regular expression matches the corresponding concatenation of strings. For example:
[A-Z][a-z]*
matches any word starting with a capital letter.
When you use a regular expression that contains backslashes, the constraint evaluator and the regular expression operation both assume that any backslashes are used to escape the character that follows. To specify a regular expression that exactly matches "a\a", create the regular expression using four backslashes as follows:
LIKE "a\\\\a"
Likewise, with the period character "." you need to include two backslashes in the expression:
LIKE "\\."
There are two operators, IN and NOTIN, used to test the memberships of sets in your constraint. A constraint set is a definition of a set of items, notated by one or more values separated by commas, enclosed in square brackets, and prefaced with either the keyword IN or NOTIN. For example, rather than writing:
. . . IF NextMonth = january or
. . . NextMonth = february or
. . . NextMonth = march;
. . . IF NextMonth IN [january, february, march] ;
The keyword IN means in this set of values, and NOTIN means not in this set of values. Neither keyword is case sensitive.
You can also specify a range of values in a set of constraints. For example, the statement:
IF age NOTIN[1..100]
says if the age value is not between 1 and 100 (inclusive), then the statement is true. The keywords IN and NOTIN work well with attributes based on enumerated types and constant sets.
You can test for specific text strings in your constraints by using the keywords LIKE and NOTLIKE. For example, assume you have a user attribute called GroupID. This attribute contains a string of data indicating information about the group the user belongs to:
GroupID = "59NY20BREQ";
To check for and exclude users in the New York office, you can test the GroupID attribute for NY as follows:
(Grant policy) IF GroupID NOTLIKE "*NY*";where * represents any number of characters. Similarly, if you want to ensure that the user was in New York, you can add this constraint:
(Grant policy) IF GroupID LIKE "*NY*";
Similar to IN and NOTIN, LIKE and NOTLIKE are not case sensitive.
To compare a string to a policy element in the constraint, replace the first characters of the element with a wildcard. Normally, the system does not evaluate a policy element as a string. For example, to compare a user, enter the constraint using the following format:
IF user like "??user/acme/Joe/";
You can build complex policy constraints by using logical operators. Boolean operators allow you to string multiple constraints together and to have the whole constraint return true only if certain patterns of the component constraints are true. For instance, if the whole constraint is only true if both component constraints are true.
If one of them is not true, then the whole constraint is not true, as the following example:
(wholeconstraint) is true IF (firstconstraintis true) AND (secondconstraintis true)
Or in another example, where it is true if either component is true:
(wholeconstraint) is true IF (firstconstraintis true) OR (secondconstraintis true)
Boolean operators are nothing more than a way to make these kinds of statements. You can write a complex Boolean constraint like this:
IF userBudget < 2000 AND ThisMonth = December
This constraint is only true if userBudget is less than $2000 and the current month is December. Table 4-2 lists the three Boolean operators allowed.
The third Boolean operator is NOT, which simply reverses the truth of a constraint. For example, if you want to make sure it is not December, you can write:
IF NOT ThisMonth = DecemberThe use of these Boolean operators can get as complex as you want. For example, you can have the following constraint:
IF A AND B OR NOT C
In English, this means, If both A and B are true or if C is not true, then the constraint is true. With a little thought, that is easy enough, but what about a complex constraint, such as:
IF A AND B OR C AND NOT D
Does it mean, if A and B are true or C is true and D is not true, grant the privilege, or does it mean, if A and B or C is true and D is not true, grant the privilege, or does it mean something else?
One way to decipher Boolean expressions is to understand keyword precedence, which is the order in which keywords are evaluated, and associativity, which is the direction in which terms are grouped. The order of precedence is:
AND and OR are left associative and NOT is right associative. That is, with AND and OR the system always looks to the immediate left of the keyword for the first value and to the immediate right for the second value. With NOT, the system only looks to the immediate right because NOT does not compare two or more values; it affects only one value. If our earlier example is evaluated using associativity and precedence, it means, If either both A and B are true or if C is true and D is not, the constraint is true.
Rather than remembering the policies about associativity and precedence, the easiest thing to do is to use parentheses to logically group your AND, OR, and NOT statements.
IF A AND B OR C AND NOT D
you can evaluate the statement by applying the policies of associativity and precedence or you can logically group the statements in parentheses as follows:
IF (A AND B) OR (C AND NOT D)
This eliminates ambiguity from the statement. It becomes clear that there are two constraints: (A AND B) and (C AND NOT D), and that one of those constraints must be true for the statement to be true because the two statements have an OR between them.
Changing the location of the parentheses can change the meaning of the statement. For example:
IF (A AND B OR C) AND (NOT D)
changes the statement completely. Now there are two constraints: (A AND B OR C) and (NOT D), in which both must be true for the statement to be true.
You may nest parentheses within parentheses to clarify or change the logic of the statement. For example:
IF ((A AND B) OR C) AND (NOT D)
is the same statement as the previous example, but it is now even clearer. However, if the parentheses are changed slightly, as in:
IF (A AND (B OR C)) AND (NOT D)
the meaning completely changes.
To understand complex grouped statements with parentheses, follow these policies:
Rather than building long OR or AND statements, you can define sets of constraints for your policies. A constraint set defines a set of items. For example, rather than writing:
If ThisMonth = january OR ThisMonth = february
OR ThisMonth = march
IF ThisMonth IN [january, february, march]
The keyword IN means in this set of values, and NOTIN means not in this set of values.
You can also specify a range of values in a set of constraints. For example, the following statement:
IF age NOTIN[1..100]
says if the age value is not between 1 and 100 (inclusive), then the statement is true.
The keywords IN and NOTIN work well with attributes based on enumerated types and with constant sets.
You may be wondering about the value of constraint sets when the constraint statement is nearly as long as the chain of ORs that you would instead have to write. Besides the ability to specify ranges of values, the real benefit to constraint sets is that you can predefine them as constants (Constant Declarations). Using the previous example:
IF ThisMonth in [january, february, march]
using a predefined a constant list called FirstQuarter, you can write:
IF ThisMonth in FirstQuarter
rather than the longer bracketed statement.
Declarations allow you to add new keywords to the policy language. These keywords can represent new data types, constants, attributes, or evaluation functions. Declaration names must start with a letter or an underscore. There are four types of declarations:
For programmers, type declarations are enumerated types. Type declarations declare the composition of the enumerated type and define an ordered list of acceptable values. Attributes and evaluation functions declare an instance (variable) of a built-in or enumerated type. Attributes are based on predefined or user-defined types, and evaluation functions are based on Boolean types.
For more information on declarations, see the following topics:
A constant is a named value or set of values that does not change at runtime. For instance, if you set a constant named Rate to 12, policies can then refer to the constant Rate rather than using its literal value, 12. You use constants to:
Constants are especially useful if the value changes periodically and you use the constant in more than one location. For example, if you enter a rate value 12 into multiple policies, you need to individually change each one. Instead, if you use the constant Rate, you can edit the value once and have it take effect in every policy that refers to it.
Here are some examples of simple constant declarations:
CONST Insurance = "home";
CONST InterestRate= 12;
Constants can contain other constants in their value:
CONST ClosurePoints = 2;
CONST FavoriteVehicle = Motorcycle;
If you enclose Motorcycle in quotation marks, this constant would contain a string without any special meaning. If you use Motorcycle without quotation marks, it is recognized as the special value Motorcycle of type Vehicles.
A constant can also contain a list of more than one value. For example, you may define a constant called MyColors with the values red, green, blue, white and black.
Constant lists differ from enumerated type lists. Types are used to restrict the values an attribute may contain. For example, an integer may only contain numerals and a constant list is simply a declared list or range of values with no implied order. A constant list always has an underlying type. In the previous example, the underlying type is a string. You can also create lists of any other type.
The rules for defining constant lists are as follows:
Here are some examples of constant lists:
CONST MyPets = ["Dogs", "Cats", "Birds"];
CONST CurrentAge = [1..120];
CONST WorkWeek = [monday..friday];
CONST Transportation = [Motorcycle];
You can even place another constant list within a constant list, like this:
CONST FamilyPets = ["Ferrets", "Birds", MyPets];
One benefit of a constant list is that it saves you from having to write multiple policies or string-together constraints to test if a value belongs in a group. Without constant lists, you would need to compare your value to each independent constant, rather than perform one quick test to see if the value belongs in the list. For example, given the constant list:
CONST Manager = ["Bert", "Marty", "Sandy"];
If you want to find out if your string attribute called Active contains a value that is in the Manager list, you could write constraints to test for these three possibilities:
IF Active = "Bert"
OR Active = "Marty"
OR Active = "Sandy"
IF Active IN Managers
As mentioned before, there is no implied order to the Manager list. So, even if Bert is clearly a more privileged Manager than Sandy, the following test is invalid.
If "Bert" > "Sandy"
For the test to work, you need to create an enumerated type containing the names of the three managers.
An enumerated type defines a class or group of values from which you can create constants and attributes. It is a template for constants and attributes. For example, an attribute of the type integer (a predefined, built-in type) may only have integer values. Many attributes can use the same type declaration, but each attribute is limited to one type, and this type cannot change without deleting and recreating the attribute. For example, you could have dozens of integer attribute variables, but each one is based on the same integer type declaration. Think of an enumerated type declaration as a cookie cutter and attributes as the cookies.
The following types are pre-defined and built into the product and are available for you to use. They cannot be modified.
date - A type that limits the data to the format MM/DD/YYYY and allows you to compare date values and date ranges within constraints.integer - A type that contains a whole number with no decimal places that may be negative, positive, or zero. You can use integers in comparisons and ranges.ip - A type that limits the data to the format allowed for IP (Internet Protocol) addresses: xxx.xxx.xxx.xxx, where xxx is any numeral between 0 and 255, inclusive. You can compare IP addresses, but when defining ranges of IP values, the host number, which is represented by the last three digits, is allowed to vary.string - A type that contains an alphanumeric text value. Strings do not allow comparison or range operations because they are not ordered. However, you can use wildcard comparisons using LIKE and NOTLIKE operations.time - A type that limits data to the format HH:MM:SS and allows you to compare time values and time ranges within constraints.| Note: | Different types of declarations cannot have the same names as they share the same namespace. For example, you cannot have a constant and an attribute both named account_number. In addition, the values of enumerated types share this namespace. So, continuing with our example, you could not create constants or attributes with the values Crows, Ducks, or Geese (or Birds). |
You can also create custom types. For example, you might create a type called Insurance that contains the values Truck, Car and Motorcycle. You would declare it like this:
enum_Insurance = (Truck,Car,Motorcycle)
Once you declare a type, you must declare an attribute to use the type in your policy. You can declare an attribute based on your new type like this:
cred Transportation : Insurance;
Once declared, you must give the attribute a value, like this:
Transportation = Motorcycle;
As mentioned earlier, you can compare the value based on your type by testing if the value is greater to or less than a value in the list. For example, to make your list order represent the relative level of insurance of a vehicle, you might use this constraint to see if your Transportation attribute is greater than a Car enumeration:
IF Transportation > Car
If Transportation is a Motorcycle, given the order of the list defined earlier, this would return TRUE and your constraint allows implementation of the policy.
An attribute is a variable that you can use in policies. Attributes store values that are predefined or dynamically defined at runtime.
Declaring an attribute allows you to associate an instance of that attribute with an identity or a resource. For example, you can declare a identity attribute named "email" of type "string", and then associate email addresses to users.
Attributes make policies more legible by replacing certain constraint values with logical names. You can use attributes to put values in constraints that depend on conditions unknown when you write the policy, such as timeofday. Attributes contain values for your input data that your policies can manipulate. That is, they can serve as variables, for example, account_balance could be used as an attribute.
There are several ways to use attributes:
Attributes are specific instances of a declared type. For example, an attribute of the type integer can only contain an integer value. Attributes can represent any type, whether provided as part of the product or defined by you. Here are some examples of attribute declarations:
cred month : month_type;
cred timeofday : time;
cred pencils_swiped : integer;
For a description of the different types of attributes, see the following topics:
Resource attributes store information about the entity to which they belong. For example, the Banking application might have an attribute called Version that contains the current version number for the application, denoted as a string.
Resource attributes behave differently from identity attributes. While they do inherit attributes and their values, they do not merge any values of redundant attributes. If the same attribute exists in more than one place in a tree, the resource first attempts to take the attribute from itself. Failing that, the resource takes the value of the attribute from the first resource above it on the tree that contains the attribute. The attributes of the same name on still higher nodes are ignored; once an instance of the attribute is found, the search ends.
For example, assume that you have an application resource called Banking that contains a variety of banking features. Deposit is a resource of the ATMCard application, which in turn is an application node below the Banking organization node. If both the ATMCard resource and the Banking application have the Version attribute defined with a value (and Deposit does not), Deposit inherits the value of the Version attribute from ATMCard. The Banking Version attribute is ignored.
User attributes store information about an individual user. For instance, you could have an attribute called AgeRange that stores a range of dates. Attributes are associated with a directory through a directory schema. The schema states that all users of a given directory have a given set of available attributes. Additionally the schema determines if the attribute value is a list.
You can also assign attributes to groups (although groups may only contain list attributes). Thus, users can inherit the attributes of all groups to which they belong. However, a user can still have a unique value for an inherited attribute. If you do not assign the user attribute a value, then the user inherits the value of the attribute from the group. This is how group attributes provide default attribute values for users who are members of those groups. If a user has the same attribute as a group, but a different value is assigned to the user attribute, the value of the user attribute always takes precedence of the value of the group attribute.
Even an empty string, " ", is considered a value for purposes of this rule. Therefore, if you do not assign a value, the user attribute does not take precedence over a group attribute of the same name. However, if you placed an empty string in the user attribute, it does take precedence.
Group attributes behave very differently from user attributes. Group attribute values are cumulative — if the same attribute exists in more than one place in the inheritance path of a user, the values of the attributes are merged and passed on to the user. For example, assume you have a user called Bob, and Bob is a member of the Manager group, which in turn is a member of the Employee group. If both Manager and Employee both have an attribute called WorkPlace with the values primary and secondary respectively, Bob would inherit a WorkPlace attribute with the value primary and secondary (a list attribute). In fact, to support this merging of attribute values, all group attributes must be list attributes. If the attribute merging finds the same value more than once, it eliminates the redundancy from the final list value.
Many attributes are specific instances of a declaration type. These attributes are often user (identity) attributes. For example, if you had a type called ColorType, you might have the static credentials HairColor and EyeColor, which are both of type ColorType. You can attach these static attributes to a user. Table 4-3 lists some examples of user attributes.
As previously discussed, there are several attribute types. Attributes differ from constants in that their value may change, but not the name and value type. Depending on the user making the request, a different value can be calculated for the attribute. In contrast, constants have a static value, as well as a static name and type. The declaration for a user attribute is attached to one or more directories. Because of this, all users in the same directory have the same user attribute names but not necessarily the same values for those attributes. Attributes can be applied to users, groups, and resources; however, each one behaves a bit differently.
A dynamic attribute is an attribute with a value that may change at policy evaluation time. Dynamic attributes have their value set by the provider, your application, or through a plug-in function. These attributes can have any type of value.
Additionally, plug-ins can be registered to compute the value of dynamic attributes. These plug-ins can retrieve the values of other attributes and use them to compute the attribute value needed.
Numerous time and date system attributes are pre-defined and built in. Most system attributes allow you to use comparison and range operators. Table 4-4 lists the built-in time and date attributes provided for you to use.
time24gmt1
|
integer |
|
1 |
There is a set of system attributes that contain details of the request. Table 4-5 describes these attributes and provides and example of each one.
An evaluation function is a declaration that returns one of two values: true or false. These values come from a predefined function and are included by using a plug-in extension that a programmer creates specifically for your application. Additionally, you can use any of the built-in evaluation functions available in all applications.
For instance, your programmer might create a plug-in for your accounting application that includes an evaluation function called Overdrawn that contains the results of a calculation of whether the account was overdrawn for that month. A constraint for a deny policy might use that function like this:
[Deny user access to something] IF Overdrawn();
Like functions and procedures in programming, evaluation functions can take zero or more parameter values, which are passed to the plug-in. For example, if you wanted to provide the overdrawn amount, you might use it like this:
[Deny user access to something] IF Overdrawn(500);
Evaluation functions can dynamically take different numbers or types of parameter values each time they are referenced in a policy. It is up to the programmer writing the evaluation function code to correctly handle the parameters.
Authorization caching allows the system to cache the result of an authorization call and use that result if future identical calls are made. The cache is smart and automatically invalidates itself if there is a policy change or other client side change that would affect the authorization results. However, the cache is not smart enough to know when authorization decisions depend on dynamic data. Dynamic data includes date and time values, as well as evaluation plug-ins that reference external sources. If you are using authorization caching you need to set expiration times on policies that reference dynamic data. For additional information on caching, see Authorization Caching, in Integrating ALES with Application Environments.
| Note: | By default, authorization caching is turned on. |
Table 4-6 lists the expiration functions for the authorization cache that let you set an expiration time for the authorization decision. This way you can instruct the cache to only hold the value for a given period of time, based on Greenwich Mean Time (GMT), or not to hold it at all.
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
For example, suppose you have the following authorization policy:
GRANT(//priv/order,//app/restaurant/breakfast,//group/customers/allusers) if hour < 11;
With authorization caching enabled (it is enabled by default), the results of this grant decision is cached until the next policy distribution.
On the other hand, if you call the valid_until_hour() expiration function in the authorization policy as follows:
GRANT(//priv/order,//app/restaurant/breakfast,//group/customers/allusers) if hour < 11 and valid_until_hour(11);
with authorization caching, the result of this policy is cached until 11:00 AM, at which time it expires. Therefore, with authorization caching enabled, it is important to update your time dependent policies appropriately.
Using policy inheritance can reduce the number of policies that have to written to protect a set of resources. The following topics describe how inheritance works:
Users or groups inherit the right (privilege or role) of any group to which they belong, either directly or through their parents. Group inheritance allows each user in the group to assume all the group rights to which they are members, either directly or indirectly through their parent groups (or the groups of their parents). Both users and groups can have parent groups but only groups can have children. Group inheritance is very powerful as it allows you to define entitlements once and have the policy apply to all members.
| Note: | BEA recommends that you define your role mapping policies using groups, rather than individual users. Role mapping policies written using users should be used for exceptions and to handle unusual or infrequent situations. |
It is important to note that parent groups usually have fewer rights than their children. As you move from the bottom of the resource tree to the top, the groups inherit the rights of their ancestors and are directly granted.
The immediate members of a group are called direct members. Direct members appear immediately below their parent on the inheritance tree. A member that has an inherited membership is called indirect member. The collection of all groups available, either directly or through inheritance, is referred to as group closure.
Group inheritance behavior is affected by how group membership searching is configured in your security providers. Two attributes control group membership searching:
If you set GroupMembershipSearching to unlimited, all indirect members will be considered when a policy is evaluated. If you set GroupMembershipSearching to limited, only indirect members within the number of levels of inheritance specified by MaxGroupMembershipSearchLevel will be considered.
Policies are inherited in a number of ways:
You can restrict policy inheritance by limiting its applicability. For example, you can limit the applicability of a GRANT role mapping policy by adding a constraint. The following policy illustrates this:
GRANT(//role/admin, //app/policy/www.myserver.com/protected, //sgrp/acme/manager/) IF sys_obj_q = //app/policy/www.myserver.com/protected;where: sys_obj_q is a system attribute on which the query is performed.
The sys_obj_q constraint keeps this policy from being applicable to the descendants of the protected resource, thus blocking policy inheritance.
Like users and groups, descendant resources also inherit the attributes of any parent resource. Resource inheritance allows each child resource in the tree to assume all of the attributes of the parent resource. Resource attribute inheritance is also very powerful as it allows you to define attributes on the parent resource, and have the attributes be inherited to all child resources automatically.
| Note: | BEA recommends that you define your attributes on parents, rather than individual child resources. When an attribute is explicitly defined for a child, the attribute overrides any inherited value. Policies written directly for child resources should be used for exceptions or short-lived policies so as to handle unusual circumstances. |
This section describes how ALES converts the different resource types supported by WebLogic Server, WebLogic Portal, AquaLogic Data Services Platform, and AquaLogic Service Bus and how they are represented in a resource tree in the Administration Console.
Table 4-7 lists the resource types supported for WebLogic Server, WebLogic Portal, AquaLogic Data Services Platform, and AquaLogic Service Bus.
An authorization policy involves a resource, action, subject and attributes. Every resource is represented as a node within a tree, and the node is referenced using a path-like expression. The nodes are delimited by the `/' character and can include the following hierarchy of nodes:
The root node of resources in ALES is a node named //app/policy.
Typically a node called an application deployment parent follows the root node. Using multiple application deployment parent nodes helps to organize resources according to their physical, organizational or logical structure. The application deployment parent can be set in the Administration Console under the authorization provider.
The application deployment parent is followed by the application node that corresponds to an application a resource is associated with. Not every resource belongs to a particular application (for example, a JDBC resource); in that case, the keyword shared substitutes for the name of the application.
The next level in the resource path is the resource type node. The name of this node corresponds to a resource type being addressed, for example, jms, ejb, jndi, etc.
The resource type node is followed by the resource parent node. The resource parent node helps to organize resources within an application and its value depends on the type of the resource.
The final element in a resource description is the name of the resource itself, which follows the resource parent node.
Thus, to address any resource in the resource tree, it is necessary to know the following resource path elements:
The application deployment parent depends only on the configuration of the authorization provider; the remaining four elements vary from one resource type to another.
Table 4-8 gives an example of how the different resource type can be represented in the Administration Console resource tree.
This section describes the values of resource path elements for most popular resource types. For each resource type, we describe how to specify the resource path and privileges, list dynamic resource attributes are available, and give examples of policies for that resource type. In the examples in this section, we assume that the application deployment parent node is //app/policy/AppParentNode.
Table 4-9 shows the mapping of the resource path elements for an EJB resource.
For the purposes of this example, suppose you have an EJB application named MyEjbApplication and a module named MyManagers, configured by the following EJB application declaration:
<Application Name="MyEjbApplication" Path="./applications" StagingMode="nostage" TwoPhase="true">
<EJBComponent Name="MyManagers" Targets="myserver" URI="managers.jar"/>
</Application>
Listing 4-1 shows how an EJB named AccountService could be defined in the standard EJB ejb-jar.xml deployment descriptor:
<enterprise-beans>
<!-- Session Beans -->
<session>
<display-name>AccountService</display-name>
<ejb-name>Accou