Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/
Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Security considerations

Project Zero implements system-level authentication and authorization. Applications can take advantage of Project Zero security by defining security rules that determine which resources are protected, by what means they are protected, and what users and groups are allowed to access those resources.

The following sections of this article provide information about authentication, authorization and requiring SSL:

Types of authentication

Project Zero provides implementations of the following types of authentication:

Basic authentication
Basic authentication is defined in RFC 2617.
Form-based authentication
The full-page form login that leverages external redirect.
Single sign-on authentication
The URL based login that leverages HTTP request parameters.
OpenID authentication
OpenID consumer based authentication for third party authentication with an OpenID provider.
Programmatic login authentication
Provides an API-based authentication model.

Security rules

Project Zero security leverages the user service that defines the users and groups referenced in the security rules. Security rules define protected resources. Resources that are not covered by any security rule are not protected.

If multiple rules match a given resource, only the first rule defined determines how that resource is protected.

Each rule contains the following information:

conditions
Any Zero condition expression. Commonly based on URI patterns (e.g. (/request/path =~ /customers(/.*)?) ) and methods (e.g. (/request/method == [PUT|POST])).
authType
The type of authentication: Basic, Form or SSO.
users
An optional list of users, separated by commas, that are allowed to access these resources.
groups
An optional list of groups, separated by commas, that are allowed to access these resources.
roles
An optional list of roles, separated by commas, that are allowed to access these resources. HELP Advanced

The following example shows basic authentication configuration:

@include "security/rule.config"{
   "conditions": "(/request/path =~ /customers(/.*)?)  && (/request/method ==[PUT|POST]) ",
   "authType" : "Basic",
   "users" : ["myUser1"],
   "groups" : ["CUSTOMERS"]
}

This rule protects all resources that match the URI pattern /customers(/.*)? and are accessed with the HTTP method of PUT or POST with basic authentication. In this example, users must be either the user named myUser1 or be a member of the CUSTOMERS group.

You can configure an optional realm to be used by basic authentication as shown in the following example:

/config/security/realm="Secure Area"

If no realm is set, the default realm is Secure Area.

Best practices for configuring security rules

The recommended URI pattern is /<prefix>(/.*)?. For example, a pattern of /foo(/.*)? would match requests for /foo, /foo/ and /foo/bar/index.html. Using this pattern that is based on prefixes, prevents clients from circumventing security rules by adding pathInfo to the end of a request. Also, because of the default file serving behavior when a directory is accessed, if you want the default files protected, you need to be sure to protect the directory. For example, if you don't want /foo/index.html served, you should be sure to protect /foo/. This is accomplished using the prefix-based rules.

Authorizing URIs

For certain types of applications, you can group resources according to who owns them or global to any authenticated users. Securing such applications can be hard because you might not know user names and groups in advance and, even if you did, they might be too numerous to track manually. Project Zero enables authorizing URIs with user names or group names or all authenticated users.

Authorizing URIs for all authenticated users

You can create authorization rules to allow any authenticated user to access a protected resource. To enable this function, Zero provides a Group named 'ALL_AUTHENTICATED_USERS'. For example, the following rule will permit any authenticated user to access the resource that starts with /formauth/customers.

@include "security/rule.config"{
   "conditions": "/request/path =~ /formauth/customers(/.*)?",
   "authType" : "Form",
   "groups" : ["ALL_AUTHENTICATED_USERS"]
}

Authorizing URIs with user names

You can authorize URIs with user names. As an example, a file sharing service might give every user a URI like /resources/shares/{user}, where anything that comes after {user} is part of the user's file share. Securing such a service so that only the user can modify his shared resources can be handled in Project Zero by creating a relationship between the URI pattern and the list of authorized users. Project Zero has a special configuration variable, remoteUser, that can be added to URI patterns to indicate that only the authenticated user whose name matches the URI token can perform certain operations. For example, we can limit write operations on our file sharing service as shown in the following example:

@include "security/rule.config"{
   "conditions": "(/request/path =~ /resources/shares/{remoteUser}) && (/request/method == [PUT|POST|DELETE])",
   "authType" : "Basic",
   "condition" : "urimatches"
}

With this rule in place, PUT, POST, and DELETE operations are only allowed if the value of {remoteUser} is equal to the name of the person who is making the request. If the resource in question is /resources/shares/joe/file1.txt, then only code acting on behalf of user joe can perform PUT operations on it.

Rules that use the {remoteUser} variable can allow access to other users as well. For example, if we want our site administrator to be able to delete any shared file, we can update the rule as shown in the following example:

