Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Jetty/Tutorial/Realms"

m
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{Jetty Tutorial
 
{{Jetty Tutorial
| introduction = (required)
+
| introduction =
| details =
+
This tutorial describes how to configure security realms to provide authentication and access control for web applications running in Jetty. A realm has a unique name, and is composed of 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 realms 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.
+
This tutorial describes how to configure security realms to provide authentication and access control for web applications running in Jetty. A realm 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 realm to share common security information across all of your web applications.  
 +
* Configure distinct realms to partition your security information webapp by webapp.
  
Realm definitions in Jetty configuration files are placed in a section like this:
+
| details =
 +
 
 +
A realm–known as 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'' (note in Jetty 6 this was called the ''HashUserRealm''):
  
 
<source lang="xml">
 
<source lang="xml">
<Set name="UserRealms">
+
<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <Array type="org.eclipse.jetty.security.UserRealm">
+
    <Item>
+
      ...
+
    </Item>
+
    <Item>
+
    ...
+
    </Item>
+
  
     ...
+
     <Call name="addBean">
 +
      <Arg>
 +
        <New class="org.eclipse.jetty.security.HashLoginService">
 +
          <Set name="name">Test Realm</Set>
 +
          <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
 +
          <Set name="refreshInterval">0</Set>
 +
        </New>
 +
      </Arg>
 +
    </Call>
  
  </Array>
+
 
</Set>
+
</Configure>
 
</source>
 
</source>
  
Alternatively, you may define a realm for just a single webapp in a ContextDeployer file:
+
Alternatively, you can define a LoginService for just a single web application in a context file. Here's how to define the same HashLoginService, but inside
 +
a context xml file instead of a configuration file:
 +
 
 
<source lang="xml">
 
<source lang="xml">
 
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 
   <Set name="contextPath">/test</Set>
 
   <Set name="contextPath">/test</Set>
 
   <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
 
   <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
    ...
+
 
 
   <Get name="securityHandler">
 
   <Get name="securityHandler">
     <Set name="userRealm">
+
     <Set name="loginService">
       <New class="org.eclipse.jetty.security.HashUserRealm">
+
       <New class="org.eclipse.jetty.security.HashLoginService">
 
             <Set name="name">Test Realm</Set>
 
             <Set name="name">Test Realm</Set>
 
             <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
 
             <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
Line 38: Line 43:
 
     </Set>
 
     </Set>
 
   </Get>
 
   </Get>
 +
 
</Configure>
 
</Configure>
 
</source>
 
</source>
  
Jetty provides a number of different realm types from which you can choose.
+
Jetty provides a number of different LoginService types from which you can choose.
  
=== HashUserRealm ===
+
=== HashLoginService ===
  
This realm is a simple realm whose authentication and authorization information is stored in a properties file. Each line in the file contains a username, a password, and 0 or more role assignments. The format is:
+
This LoginService is a simple realm whose authentication and authorization information is stored in a properties file. Each line in the file contains a username, a password, and zero or more role assignments. The format is:
 
  username: password[,rolename ...]
 
  username: password[,rolename ...]
  
Line 58: Line 64:
 
  guest: guest,read-only
 
  guest: guest,read-only
  
The HashUserRealm is configured with a name and a reference to the location of the properties file:
+
You configure the HashLoginService with a name and a reference to the location of the properties file:
 
<source lang="xml">
 
<source lang="xml">
 
<Item>
 
<Item>
   <New class="org.eclipse.jetty.security.HashUserRealm">
+
   <New class="org.eclipse.jetty.security.HashLoginService">
 
     <Set name="name">Test Realm</Set>
 
     <Set name="name">Test Realm</Set>
 
     <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
 
     <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
Line 70: Line 76:
 
are detected. The reloadInterval is in seconds:
 
are detected. The reloadInterval is in seconds:
 
<source lang="xml">
 
<source lang="xml">
<Item>
+
 
   <New class="org.mortbay.jetty.security.HashUserRealm">
+
   <New class="org.eclipse.jetty.security.HashLoginService">
 
     <Set name="name">Test Realm</Set>
 
     <Set name="name">Test Realm</Set>
 
     <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
 
     <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
Line 77: Line 83:
 
     <Call name="start"></Call>
 
     <Call name="start"></Call>
 
   </New>
 
   </New>
</Item>
+
 
 
</source>
 
</source>
  
=== JDBCUserRealm ===
+
=== 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. Below is an example of a properties file for this realm implementation:
+
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:
  
 
<source lang="ini">
 
<source lang="ini">
Line 102: Line 108:
 
</source>
 
</source>
  
The format of the database tables is:
+
The format of the database tables is (pseudo-sql):
  
{| class="wikitable" border="1"
 
|-
 
! users
 
|-
 
| id
 
|-
 
| user
 
|-
 
| pwd
 
|}
 
 
{| class="wikitable" border="1"
 
|-
 
! user_roles
 
|-
 
| user_id
 
|-
 
| role_id
 
|}
 
 
{| border="1"
 
|- style="background-color:#ffffcc; font-style:bold"
 
! roles
 
|-
 
| id
 
|-
 
| role
 
|}
 
 
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''' is the unique identifier of a role
 
** '''role''' is 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.
 
 
The pseudo-sql to set up each of these tables would look like:
 
 
==== users ====
 
 
<source lang="sql">
 
<source lang="sql">
 +
users
 
(
 
(
 
   id integer primary key,
 
   id integer primary key,
Line 160: Line 119:
 
</source>
 
</source>
  
==== user_roles ====
 
 
<source lang="sql">
 
<source lang="sql">
 +
user_roles
 
(
 
(
 
   user_id integer not null,
 
   user_id integer not null,
Line 170: Line 129:
 
</source>
 
</source>
  
==== roles ====
 
 
<source lang="sql">
 
<source lang="sql">
 +
roles
 
(
 
(
 
   id integer primary key,
 
   id integer primary key,
Line 178: Line 137:
 
</source>
 
</source>
  
A JDBCRealm is defined with the name of the realm and the location of the properties file describing the database:
+
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:
 
<source lang="xml">
 
<source lang="xml">
<Item>
+
<New class="org.eclipse.jetty.security.JDBCLoginService">
  <New class="org.eclipse.jetty.security.JDBCUserRealm">
+
 
   <Set name="name">Test JDBC Realm</Set>
 
   <Set name="name">Test JDBC Realm</Set>
 
   <Set name="config">etc/jdbcRealm.properties</Set>
 
   <Set name="config">etc/jdbcRealm.properties</Set>
  </New>
+
</New>
</Item>
+
 
</source>
 
</source>
 +
 +
== Assigning Realms ==
 +
 +
You need to explicitly tell a context which realm (LoginService) to use if you have defined more than one in the Server.
 +
 +
# Configure realms on the server.
 +
# Give the SecurityHandler for a context either the name of the realm you want to use, or give it the actual LoginService.
 +
 +
For example:
 +
 +
<source lang="xml">
 +
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 +
<Get name="securityHandler">
 +
  <!-- Either: -->
 +
  <Set name="loginService">
 +
    <New class="org.eclipse.jetty.security.HashLoginService">
 +
          <Set name="name">Test Realm</Set>
 +
    </New>
 +
  </Set>
 +
 +
  <!-- or if you defined a LoginService called "Test Realm" in jetty.xml : -->
 +
  <Set name="realmName">Test Realm</Set>
 +
 +
</Get>
 +
</source>
 +
 
| more =
 
| more =
  
See the page on [[Jetty/Feature/JAAS|JAAS authentication and authorization]] with Jetty.
+
See [[Jetty/Tutorial/JAAS|Java Authentication and Authorization Service (JAAS)]] tutorial for additional information about configuring security realms.
 
| category = [[Category:Jetty Tutorial]]
 
| category = [[Category:Jetty Tutorial]]
 
}}
 
}}

Latest revision as of 15:02, 1 March 2012



Introduction

This tutorial describes how to configure security realms to provide authentication and access control for web applications running in Jetty. A realm 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 realm to share common security information across all of your web applications.
  • Configure distinct realms to partition your security information webapp by webapp.

Details

A realm–known as 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 (note in Jetty 6 this was called the HashUserRealm):

<Configure id="Server" class="org.eclipse.jetty.server.Server">
 
    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.security.HashLoginService">
          <Set name="name">Test Realm</Set>
          <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
          <Set name="refreshInterval">0</Set>
        </New>
      </Arg>
    </Call>
 
 
</Configure>

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

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/test</Set>
  <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
 
  <Get name="securityHandler">
    <Set name="loginService">
      <New class="org.eclipse.jetty.security.HashLoginService">
            <Set name="name">Test Realm</Set>
            <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
      </New>
    </Set>
  </Get>
 
</Configure>

Jetty provides a number of different LoginService types from which you can choose.

HashLoginService

This LoginService is a simple realm whose authentication and authorization information is stored in a properties file. Each line in the file contains a username, a password, and zero or more role assignments. The format is:

username: password[,rolename ...]

where:

  • username is the user's unique identity;
  • password is the user's (possibly obfuscated or MD5 encrypted) password;
  • rolename is the user's role.

For example:

admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
other: OBF:1xmk1w261u9r1w1c1xmq
guest: guest,read-only

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

<Item>
  <New class="org.eclipse.jetty.security.HashLoginService">
     <Set name="name">Test Realm</Set>
    <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
  </New>
</Item>

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

  <New class="org.eclipse.jetty.security.HashLoginService">
    <Set name="name">Test Realm</Set>
    <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
    <Set name="reloadInterval">5</Set>
    <Call name="start"></Call>
  </New>

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:

jdbcdriver = org.gjt.mm.mysql.Driver
url = jdbc:mysql://localhost/jetty
username = jetty
password = jetty
usertable = users
usertablekey = id
usertableuserfield = username
usertablepasswordfield = pwd
roletable = roles
roletablekey = id
roletablerolefield = role
userroletable = user_roles
userroletableuserkey = user_id
userroletablerolekey = role_id
cachetime = 300

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

users
(
  id INTEGER PRIMARY KEY,
  username VARCHAR(100) NOT NULL UNIQUE KEY,
  pwd VARCHAR(50) NOT NULL
);
user_roles
(
  user_id INTEGER NOT NULL,
  role_id INTEGER NOT NULL,
  UNIQUE KEY (user_id, role_id),
  INDEX(user_id)
);
roles
(
  id INTEGER PRIMARY KEY,
  ROLE VARCHAR(100) NOT NULL UNIQUE KEY
);

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:

<New class="org.eclipse.jetty.security.JDBCLoginService">
  <Set name="name">Test JDBC Realm</Set>
  <Set name="config">etc/jdbcRealm.properties</Set>
</New>

Assigning Realms

You need to explicitly tell a context which realm (LoginService) to use if you have defined more than one in the Server.

  1. Configure realms on the server.
  2. Give the SecurityHandler for a context either the name of the realm you want to use, or give it the actual LoginService.

For example:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 <Get name="securityHandler">
   <!-- Either: -->
   <Set name="loginService">
     <New class="org.eclipse.jetty.security.HashLoginService">
           <Set name="name">Test Realm</Set>
     </New>
   </Set>
 
   <!-- or if you defined a LoginService called "Test Realm" in jetty.xml : -->
   <Set name="realmName">Test Realm</Set>
 
 </Get>

Additional Resources

See Java Authentication and Authorization Service (JAAS) tutorial for additional information about configuring security realms.

Copyright © Eclipse Foundation, Inc. All Rights Reserved.