Jetty Logo
Version: 9.1.3-SNAPSHOT
Contact the core Jetty developers at www.webtide.com

private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery

Authentication

Configuring an Authentication mechanism
Security Realms
Scoping Security Realms
Configuring a LoginService
Authorization

There are two aspects to securing a web application(or context) within the Jetty server:

Authentication

The web application can be configured with a mechanism to determine the identity of the user. This is configured by a mix of standard declarations and jetty specific mechanisms and is covered in this section.

Authorization

Once the identify of the user is known (or not known), the web application can be configured via standard descriptors with security constraints that declare what resources that user may access.

Configuring an Authentication mechanism

The jetty server supports several standard authentication mechanisms: BASIC; DIGEST; FORM; CLIENT-CERT; and other mechanisms can be plugged in using the extensible JASPI or SPNEGO mechanisms.

Internally, configurating an authentication mechanism is done by setting an instance of a the Authenticator interface onto the SecurityHandler of the context, but in most cases it is done by declaring a < login-config> element in the standard web.xml descriptor or via annotations.

Below is an example taken from the jetty-test-webapp web.xml that configures BASIC authentication:

The jetty-test-webapp web.xml also includes commented out examples of other DIGEST and FORM configuration:

With FORM Authentication, you must also configure URLs of pages to generate a login form and handle errors. Below is a simple HTML form from the test webapp logon.html:

The Authentication mechanism declared for a context / web application defines how the server obtain authentication credentials from the client, but it does not define how the server checks if those credentials are valid. To check credentials, the server and/or context also need to be configured with a LoginService instance, which may be matched by the declared realm-name.

Security Realms

Security realms allow you to secure your web applications against unauthorized access. Protection is based on authentication that identifies who is requesting access to the webapp and access control that restricts what can be accessed and how it is accessed within the webapp.

A webapp statically declares its security requirements in its web.xml file. Authentication is controlled by the <login-config> element. Access controls are specified by <security-constraint> and <security-role-ref> elements. When a request is received for a protected resource, the web container checks if the user performing the request is authenticated, and if the user has a role assignment that permits access to the requested resource.

The Servlet Specification does not address how the static security information in the WEB-INF/web.xml file is mapped to the runtime environment of the container. For Jetty, the LoginService performs this function.

A LoginService has a unique name, and gives access to information about a set of users. Each user has authentication information (e.g. a password) and a set of roles associated with him/herself.

You may configure one or many different LoginServices depending on your needs. A single realm would indicate that you wish to share common security information across all of your web applications. Distinct realms allow you to partition your security information webapp by webapp.

When a request to a web application requires authentication or authorization, Jetty will use the <realm-name> sub-element inside <login-config> element in the web.xml file to perform an exact match to a LoginService.

Scoping Security Realms

A LoginService has a unique name, and is composed of a set of users. Each user has authentication information (for example, a password) and a set of roles associated with him/herself. You can configure one or many different realms depending on your needs.

  • Configure a single LoginService to share common security information across all of your web applications.

  • Configure distinct LoginServices to partition your security information webapp by webapp.

Globally Scoped

A LoginService is available to all web applications on a Server instance if you define it in a Jetty configuration file, for example ${jetty.home}/etc/jetty.xml. Here's an example of defining an in-memory type of LoginService called the HashLoginService:

If you define more than one LoginService on a Server, you will need to specify which one you want used for each context. You can do that by telling the context the name of the LoginService, or passing it the LoginService instance. Here's an example of doing both of these, using a context xml file:

Per-Webapp Scoped

Alternatively, you can define a LoginService for just a single web application. Here's how to define the same HashLoginService, but inside a context xml file:

Jetty provides a number of different LoginService types which can be seen in the next section.

Configuring a LoginService

A LoginService instance is required by each context/webapp that has a authentication mechanism, which is used to check the validity of the username and credentials collected by the authentication mechanism. Jetty provides the following implementations of LoginService:

HashLoginService

A user realm that is backed by a hash map that is filled either programatically or from a java properties file.

JDBCLoginService

Uses a JDBC connection to an SQL database for authentication

DataSourceLoginService

Uses a JNDI defined DataSource for authentication

JAASLoginService

Uses a JAAS provider for authentication, See the section on JAAS support for more information.

SpnegoLoginService

SPNEGO Authentication, See the section on SPNEGO support for more information.

An instance of a LoginService can be matched to a context/webapp either by:

  • A LoginService instance may be set directly on the SecurityHandler instance via embedded code or IoC XML

  • Matching the realm-name defined in web.xml with the name of a LoginService instance that has been added to the Server instance as a dependent bean.

  • If only a single LoginService instance has been set on the Server then it is used as the login service for the context.

HashLoginService

The HashLoginService is a simple and efficient login service that loads usernames, credentials and roles from a java properties file in the format:

where:

username

is the user's unique identity

password

is the user's (possibly obfuscated or MD5 encrypted) password;

rolename

is a role of the user

For example:

You configure the HashLoginService with a name and a reference to the location of the properties file:

You can also configure it to check the properties file regularly for changes and reload when changes are detected. The reloadInterval is in seconds:

JDBCLoginService

In this implementation, authentication and role information is stored in a database accessed via JDBC. A properties file defines the JDBC connection and database table information. Here is an example of a properties file for this realm implementation:

The format of the database tables is (pseudo-sql):

Where:

  • users is a table containing one entry for every user consisting of:

    id

    the unique identity of a user

    user

    the name of the user

    pwd

    the user's password (possibily obfuscated or MD5 encrypted)

  • user-roles is a table containing one row for every role granted to a user:

    user_id

    the unique identity of the user

    role_id

    the role for a user

  • roles is a a table containing one role for every role in the system:

    id

    the unique identifier of a role

    role

    a human-readable name for a role

If you want to use obfuscated, MD5 hashed or encrypted passwords the 'pwd' column of the 'users' table must be large enough to hold the obfuscated, hashed or encrypted password text plus the appropriate prefix.

You define a JDBCLoginService with the name of the realm and the location of the properties file describing the database:

Authorization

As far as the Servlet Specification is concerned, authorization is based on roles. As we have seen, a LoginService associates a user with a set of roles. When a user requests a resource that is access protected, the LoginService will be asked to authenticate the user if they are not already, and then asked to confirm if that user possesses one of the roles permitted access to the resource.

Until Servlet 3.1, role-based authorization could define:

  • access granted to a set of named roles

  • access totally forbidden, regardless of role

  • access granted to a user in any of the roles defined in the effective web.xml. This is indicated by the special value of "*" for the <role-name> of a <auth-constraint> in the <security-constraint>

With the advent of Servlet 3.1, there is now another authorization:

  • access granted to any user who is authenticated, regardless of roles. This is indicated by the special value of "**" for the <role-name> of a <auth-constraint> in the <security-constraint>

See an error or something missing? Contribute to this documentation at Github!(Generated: 2014-04-15T11:43:39-05:00)