Dec 2, 2005 - Frank Piessens, Bart De Win, Eddy Truyen, Wouter Joosen. DistriNet, K.U. ... bear this notice and the full citation on the first page. To copy ...
Implementing a Modular Access Control Service to Support Application-specific Policies in CaesarJ ∗
Tine Verhanneman , Frank Piessens, Bart De Win, Eddy Truyen, Wouter Joosen DistriNet, K.U.Leuven 3001 Leuven, Belgium {tine,frank,bartd,eddy,wouter}@cs.kuleuven.be
ABSTRACT Ideally, the enforcement of application-specific policies in an access control service should be untangled from the application logic. The access control services that are provided in state-of-the-art application servers typically fail to support such a separation. Aspect-Oriented Software Development techniques can be used to alleviate such shortcomings. This paper describes the design and implementation of a modular access control service that improves the separation between application logic and access control. The prototype has been implemented in CaesarJ.
Categories and Subject Descriptors D.2.2 [Software Engineering]: Design Tools and Techniques—Modules and interfaces; D.4.6 [Software]: Operating Systems—Security and Protection
General Terms Security, Design
1.
INTRODUCTION
Existing middleware platforms need to cater for a variety of applications. The access control services, integrated in these platforms, support only access control policies which are limited in expressiveness: These access control services can typically only take into account information contained within the method invocation (invocation access policy [11]), and for example, fail to include application state in the access decision process. As an example, the declarative access control system in J2EE makes decisions based only on application method names and subject role. ∗Tine Verhanneman is supported by a grant from the Institute for the Promotion of Innovation through Science and Technology in Flanders (IWT-Vlaanderen)
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. AOMD ’05 November 28- December 2, 2005 Grenoble , France Copyright 2005 ACM 1-59593-265-8/05/11 ...$5.00.
Article 5
However, this does not suffice for many distributed applications, of which the access control policy relies on applicationspecific information. For these cases, existing platforms provide an API to interact with the access control service and leave it up to the application developer to enforce the application-specific access policy. In J2EE, for example, this API allows to find out who the current principal is. This socalled imperative access control leads to tangling of the access control concern with the functionality. Aspect-oriented languages and frameworks, designed to support separation of concerns, promise to improve the support of applicationlevel access control services in middleware, or at least the development of enhanced access control modules that are reusable across a variety of applications [5, 6]. In this paper, we report on our experiences of implementing such an advanced access control service in CaesarJ [1, 9]. Our major goal was to build a modular access control service which can enforce expressive policies taking into account application-specific state. This access control service (1) should be bound to an application without requiring invasive changes to this application. This allows to change the policy enforced (by preference declaratively) without needing to modify the application itself. The modular access control service, moreover, (2) encompasses a reusable authorization engine, which decides on access requests according to a given access policy. It should be straightforward to plug in such an engine into the access control service. To realize this, we view the access control service as a socalled container managed service, provided by an application server to the application without the application needing to be aware of it. The access control service controls access to security critical operations and should be easily configurable by means of a deployment descriptor, so that the desirable access policy is enforced. The access control service itself, may be woven into the application at deployment time or may be a runtime entity. The service intercepts critical operations, calls the authorization engine, and enforces its decision. The remainder of the paper is structured as follows: In Section 2, the design of the access control service is described. Section 3 discusses its implementation in CaesarJ, which is evaluated in Section 4. In Section 5, conclusions are drawn.
2.
ACCESS CONTROL SERVICE DESIGN
In this section, the design of the access service is presented. This design is based on the concepts access interface and view connector. These concepts are briefly introduced
and illustrated by means of a small calendar application. An elaborated motivation and more details can be found in [12].
2.1
Figure 1: Calendar Access Interface ObjectInterface CalendarAO{
Calendar System
The calendar application presented, is based on the calendar application in [3]. The calendar system allows users to book appointments, or entries, which may be either singular (one entry) or continual (repetitive). A calendar entry involves the participating users and some resources (laptops, projectors, . . . ). Three main actors can be distinguished: Calendar owner, Secretary and Employee, whose access rights are determined by the following access policy:
action: action: action: action: action:
showEntries; newContinualEntry; newEntry; editEntry; deleteEntry;
action: action:
book; cancel;
} SubjectInterface EmployeeAS{} SubjectInterface CalendarOwnerAS extends EmployeeAS{
2. The secretary of the owner of a calendar can book only singular entries and edit all entries. He is also allowed to book the necessary resources.
attribute: SecretaryAS secretary; } SubjectInterface SecretaryAS extends EmployeeAS{}
3. The information in a calendar is publicly accessible to all employees, but cannot be changed by them.
Access Interface
An access interface is an additional abstraction layer, providing a view on the application which reflects only information relevant for access control. An access interface can be seen as a domain model, which specifies all that is needed to formulate the access policy. In this model, the application is viewed as a set of (security) objects and (security) subjects, who can make an access request to perform an action on an object. We assume (as is customary in access control) that the objects are subdivided into domains, and that subject are classified into roles, and that the information needed to decide on an access request, can differ depending on the domain and role of the object and subject involved, respectively. An access interface consists of a number of object interfaces (one per domain) and a number of subject interfaces (one per role). These interfaces declare the information that the policy may need, in the form of a number of attribute declarations. An object interface declares in addition semantic actions. These semantic actions abstract syntactic actions and represent the security sensitive operations to which the policy applies.
Calendar Access Interface Figure 1 displays a possible access interface for this calendar application, which is based on the high level policy rules formulated in the Section 2.1. The access policy can be formulated in terms of this access interface, as shown in Figure 2.
2.3
CalendarOwnerAS calendarOwner;
} ObjectInterface ResourceAO{
1. The owner of the calendar can book, edit and delete entries. However, he is not allowed to book a resource as this is the responsibility of his secretary.
2.2
attribute:
View Connector
The access interface needs to be bound to the application by means of a deployment descriptor. This is done by an application-specific view connector. This view connector: 1. decides how application objects map to (security) objects and subjects. The view connector implementation currently only supports the specification of domains (and role) based on the type of an application object. 2. determines how to compute the necessary attributes for security objects and subjects.
Article 5
3. identifies all operations on such data and map these operations to the corresponding semantic actions in the object interface. We leave open how this view connector is actually implemented; e.g. it can be woven into the application or represented as a runtime entity.
Calendar View Connector The class diagram for the Calendar application is shown in Figure 3. In Figure 4, a small part of the (simple) view connector for the calendar application is described. For a more complex example, we refer to [12].
2.4
Access Control Service
The access control service can now be seen as a collaboration, as shown in Figure 5, between following three entities: (third party) authorization engine, access interface and the view connectors, which each bind the access interface to a particular application. The view connector makes use of the access control decision functionality (checkAccess ) each time an application event occurs, which is annotated as one of the semantic actions in the access interface. Conversely, the authorization engine can query the view connector, through the access interface, to retrieve the required object and security attributes. In the next section, we will elaborate on a prototype of this access service implementation in CaesarJ.
3.
IMPLEMENTATION IN CAESARJ
We will start by describing the design. Afterwards, the design will be motivated and compared with alternative design choices. The presented codelistings use the current syntax of the CaesarJ language which differs considerably from the syntax presented in [9]. Further details can be found on the CaesarJ homepage [1].
3.1
Access Interface
The access interface, shown in the codelisting below, is modeled as a Caesar collaboration (cclass ), which declares
ResourceAO r -
Role EmployeeAS
e
SecretaryAS
( EmployeeAS )
s
r.book r.cancel
CalendarOwnerAS
( EmployeeAS )
co
-
CalendarAO c c.showEntries [s=c.calendarOwner.secretary] c.newEntry c.editEntry [co=c.calendarOwner] c.newContinualEntry c.newEntry c.editEntry c.deleteEntry
Figure 2: Access Matrix
Employee
CalendarFactory
-name: String +getName(): String
+createCalendar(user:User): Calendar
Calendar
Secretary
-entries: Entry[] +newEntry(time:TimeInterval,r:Resource[]): void +newContinualEntry(firstOccurence:TimeInterval, endDate:Date,r:Resource[]): void +updateEntry(entryID:int,t:TimeInterval, r:Resource[]): void +deleteEntry(entry:Entry): void +showEntries(): Entry[] +getOwner(): User
1 0..1
User
is owned by
hasSecretary *
1
-calendar: Calendar -secretary: Secretary
*
+assignSecretary(s:Secretary): void +getCalendar(): Calendar +getSecretary(): Secretary
meets with
*
Entry -timeInterval: TimeInterval -resources: Resource[] -EID: int -users: User[]
Resource * uses
*
+getEID(): int +getTimeInterval(): TimeInterval
ResourceFactory +createResource(): Resource
-bookings: Entry[] +bookEntry(e:Entry): void +cancelEntry(e:Entry): void +showBookings(): Entry[]
Figure 3: Calendar Design Model
1. Domain Mapping type: object-interface:
Calendar CalendarAO 2. Information Retrieval
attributes: calendarOwner
→
Calendar.getOwner()
3. Semantic Action Annotations actions: showEntries newContinualEntry newEntry editEntry deleteEntry
→ → → → →
getAllEntries() newContinualEntry(..) newEntry(..) updateEntry(..) deleteEntry(..)
Figure 4: Calendar View Connector
Article 5
Acces Control Service Collaboration Authorization Engine
3.2
The choice for a specific authorization engine can be left open. The interface of the authorization engine, shown in Figure 6, is independent of the specific access interface bound to the application. It only makes use of the abstract AccessInterface collaboration, presented in Section 3.1. Since CaesarJ supports family polymorphism [7], the type of the parameter m can be declared as a dependent type, which guarantees that m belongs to the family of o, and thus that m is a valid action on o.
checkAccess
Access Policy checkAccess Access Interface
information Retrieval
semantic actions domains (object interface) roles(subject interface) attributes
View Connector
View Connector
Application a
Application b
To integrate a specific authorization engine, we might have to write an adaptor to translate the access request in a format the engine understands. The only assumption here is that the engine is able to cope with the (common) abstractions subject, object and method and with attributes for subject and object. We could for example integrate with the Ponder [4], or XACML framework [10]. In the implementation of this adaptor, we can choose to push all the information that the access control service might possibly need. Alternatively, a lazy strategy can be used, whereby the access control service pulls the attributes by means of callbacks, whenever needed for the evaluation of an access request.
binding to the application
Figure 5: Access Control Service
two virtual classes, namely AccessSubject and AccessObject . The latter, on its turn, declares a virtual class AccessMethod .
3.3
View Connector
The responsibility of the view connector is to bind an access interface to the application. In this design, we have implemented the view connector as a cclass which binds an AccessInterface to the application. In Figure 7, a small part of this implementation is shown, which binds the CalendarAccessInterface to the calendar application according to the view connector presented in Figure 4. It does this by extending the corresponding access interface. Two parts can be distinguished: 1. Wrappers (line 3-9) implement the retrieval of attributes for both (security) objects and subjects. These attributes may be retrieved from the application object itself (by means of the wrappee construct) or may be declared by the wrapper.
public abstract cclass AccessInterface{ public abstract cclass AccessSubject{} public abstract cclass AccessObject{ public abstract cclass AccessMethod{} } }
When an access interface for a specific application domain is to be implemented, the above presented AccessInterface is extended, and the necessary object- and subject interfaces are provided. For attributes, an (abstract) getter is provided. The access interface for the calendar application then may look like this:
2. Pointcuts (line 10-16) translate application-specific requests in terms of the access interface, wherever applicable and invoke the authorization engine. Depending on its decision, the call proceeds or an access failure is reported.
public cclass CalendarAccessInterface extends AccessInterface{ //[SubjectInterfaces] public cclass EmployeeAS extends AccessSubject{} public cclass SecretaryAS extends EmployeeAS{} public abstract cclass CalendarOwnerAS extends EmployeeAS{ public abstract SecretaryAS getSecretary(); } 10 //[ObjectInterfaces] public abstract cclass CalendarAO extends AccessObject{ public abstract CalendarOwnerAS getCalendarOwner(); public cclass NewEntry extends AccessMethod{} ... } public cclass ResourceAO extends AccessObject{ public cclass Book extends AccessMethod{} ... }
Authorization Engine
20
}
Article 5
In the pointcuts, we can get hold of the AccessSubject (line 13), which represents the subject on whose behalf the access request is made. The view connector retrieves this subject, by interacting with a session, which holds the active roles for a user or process.
3.4
Motivation
The choice to implement the prototype in CaesarJ was driven by the support the language offers to modularize aspects: A collaboration interface allows to introduce abstractions as nested virtual classes, which are characteristic for the aspect. Expected and provided methods (although not explicitly enforced in the current CaesarJ language) make explicit what functionality the aspect provides and needs so that it can be bound to an application. We implemented semantic actions as virtual classes in the AccessInterface (Section 3.1). This construction is needed
Figure 6: Authorization Engine public abstract cclass AuthorizationEngine{ public abstract boolean checkAccess(AccessInterface.Subject s, final AccessInterface.Object o, o.AccessMethod m); }
Figure 7: Calendar View Connector public cclass CalendarViewConnector extends CalendarAccessInterface{ //[WRAPPERS] public cclass CalendarWrapper extends CalendarAO wraps Calendar{ public CalendarOwnerAS getCalendarOwner(){return CalendarOwnerAS(wrappee.getOwner());} } public cclass CalendarOwnerAS wraps User{ public SecretaryAS getSecretary(){return SecretaryAS(wrappee.getSecretary());} } //[POINTCUTS] void around(Calendar c) : (execution(void Calendar+.updateEntry(. .)) && this(c)){ final CalendarAO cao = CalendarWrapper(c); if (accessService.checkAccess(getAccessSubject(),cao,cao.new EditEntry())) proceed(c); else {reportAccessDenial(new AccessDenial("Calendar.updateEntry");} } ... }
of exploring and comparing alternative implementations. In the prototype implementation, we have implemented the view connector ourselves by hand. It should be feasible to generate the code of the view connector given its descriptor. This has not yet been implemented.
Figure 8: Access Control Service in CaesarJ Access Control Service AuthorizationEngine
-
AccessInterface objects & subjects actions attributes
-
View Connector domain mapping information retrieval
-
semantic actions checkAccess
+
-
Caesar Collaboration Interface (provided operation) Collaboration Interface abstract nested classes concrete nested classes expected operations (declaration) binding wrappers expected operations (implementation) pointcuts
4.
DISCUSSION
In this section, we evaluate our approach (Section 4.1), describe our experiences with CaesarJ (Section 4.2) and discuss how the access control service may fit into middleware (Section 4.3).
4.1
because Caesar does not provide explicit support to represent semantic actions. Reifying the semantic action allows us to keep the interface of the access control service generic. CaesarJ’s family polymorphism and dependent types, moreover, render the interface typesafe. In Figure 8, we summarize how the concepts Caesar offers, are used to implement the Access Control Service collaboration (Figure 5). Alternatively, we could have implemented the semantic actions as (provided) methods on the AccessObject and invoke these in the binding instead of instantiating an AccessMethod object (Figure 7). Implementing the semantic actions like this, would require that we invoke the checkAccess method in the implementation of every method. This duplication of code can be avoided by declaring a generic pointcut in the AccessInterface , which intercepts each provided method declared by an AccessObject . Also, provisions should be made that the subject (AccessSubject ) is conveyed to the authorization engine. We have not yet implemented this alternative design and are still in the process
Article 5
Evaluation of Our Approach
Now, we will discuss to what extent we were able to fulfill the goal, as stated in Section 1, namely to build a modular access control service to enforce expressive policies taking into account application-specific state, which (1) can be bound to an application without requiring invasive changes to this application and (2) encompasses a reusable authorization engine.
4.1.1
Modular Binding to the Application
As soon as a more expressive access policy needs to be enforced, it is the responsibility of the application developer to enforce this policy in the application (as discussed in Section 1): Either the access logic is hardcoded or calls to an external authorization engine are embedded in the application. In the latter case, the developer needs to ensure that all the information, needed for the access request evaluation, is conveyed to the engine. Moreover, the access request might need to be translated into terms understood by the access engine, before this engine is called. In the CORBA Resource Access Decision (RAD) service [2], for example, a protected resource name and access operation are conveyed to the access decision function, which abstract respectively the object accessed and the action.
10
Entangling access logic or calls to an authorization engine with business logic, renders it hard to adapt the enforced access policy. Aspect-Orientation allows to define the abstractions required by the access logic as a sort of view onto the application, and to bind these to the application at hand in a modularized manner. A problem, which is not specific for the access control aspect, is how to deal with exceptions or exceptional conditions which originate within the aspect. In our case, an access denial could potentially occur at each method invocation. As a consequence, the application may be left in an inconsistent state. Future work should reveal how costly it is to provide the necessary recovery/rollback operations.
4.1.2
A Reusable Authorization Engine
Authorization engines, such as Tivoli Access Manager [8] or the CORBA Resource Access Decision (RAD) service [2], are commonly used. However, their support for applicationspecific policies is limited, in the sense that it is not made explicit which information the authorization engine expects to evaluate an access request. In our approach, this is made explicit by the access interface, with which the authorization engine can be configured.
4.2
Experiences with CaesarJ
As has been shown in the previous sections, CaesarJ provides the developer with powerful means to come to a reusable and type safe design. In this section, we discuss our experiences with the CaesarJ language.
4.2.1
Type System
Caesar provides a strong type system which enforces type safety. In some occasions, this type system is too restrictive, as is briefly illustrated in the following paragraphs by means of two examples.
Nominal Subtyping. CaesarJ supports nominal subtyping, i.e. the developer needs to state explicitly all the subtyping relations. A caesar cclass has to declare explicitly which collaboration interface(s) it implements or binds. We have encountered situations, where we would like to leave this choice open until (mixin) composition time. To support this case, a form of structural subtyping is needed.
Compound Types. CaesarJ does not support the declaration of compound types. For example, we should be able to declare a type which extends two mixins (say A and B ) as A & B . Instead, a third mixin (say C ) has to be defined which extends these two mixins. The same problem exists with interfaces in Java, but is aggravated in the presence of a multitude of mixins, which allow to modularize a more fine-granular unit of functionality.
4.2.2
Lack of Guidelines
CaesarJ offers the developer more options to model an application than plain Java. However, a choice may impose restrictions on a design, which one may not have foreseen, and which may render the composition hard or even unfeasible. Therefore guidelines are needed to help the developer in making the right choices.
4.3
Middleware Support for Access Control
Our access control system is an aspect based subsystem that manages the separation of concerns between security
Article 5
specific components (i.e. authorization engine) and the application logic. View connectors indeed are aspects. An interesting question is whether the underlying middleware layers need to (or should) offer specific support for such aspects. In practice, we did not strictly require anything beyond the support of a standard distribution platform (e.g. remote invocation) to have our prototype up and running. In a way, the good news is that in this case aspect-orientation can be achieved in principal on top of state-of-the-art middleware. However, a relevant improvement would be to build in support to make the construction of view connectors more straightforward, even configurable - and thus part of the middleware. This is an important topic for further investigation.
5.
CONCLUSION
In this paper, we reported on our experiences of developing a modular access control service, which is capable of enforcing application-specific policies, and which, at the same time, can be bound to an application without requiring invasive changes. A design and an implementation in CaesarJ has been presented. From this experience, we conclude that CaesarJ offers powerfull concepts to modularize concerns, but that guidelines are needed to help developers in choosing the most appropriate design option.
6.
REFERENCES
[1] CaesarJ homepage: http://caesarj.org/. [2] K. Beznosov, Y. Deng, B. Blakley, C. Burt, and J. Barkley. A Resource Access Decision Service for CORBA-based Distributed Systems. In ACSAC’99, pages 310–319, 1999. [3] G. Brose, M. Koch, and K.-P. L¨ ohr. Integrating Security Policy Design into the Software Development Process. Technical Report Technical Report B-01-06, Freie Universit¨ at Berlin, November 2001. [4] N. Damianou, N. Dulay, E. Lupu, and M. Sloman. The Ponder Policy Specification Language. LNCS, 1995:18–28, 2001. [5] B. De Win, W. Joosen, and F. Piessens. Developing secure applications through aspect-oriented programming. In R. E. Filman, T. Elrad, S. Clarke, and M. Ak¸sit, editors, Aspect-Oriented Software Development, pages 633–650. Addison-Wesley, 2005. [6] P. T. Devanbu and S. Stubblebine. Software engineering for security: a roadmap. In ICSE ’00, pages 227–239, 2000. [7] E. Ernst. Family Polymorphism. In ECOOP ’01, pages 303–326, 2001. [8] G. Karjoth. Access control with IBM Tivoli access manager. ACM Trans. Inf. Syst. Secur., 6(2):232–257, 2003. [9] M. Mezini and K. Ostermann. Conquering aspects with Caesar. In AOSD ’03, pages 90–99, 2003. [10] OASIS. Core Specification: eXtensible Access Control Markup Language (XACML) Version 2.0. [11] Object Management Group. Security Service specification, v1.8, March 2002. [12] T. Verhanneman, F. Piessens, B. De Win, and W. Joosen. Uniform Application-level Access Control Enforcement of Organizationwide Policies. to appear in ACSAC’05.