@include "security/rule.config"{
   "conditions": "(/request/path == /resources/shares/{remoteUser}) && (/request/method == [PUT|POST])",
   "authType" : "Basic",
}

@include "security/rule.config"{
   "conditions": "(/request/path == /resources/shares/{remoteUser} ) &&  (/request/method == DELETE)",
   "authType" : "Basic",
   "users": ["admin"]
}

Authorizing URIs with group names

Just as you can incorporate user names into your URIs to ease the configuration of user-owned resources, you can also include a group name for group-owned resources. All of the semantics of the Authorizing URIs with user names section can be applied to groups. To do this, replace {remoteUser} with {remoteGroup}, and your authorization rule must contain a groups property that contains the list of authorized groups, as shown in the following example:

@include "security/rule.config"{
   "conditions": "/request/path == /resources/calendars/{remoteGroup}",
   "authType" : "Basic",
   "groups": ["newyork-team", "raleigh-team", "chicago-team"]
}

Retrieving user information

After Project Zero has verified the credentials, they are available in the request context as /request/subject Map exposed using the remote_user and groups keys as shown in the following examples in java and grooovy:

// java snippet
String remoteUser = GlobalContext.zget(Request.Subject.remoteUser);
java.util.List groupNames = GlobalContext.zget(Request.Subject.groups);

// groovy snippet
RemoteUser: <%=request.subject.remoteUser[] %>
Groups:  <%=request.subject.groups[] %>

This information is only available when accessing protected resources. If you want to be able to use this information when accessing non-protected resources you can store it in the user's session.

Requiring SSL

To require HTTPS access to a resource, create a requireSSL=true rule. For example, the following rule protects the resource with basic authentication while also requiring the connection to be SSL:
@include "security/rule.config"{
   "conditions": "/request/path =~ /employees(/.*)?",
   "authType" : "Basic",
   "requireSSL" : true
}

The SSL requirement can be combined with requirements for authentication, authorization or both by adding the requireSSL=true line to any stanza. It can also be used where there are no other security requirements. For example, the same resource in the previous example can be designated as requiring SSL but not be protected as shown in the following example:

@include "security/requireSSL.config"{
   "conditions" : "/request/path =~/employees(/.*)?",
   "requireSSL": true
}

If a resource that requires SSL access is accessed without it, a 403 (Access Forbidden) status code is returned to the client.

Caching of secured resources

In an effort to limit the caching of secured resources on the client, Zero security sets the Cache-Control header for all secured resources and their associated login forms (OpenID, Form-based Login, Single Sign-On) that are provided as part of the Zero security model.

The default Cache-Control header value is "must-revalidate","max-age=0","private". To override this default setting, the following zero configuration is provided with the example demonstrating the default Cache-Control value.

# max-age/must-revalidate can be dropped if there are only 1.1 
# caches as it would improve cacheability
/config/security/cacheControl = ["must-revalidate","max-age=0","private"]

HELP Note Custom security handlers that override the secure event or provide a custom security implementation for obtaining a user's credentials will need to handle the Cache-Control header themselves. To add this Cache-Control header programmatically, the following API is provided.

zero.core.security.TokenService.setCacheControlHeader();

Using roles

HELP Advanced Topic Use of roles is an advanced topic and should not be required for most applications.

By including role based authorization, Project Zero provides a method for developers to specify which roles can access specific resources. For example, you could provide access only to users where the users role consists of users from the groups developers, sysadmins, and testers.

To enable role based authentication requires the specification of roles to users or groups or both. For example, for development purposes, you could include the following lines in the application configuration:

# developmentRoles.config
/config/security/roles/ADMIN/users=["testUser"]

When in production, you might want to enable the productionRoles.config as shown in the following example:

# productionRoles.config
/config/security/roles/ADMIN/groups=["ROOT"]

The following example shows how to leverage roles for authorization:

@include "developmentRoles.config"

#Authorization rules
@include "security/rule.config"{
   "conditions": "/request/path =~formauth/adminRoleOnly(/.*)?",
   "authType" : "Form",
   "roles" : ["ADMIN"]
}

After a user has successfully authenticated for the REST resource /formauth/adminRoleOnly(/.*)?, the global context is updated to reflect not only the remote user (remoteUser) and groups for the current subject but also the set of roles of which this user is a member. The following examples in java and groovy filters users based on whether the user is part of a role:

// java snippet
boolean isUserInAdminRole = 
GlobalContext.zget(Request.Subject.roles).contains("ADMIN");

// groovy snippet
boolean isUserInAdminRole = request.subject.roles[].contains("ADMIN");

r18 - 04 Mar 2008 - 21:41:31 - steveims
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site