|
|
By Robert Skoczylas and Marina Sum, June 25, 2007; updated: September 10, 2007 and January 3, 2008
|
|
|
Over the past few years, demand has been steadily rising for robust solutions for securing Web applications. To ensure adequate security, most enterprises that offer online Web services implement security on two service levels:
- Authentication To verify that you are who you claim to be.
- Authorization To confirm that you have the privileges to the resources you would like to access.
Meeting the service-level requirements calls for a detailed, meticulous design of the architecture and painstaking implementation.
This article, Part 1 of a series, describes how to use Sun Java System Access Manager (henceforth, Access Manager) to fulfill the authorization requirements for a fictitious health-care insurance company, EB Health. Access Manager, an enterprise platform, secures Web applications and services with authentication, single sign-on, and authorization capabilities. The entire implementation for EB Health's needs is based on the standard, out-of- the box capabilities and custom extensions of Access Manager 6.3 (Sun Java Enterprise System 2005Q2) and ported to Access Manager 7.1 (Sun Java Enterprise System 5)with no modifications to the source code or configurations.
Part 2 discusses how to extend Access Manager authorization with a hierarchy-based resource model and interoperable Web services for .NET applications.
Contents
All of EB Health's applications are on a two-tier security model: a Web tier and an Enterprise JavaBeans (EJB) tier.
The authorization model is a role-based access control (RBAC) design that restricts access to certain parts of the applications. That model meets the following three requirements:
- Access for all authenticated users
- Access to the application URI based on roles
- Access to the application components (Java EE components, form fields, portlets) based on roles
Access Manager enables centralized authentication and policy evaluation services and dynamic access management control. In addition, enhanced manageability is achieved through a common user interface.
The most common deployment scenario for securing Web applications with Access Manager is through a Policy Agent-based architecture. In this architecture, you install a Policy Agent on the container that hosts the application and that acts as a policy enforcement point (PEP). Policy Agents can operate in various modes, most notably these two:
URL_POLICY mode In this mode, the Policy Agents intercept all incoming HTTP or HTTPS requests and validate them for authentication, session validity, and authorization. Access Manager Policy Agents are supported on most industry-standard Web containers.
J2EE_POLICY mode In conjunction with the Java EE security model, this mode propagates the subject's information to the Web and EJB tiers to ensure that Java EE programmatic and declarative security works properly. Access Manager Policy Agents are supported on most industry-standard Java EE containers.
Figure 1 is a high-level view of the architecture, which involves application servers, Policy Agents, and Access Manager:
Figure 1: Architecture of Authorization |
Even though the Java EE security model serves as a framework for authorization, it lacks central control for policy definitions and hence complicates maintenance and runtime access control. Furthermore, the Java EE Specification does not allow access levels for resource roles. You cannot, for example, define the ADMIN role to just have READ ONLY access to a session bean.
Conversely, the model illustrated in Figure 1 works well for applications that require both basic security and a sophisticated model with access levels. Read on to learn how to customize Access Manager with fine-grained access-level authorization.
The Access Manager Administrative Console (amconsole) is a Web-based interface for defining and managing policies for resources. This section describes how to meet the three authorization requirements by configuring the settings in the Administrative Console or from the command-line interface (CLI).
By adopting the architecture described in the preceding section, you can configure, out of the box, the first two requirements:
- Access for all authenticated users
- Access, based on roles, to the application URI
Here is a summary of the procedure:
- Install a Policy Agent, enabled for the
URL_POLICY mode, on the application server that hosts the application.
- Create a policy rule to allow access to a URL, for example,
http://www.ebhealthinsurance.com/claims/*, for all the subjects, that is, the authenticated users.
- Repeat steps 1 and 2 for the second requirement. The subjects in this case would be the roles that have the privilege to access the defined resource.
Granting Access to Authenticated Users
To secure access to the Claims application at EB Health, define the policy, the rules, and the subjects, as follows:
- In the Administrative Console, click New Policy to create a policy and then New Rule to create a rule.
- In the screen shown in Figure 2, select URL Policy Agent (with resource name). Click Next.
Figure 2: Selecting URL Policy Agent as the Service Type for the Rule |
- In the screen shown in Figure 3:
- Type
Claims Processing Application in the Name field.
- Type
http://www.ebhealthinsurance.com/claims/*, the URL of the Claims application, in the Resource Name field.
- Select Allow for both
GET and POST under Actions. Click Finish.
Figure 3: Defining the Specifics for the Rule |
- Create another subject and then, in the screen shown in Figure 4, select Authenticated Users. Click Next.
Figure 4: Selecting Authenticated Users as the Subject Type |
- In the screen shown in Figure 5, type
All Authenticated Users in the Name field. Click Finish.
Figure 5: Specifying a Name for the Subject |
Access Manager then confirms the policy settings, as shown in Figure 6.
Figure 6: Confirmation of Policy Settings |
Granting Access to the Application URI
To satisfy the second requirement and grant access to only certain roles, repeat steps 1 through 3 in the preceding section and then do the following:
- In the screen shown in Figure 7, select Access Manager Identity Subject. Click Next.
Figure 7: Selecting Access Manager Identity Subject as the Subject Type |
- In the screen shown in Figure 8, type
Admin Role in the Name field and choose Role from the Filter drop-down menu.
- Under Available, select
admin and click Add to move it to the Selected area. Click Finish.
Figure 8: Defining the Subject Parameters |
Granting Role-Based Access to the Application Components
To satisfy the third requirement of granting access to the application components, customize Access Manager by creating a service that secures components at a much lower level than that offered through the URL resources.
Security Requirements
EB Health aims to programmatically accomplish the following:
- Allow certain roles to access only certain parts of the Claims application.
- Deny access of certain parts of the Claims application to the unauthorized roles.
- Centrally collect the information in a policy store.
Toward that end, EB Health must secure page-level resources and, for each of the resources, specify an access level by role. The access levels are CREATE, READ, UPDATE, DELETE, ALL, and NONE.
For example, EB Health would like to control access to the User Profile screen in their Claims application according to roles. Thanks to the Java EE application, which enables users to access resources but restrictsaccording to the user roleswhat users can view and do, that screen renders differently for different roles.
Two roles can access the User Profile screen: Admin and Employee. The security requirements and related UI, as illustrated by Figure 9, are as follows:
Admin This role has all privileges to the entire screen, including the SSN [Social Security Number] field (SSN_FORM_FIELD). Accordingly, when accessed by Admin, the User Profile screen shows all the field values being editable along with the Create, Update, Delete, and Cancel buttons.
Employee This role has UPDATE privilege for the User Id, Email, and Phone fields; but only READ privilege to the SSN field. When accessed by Employee, the User Profile screen shows only the User Id, Email, and Phone fields being editable and grays out the SSN field to reflect the role's READ ONLY access.
Figure 9: Access of User Profile Screen According to Admin and Employee Roles |
Procedure
First, extend the Access Manager services and create a service named CustomClaimsAppPolicyService:
- Create an XML schema named
CustomClaimsAppPolicyService.xml that complies with the Document Type Definition (DTD), sms.dtd, and that specifies the six access levels.
The schema also describes the service name, service attributes, and their values.
- Import the
CustomClaimsAppPolicyService.xml file into Access Manager on the CLI. Type, all on one line:
/opt/SUNWam/bin/amadmin --verbose --runasdn uid=amAdmin,ou=People,dc=ebhealthinsurance,dc=com --password admin-password --schema CustomClaimsAppPolicyService.xml
Access Manager then generates the following output:
Info 109: Calling XML PARSER
Info 110: XML file to import:CustomClaimsAppPolicyService.xml
Info 103: Loading Service Schema XML CustomClaimsAppPolicyService.xml
Service Schema XML CustomClaimsAppPolicyService.xml
Info 115: Reading schema file :CustomClaimsAppPolicyService.xml
Info 105: Done loading Service Schema XML: [CustomClaimsApplicationPolicyService]
Success 0: Successfully completed.
|
Note: You need not restart the server for the changes to take effect.
- Copy
CustomClaimsAppPolicyService.properties and CustomClaimsAppPolicyService_en.properties to Access Manager's local directory, for example, /opt/SUNWam/locale.
Next, create the policies from either the Administration Console or the CLI. The procedures below show you how to create the Claims Process Policy and specify the related rules and a subject from both venues.
Note: In the case of deployment of large-scale applications with numerous policy rules, the CLI might be more appropriate.
From the Administration Console:
- Click New Policy to create a policy.
- Fill in the Policy Name and Description fields with the values of your choice.
- Click New under Rules.
Access Manager displays the new custom policy service among the default service types.
- In the screen shown in Figure 10, select
CustomClimsApplicationPolicyService (with resource name) and click Next.
Figure 10: Selecting CustomClaimsApplicationPolicyService as the Service Type for the Rule |
- In the screen shown in Figure 11, define the rules that associate the resources with their access levels, as filled in for the figure.
Figure 11: Defining the Settings for the New Rule |
A resource name can be a string representation of a component, widget, page, URL, or any other object that requires authorization, making for flexibility and convenience.
- Create another rule for the user form with the following settings:
| Service Type | CustomClaimsApplicationPolicyService |
| Name | UserForm_A1 |
| Resource Name | UserForm |
| Choose Permission | ALL |
- Assign the subjects (roles), in this case Access Manager roles, for the rules by selecting Access Manager Identity Subject in the screen shown in Figure 12. Then search by role to list the entire set of available roles.
Figure 12: Selecting Access Manager Identity Subject as the Subject Type |
- In the screen shown in Figure 13, type
Admin Role in the Name field because the policy allows ALL access to the SSN field for the Admin role. Under Filter, add admin to the Selected area. Click Finish to return to the previous screen.
Figure 13: Specifying the Settings for Access Manager Identity Subject |
Figure 14 summarizes the rules and subject you just created.
Figure 14: Rules and Subjects for Claims Process Policy |
From the CLI:
- Create an XML schema named
ClaimsApplicationPolicies.xml that complies with the DTD, amAdmin.dtd, and that contains the policy information.
- Import
ClaimsApplicationPolicies.xml. Type, all on one line:
/opt/SUNWam/bin/amadmin --verbose --runasdn uid=amAdmin,ou=People,dc=ebhealthinsurance,dc=com --password admin-password --data ClaimsApplicationPolicies.xml
Access Manager then generates the following output:
Info 107: Calling XML PARSER
Info 108: XML file to parse:ClaimsAppPolicies.xml
Info 101: Processing ClaimsAppPolicies.xml
Info 111: Requests generated by amadmin
Info 130: Created Policy under Organization dc=ebhealthinsurance,dc=com
Info 102: Done processing ClaimsAppPolicies.xml
Success 0: Successfully completed.
|
The Claims application is now ready to secure its resources by invoking policy evaluation against Access Manager.
This section describes how to implement security in the Claims application with the Access Manager SDK.
Introducing the Process
The process involves an installation of the Access Manager Policy Agent, including the Access Manager SDK, in the Java EE container that hosts the Claims application. To connect with Access Manager, the Policy Agent sets the necessary client Java archive (JAR) files and configuration. In turn, the configuration enables the Java EE platform-compliant application to secure access through authentication and URL-based, coarse-grained authorization with the Policy Agent.
For an additional level of authorization, the Access Manager SDK within the application code comes into play. During policy evaluations, Access Manager automatically reflects policy changes on the server side.
You can configure the cache parameterssize, other intervalsby editing the AMAgent.properties file. In the case of EB Health, because the Policy Agent already furnishes an adequate level of caching, no custom caching mechanism is required.
Figure 15 is a high-level illustration of the deployment scenario.
Figure 15: Deployment |
Delving Into the Code
This subsection cites several code segments to demonstrate the authorization process.
Policy Evaluation and Policy Decisions
The following code segment evaluates the policy:
String serviceName = "CustomClaimsApplicationPolicyService";
String resourceName = "SSN_FORM_FIELD";
com.sun.identity.policy.client.PolicyEvaluator pe;
PolicyDecision policyDecision;
Map envParams = new HashMap();
/*
Note: The implementation of PolicyEvaluator is from package com.sun.identity.policy.client
*/
pe = new PolicyEvaluator(serviceName);
policyDecision = pe.getPolicyDecision(token, resourceName, actionNames, envParams);
String str = policyDecision.tostring();
String xml = policyDecision.toXml();
|
Here, the client PolicyEvaluator is invoked with the appropriate parameters. Depending on the parameters passed from the Claims application, Access Manager returns a policy decision that represents the access level.
The PolicyDecision object contains either of these two methods:
toString This method generates the output permission=[all].
toXML This method generates the following output:
<PolicyDecision>
<ResponseAttributes>
</ResponseAttributes>
<ActionDecision timeToLive="1179344504796">
<AttributeValuePair>
<Attribute name="permission"/>
<Value>all</Value>
</AttributeValuePair>
<Advices>
</Advices>
</ActionDecision>
</PolicyDecision>
|
In the case where you have configured multiple permissions for a resource, Access Manager returns a list of those permissions as part of the evaluation. Consider the example of a user with these two roles:
Admin ALL access to the resource UserForm
Employee CREATE and READ access to the resource UserForm
After evaluating the policy, Access Manager returns either of these two scenarios on UserForm for the user:
- The
toString method, which generates permission=[all, create, read]
- The
toXML method, which generates the following output:
<PolicyDecision>
<ResponseAttributes>
</ResponseAttributes>
<ActionDecision timeToLive="1179346529031">
<AttributeValuePair>
<Attribute name="permission"/>
<Value>all</Value>
<Value>create</Value>
<Value>read</Value>
</AttributeValuePair>
<Advices>
</Advices>
</ActionDecision>
</PolicyDecision>
|
Determination of Access Level
You can place the permissions returned in PolicyDecision into a class, for example, AccessLevel, and manage it as an object or a set of objects at runtime. How to handle a set of access levels for a given resource might vary according to the requirements of the application. EB Health requires that the permissions be returned as a result set of AccessLevel classes to facilitate further operations. As a safeguard, the Claims application queries the result set for specific permissions before granting access and rendering pages.
See this AuthZClientProxy class, in which a client proxy class (AuthZClientProxy) encapsulates the Access Manager SDK and creates an AccessLevel object according to ActionDecision. This strategy acts as a facade to the underlying Access Manager SDK by encapsulating Access Manager SDK-specific code.
Also, you can instantiate the proxy client from the Web tier with HttpSerlvetRequest or with EjBContext from the EJB tier. Both context objects enable the proxy client to retrieve SSOToken, which is created by the underlying Policy Agent. In EB Health's case, policy decisions are also cached by the Access Manager SDK for enhanced performance. For the caching configurations, see the Policy Agent's configuration file.
EB Health implements the client proxy within Web components and EJB components. The proxy encapsulates the Access Manager SDK-specific calls and sends an abstraction to the application. The underlying Policy Agent mandates the URL_POLICY mode for a smooth go within the Web tier.
Important: Be sure to set the correct mode to propagate the subject's information to the tiers for a correct evaluation of the policies. Failure to do so results in denied access to the application.
Here is the related code segment:
public void doGetPost (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
AuthZClientProxy client = new AuthZClientProxy(request);
AuthZResultSet levels = client.authorize(resource);
If (levels.hasAll()) {
//User has all permission to resource
} else if (level.hasCreate()) {
//User has create permission to resource
} else if (level.hasRead()) {
//User has read only permission to resource
} else if (level.hasUpdate()) {
//User has update permission to resource
} else if (level.hasDelete()) {
//User has delete permission to resource
} else {
//User has other access level or no permission to resource
}
|
The same code also resides within the EJB layer. The only difference is that EJBContext must be passed to the constructor during instantiation. Afterwards, the Access Manager SDK retrieves with EJBContext the identity token of the subject that's attempting to access the resource. During authentication, Access Manager creates the user token and propagates it to the Web and EJB tiers.
This code segment illustrates the scenario:
EJBContext ctx;
AuthZClientProxy client = new AuthZClientProxy(ctx);
AuthZResultSet levels = client.authorize(resource);
If (levels.hasAll()) {
//User has all permission to resource
} else {
if (levels.hasCreate()) {
//User has create permission to resource
}
if (levels.hasRead()) {
//User has read-only permission to resource
}
if (levels.hasUpdate()) {
//User has update permission to resource
}
if (levels.hasDelete()) {
//User has delete permission to resource
}
} // else
|
Important: Implementation of the policy evaluation APIs on the EJB tier requires that you configure the Policy Agent to the J2EE_POLICY or ALL mode. Failure to do results in denied access to the application.
The EB Health example demonstrates that, as a platform for securing Java EE application resources, Access Manager enables you to customize the required extensions with only minimal effort. Like all enterprise implementations, the EB Health case requires a circumspect architecture to meet the service-level requirements. Proper processes must be in place to govern the rollout of policies for all the applications.
Part 2 of this series will show you, by means of policy evaluations through bulk operations, how to enhance performance by minimizing the number of requests that are sent to Access Manager. The article will also describe how Access Manager and Microsoft .NET services interoperate and how EB Health secures both platforms with Access Manager. Stay tuned.
Many thanks to Bartosz Adamczyk, Rajeev Angal, Dilli Dorai, Rajeev Parekh, Pat Patterson, and Aravindan Ranganathan for their invaluable feedback and suggestions.
- Sun Java System Access Manager
- Publications of interest
- Sun developer services
|
Robert Skoczylas is a senior enterprise architect with Indigo Consulting, a Sun partner consulting firm. He has over a decade of experience building distributed systems with Java, open-source, and open standards-based technologies, specializing in SOA and identity-based systems for enterprises worldwide.
|
Marina Sum is a staff writer for Sun Developer Network. She has been writing for Sun since 1989, mostly in the technical arena. Marina blogs on Sun products, technologies, events, and publications.
|
|