blob: 5b38eb5ded02f9572860569f4745888e2d726b35 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JAAS Support</title><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><meta name="keywords" content="jetty, servlet, servlet-api, cometd, http, websocket, eclipse, maven, java, server, software"><link rel="home" href="index.html" title="Jetty : The Definitive Reference"><link rel="up" href="configuring-security.html" title="Chapter&nbsp;7.&nbsp;Configuring Security"><link rel="prev" href="configuring-security-secure-passwords.html" title="Secure Password Obfuscation"><link rel="next" href="spnego-support.html" title="Spnego Support"><link xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" rel="shortcut icon" href="images/favicon.ico"><script type="text/javascript" src="js/shCore.js"></script><script type="text/javascript" src="js/shBrushJava.js"></script><script type="text/javascript" src="js/shBrushXml.js"></script><script type="text/javascript" src="js/shBrushBash.js"></script><script type="text/javascript" src="js/shBrushJScript.js"></script><script type="text/javascript" src="js/shBrushSql.js"></script><script type="text/javascript" src="js/shBrushProperties.js"></script><script type="text/javascript" src="js/shBrushPlain.js"></script><link type="text/css" rel="stylesheet" href="css/shCore.css"><link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css"><link type="text/css" rel="stylesheet" href="css/font-awesome.min.css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><tr><td style="width: 25%"><a href="http://www.eclipse.org/jetty"><img src="images/jetty-header-logo.png" alt="Jetty Logo"></a><br><span style="font-size: small">
Version: 9.3.0.v20150612</span></td><td style="width: 50%"><script type="text/javascript"> (function() {
var cx = '016459005284625897022:obd4lsai2ds';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script><gcse:search></gcse:search></td></tr></table><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">JAAS Support</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="configuring-security-secure-passwords.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;7.&nbsp;Configuring Security<br><a accesskey="p" href="index.html"><i class="icon-home"></i> Home</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="spnego-support.html">Next <i class="icon-chevron-right"></i></a></td></tr></table><hr></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="jetty-callout"><h5 class="callout"><a href="http://www.webtide.com/">Contact the core Jetty developers at
<span class="website">www.webtide.com</span></a></h5><p>
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
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jaas-support"></a>JAAS Support</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="jaas-support.html#jetty-jaas">Jetty and JAAS</a></span></dt><dt><span class="section"><a href="jaas-support.html#jaas-configuration">Configuration</a></span></dt><dt><span class="section"><a href="jaas-support.html#d0e6146">A Closer Look at JAASLoginService</a></span></dt><dt><span class="section"><a href="jaas-support.html#d0e6325">Writing your Own LoginModule</a></span></dt><dt><span class="section"><a href="jaas-support.html#d0e6354">Other Goodies</a></span></dt></dl></div><p>JAAS implements a Java version of the standard Pluggable
Authentication Module (PAM) framework.</p><p>JAAS can be used for two purposes:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>for authentication of users, to reliably and securely determine
who is currently executing Java code, regardless of whether the code is
running as an application, an applet, a bean, or a servlet; and</p></li><li class="listitem"><p>for authorization of users to ensure they have the access control
rights (permissions) required to do the actions performed.</p></li></ul></div><p>JAAS authentication is performed in a pluggable fashion. This permits
applications to remain independent from underlying authentication
technologies. New or updated authentication technologies can be plugged
under an application without requiring modifications to the application
itself. Applications enable the authentication process by instantiating a
LoginContext object, which in turn references a Configuration to determine
the authentication technology(ies), or LoginModule(s), to be used in
performing the authentication. Typical LoginModules may prompt for and
verify a username and password. Others may read and verify a voice or
fingerprint sample.</p><p>See Java Authentication and Authorization Service (JAAS) <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html" target="_top">Reference
Guide</a> for more information about JAAS.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="jetty-jaas"></a>Jetty and JAAS</h3></div></div></div><p>Many application servers support JAAS as a means of bringing greater
flexibility to the declarative security models of the J2EE (now known as
the JavaEE) <a class="link" href="http://java.sun.com/javaee/index.jsp" target="_top">specification</a>. Jetty
support for JAAS provides greater alternatives for servlet security, and
increases the portability of web applications.</p><p>The JAAS support aims to dictate as little as possible whilst
providing a sufficiently flexible infrastructure to allow users to drop in
their own custom <a class="link" href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html" target="_top">LoginModules</a>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="jaas-configuration"></a>Configuration</h3></div></div></div><p>Using JAAS with jetty is very simply a matter of declaring a
<code class="code">org.eclipse.jetty.jaas.JAASLoginService</code>, creating a jaas
login module configuration file and specifying it on the jetty run line.
Let's look at an example.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6015"></a>Step 1</h4></div></div></div><p>Configure a jetty <code class="code"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/JAASLoginService.html" target="_top">org.eclipse.jetty.jaas.JAASLoginService</a></code>
to match the &lt;realm-name&gt; in your web.xml file. For example, if
the <code class="filename">web.xml</code> contains a realm called "xyz" like
so:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[<login-config>
<auth-method>FORM</auth-method>
<realm-name>xyz</realm-name>
<form-login-config>
<form-login-page>/login/login</form-login-page>
<form-error-page>/login/error</form-error-page>
</form-login-config>
</login-config>]]>
</script></div><p>Then you need to create a JAASLoginService with the matching name
of "xyz":</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="Name">Test JAAS Realm</Set>
<Set name="LoginModuleName">xyz</Set>
</New>]]>
</script></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><i class="icon-exclamation-sign"></i> Caution</h3><p>The name of the realm-name that you declare in
<code class="filename">web.xml</code> must match exactly the name of your
JAASLoginService.</p></div><p>You can declare your JAASLoginService in a couple of different
ways:</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>If you have more than one webapp that you would like to use
the same security infrastructure, then you can declare your
JAASLoginService in a top-level jetty xml file as a bean that is
added to the org.eclipse.jetty.server.Server. Here's an
example:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="name">Test JAAS Realm</Set>
<Set name="LoginModuleName">xyz</Set>
</New>
</Arg>
</Call>
</Configure>]]>
</script></div></li><li class="listitem"><p>Alternatively, you can use a JAASLoginService with just a
specific webapp by creating a <a class="link" href="configuring-specific-webapp-deployment.html#deployable-descriptor-file" title="Jetty Deployable Descriptor XML File">context xml</a> file for the
webapp, and specifying the JAASLoginService in it:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="securityHandler">
<New class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<Set name="loginService">
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="name">Test JAAS Realm</Set>
<Set name="loginModuleName">xyz</Set>
</New>
</Set>
</New>
</Set>
</Configure>]]>
</script></div></li></ol></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="jaas-step-2"></a>Step 2</h4></div></div></div><p>Set up your <code class="code">LoginModule</code> in a configuration file,
following the <a class="link" href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html" target="_top">syntax
rules</a> :</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[xyz {
com.acme.SomeLoginModule required debug=true;
};]]>
</script></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><i class="icon-exclamation-sign"></i> Caution</h3><p>It is imperative that the application name on the first line is
exactly the same as the <code class="code">LoginModuleName</code> of your
JAASLoginService.</p></div><p>You may find it convenient to name this configuration file as
<code class="filename">etc/login.conf</code> because, as we will see below, some
of the wiring up for jaas has been done for you.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6084"></a>Step 3</h4></div></div></div><p>You now need to invoke jetty with support for jaas. There are 2
aspects to this:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>adding jaas-related jars to the jetty container
classpath</p></li><li class="listitem"><p>setting the System property
<code class="code">java.security.auth.login.config</code></p></li></ul></div><p>To accomplish the above, use the jetty <a class="link" href="startup.html#startup-overview" title="Startup Overview">startup</a> <a class="link" href="startup-modules.html" title="Managing Startup Modules">modules mechanism</a> to add the jaas <a class="link" href="startup-modules.html" title="Managing Startup Modules">module</a>:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: bash;toolbar: false">
<![CDATA[java -jar start.jar --add-to-startd=jaas]]>
</script></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><i class="icon-asterisk"></i> Note</h3><p>The top level of the distribution does not have the jaas module
enabled by default. However, there are several <a class="link" href="quickstart-running-jetty.html#demo-webapps-base" title="Demo Base">demo webapps</a> - including a jaas
webapp - available in the <code class="filename"><a class="link" href="startup-base-and-home.html" title="Managing Jetty Base and Jetty Home">demo-base</a></code> directory
of the distribution which has pre-enabled the jaas module.</p></div><p>Now you will have a file named
<code class="filename">start.d/jaas.ini</code>, which contains:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[--module=jaas
jaas.login.conf=etc/login.conf]]>
</script></div><p>The <code class="code">jaas.login.conf</code> property refers to the location
of your LoginModule configuration file that you established in <a class="link" href="jaas-support.html#jaas-step-2" title="Step 2">Step 2</a>. If you called it
<code class="filename">etc/login.conf</code>, then your work is done. Otherwise,
change the value of the<code class="code"> jaas.login.conf</code> property to be the
location of your LoginModule configuration file. Jetty will
automatically use this property to set the value of the System property
<code class="code">java.security.auth.login.config.</code></p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6146"></a>A Closer Look at JAASLoginService</h3></div></div></div><p>To allow the greatest degree of flexibility in using JAAS with web
applications, the <code class="classname">JAASLoginService</code> supports a
couple of configuration options. Note that you don't ordinarily need to
set these explicitly, as jetty has defaults which will work in 99% of
cases. However, should you need to, you can configure:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>a policy for role-based authorization (Default:
<code class="classname">o<a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/StrictRoleCheckPolicy.html" target="_top">rg.eclipse.jetty.jaas.StrictRoleCheckPolicy</a></code>)</p></li><li class="listitem"><p>a CallbackHandler (Default: <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.html" target="_top">org.eclipse.jetty.jaas.callback.DefaultCallbackHandler</a></code>)</p></li><li class="listitem"><p>a list of classnames for the Principal implementation that
equate to a user role (Default: <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/JAASRole.html" target="_top">org.eclipse.jetty.jaas.JAASRole</a></code>)</p></li></ul></div><p>Here's an example of setting each of these (to their default
values):</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="Name">Test JAAS Realm</Set>
<Set name="LoginModuleName">xyz</Set>
<Set name="RoleCheckPolicy">
<New class="org.eclipse.jetty.jaas.StrictRoleCheckPolicy"/>
</Set>
<Set name="CallbackHandlerClass">
org.eclipse.jetty.jaas.callback.DefaultCallbackHandler
</Set>
<Set name="roleClassNames">
<Array type="java.lang.String">
<Item>org.eclipse.jetty.jaas.JAASRole</Item>
</Array>
</Set>
</New>
]]>
</script></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6182"></a>RoleCheckPolicy</h4></div></div></div><p>The RoleCheckPolicy must be an implementation of the
<code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/RoleCheckPolicy.html" target="_top">org.eclipse.jetty.jaas.RoleCheckPolicy</a></code>
interface and its purpose is to help answer the question "is User X in
Role Y" for role-based authorization requests. The default
implementation distributed with jetty is the <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/StrictRoleCheckPolicy.html" target="_top">org.eclipse.jetty.jaas.StrictRoleCheckPolicy</a></code>,
which will assess a user as having a particular role iff that role is at
the top of the stack of roles that have been temporarily pushed onto the
user or if the user has no temporarily assigned roles, the role is
amongst those configured for the user.</p><p>Roles can be temporarily assigned to a user programmatically by
using the pushRole(String rolename) method of the <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/JAASUserPrincipal.html" target="_top">org.eclipse.jetty.jaas.JAASUserPrincipal</a></code>
class.</p><p>For the majority of webapps, the default StrictRoleCheckPolicy
will be quite adequate, however you may provide your own implementation
and set it on your JAASLoginService instance.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6203"></a>CallbackHandler</h4></div></div></div><p>A CallbackHandler is responsible for interfacing with the user to
obtain usernames and credentials to be authenticated.</p><p>Jetty ships with the <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.html" target="_top">org.eclipse.jetty.jaas.DefaultCallbackHandler</a></code>
which interfaces the information contained in the request to the
Callbacks that are requested by LoginModules. You can replace this
default with your own implementation if you have specific requirements
not covered by the default.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6214"></a>Role Principal Implementation Class</h4></div></div></div><p>When LoginModules authenticate a user, they usually also gather
all of the roles that a user has and place them inside the JAAS Subject.
As LoginModules are free to use their own implementation of the JAAS
Principal to put into the Subject, jetty needs to know which Principals
represent the user and which represent his/her roles when performing
authorization checks on &lt;security-constraint&gt;s. The example
LoginModules that ship with jetty all use the
<code class="classname">org.eclipse.jetty.jaas.JAASRole</code> class. However,
if you have plugged in some other LoginModules, you must configure the
classnames of their role Principal implementations.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6222"></a>Sample LoginModules</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/JDBCLoginModule.html" target="_top"><code class="code">org.eclipse.jetty.jaas.spi.JDBCLoginModule</code></a></p></li><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.html" target="_top"><code class="code">org.eclipse.jetty.jaas.spi.PropertyFileLoginModule</code></a></p></li><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.html" target="_top"><code class="code">org.eclipse.jetty.jaas.spi.DataSourceLoginModule</code></a></p></li><li class="listitem"><p><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/LdapLoginModule.html" target="_top"><code class="code">org.eclipse.jetty.jaas.ldap.LdapLoginModule</code></a></p></li></ul></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><i class="icon-asterisk"></i> Passwords/Credentials</h3><p>Passwords can be stored in clear text, obfuscated or
checksummed. The class <a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/util/security/Password.html" target="_top"><code class="classname">org.eclipse.jetty.util.security.Password</code></a>
should be used to generate all varieties of passwords,the output from
which can be cut and pasted into property files or entered into
database tables.</p><p>See more on this
under the Configuration section on <a class="link" href="configuring-security-secure-passwords.html" title="Secure Password Obfuscation">securing
passwords</a>.</p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6260"></a>JDBCLoginModule</h4></div></div></div><p>The JDBCLoginModule stores user passwords and roles in a database
that are accessed via JDBC calls. You can configure the JDBC connection
information, as well as the names of the table and columns storing the
username and credential, and the name of the table and columns storing
the roles.</p><p>Here is an example login module configuration file entry for it
using an HSQLDB driver:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
jdbc {
org.eclipse.jetty.jaas.spi.JDBCLoginModule required
debug="true"
dbUrl="jdbc:hsqldb:."
dbUserName="sa"
dbDriver="org.hsqldb.jdbcDriver"
userTable="myusers"
userField="myuser"
credentialField="mypassword"
userRoleTable="myuserroles"
userRoleUserField="myuser"
userRoleRoleField="myrole";
};]]>
</script></div><p>There is no particular schema required for the database tables
storing the authentication and role information. The properties
userTable, userField, credentialField, userRoleTable, userRoleUserField,
userRoleRoleField configure the names of the tables and the columns
within them that are used to format the following queries:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">select &lt;credentialField&gt; from &lt;userTable&gt;
where &lt;userField&gt; =?</code></p></li><li class="listitem"><p><code class="code">select &lt;userRoleRoleField&gt; from
&lt;userRoleTable&gt; where &lt;userRoleUserField&gt;
=?</code></p></li></ul></div><p>Credential and role information is lazily read from the database
when a previously unauthenticated user requests authentication. Note
that this information is only cached for the length of the authenticated
session. When the user logs out or the session expires, the information
is flushed from memory.</p><p>Note that passwords can be stored in the database in plain text or
encoded formats - see "Passwords/Credentials" note above.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6285"></a>DataSourceLoginModule</h4></div></div></div><p>Similar to the JDBCLoginModule, but this LoginModule uses a
DataSource to connect to the database instead of a jdbc driver. The
DataSource is obtained by doing a jndi lookup on
<code class="code">java:comp/env/${dnJNDIName}</code></p><p>Here is a sample login module configuration for it:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
ds {
org.eclipse.jetty.jaas.spi.DataSourceLoginModule required
debug="true"
dbJNDIName="ds"
userTable="myusers"
userField="myuser"
credentialField="mypassword"
userRoleTable="myuserroles"
userRoleUserField="myuser"
userRoleRoleField="myrole";
};
]]>
</script></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6297"></a>PropertyFileLoginModule</h4></div></div></div><p>With this login module implementation, the authentication and role
information is read from a property file.</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
props {
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
debug="true"
file="/somewhere/somefile.props";
};
]]>
</script></div><p>The file parameter is the location of a properties file of the
same format as the etc/realm.properties example file. The format
is:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
<username>: <password>[,<rolename> ...]
]]>
</script></div><p>Here's an example:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
fred: OBF:1xmk1w261u9r1w1c1xmq,user,admin
harry: changeme,user,developer
tom: MD5:164c88b302622e17050af52c89945d44,user
dick: CRYPT:adpexzg3FUZAk,admin
]]>
</script></div><p>The contents of the file are fully read in and cached in memory
the first time a user requests authentication.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6317"></a>LdapLoginModule</h4></div></div></div><p>Here's an example:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: plain;toolbar: false">
<![CDATA[
ldaploginmodule {
org.eclipse.jetty.jaas.spi.LdapLoginModule required
debug="true"
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
hostname="ldap.example.com"
port="389"
bindDn="cn=Directory Manager"
bindPassword="directory"
authenticationMethod="simple"
forceBindingLogin="false"
userBaseDn="ou=people,dc=alcatel"
userRdnAttribute="uid"
userIdAttribute="uid"
userPasswordAttribute="userPassword"
userObjectClass="inetOrgPerson"
roleBaseDn="ou=groups,dc=example,dc=com"
roleNameAttribute="cn"
roleMemberAttribute="uniqueMember"
roleObjectClass="groupOfUniqueNames";
};
]]>
</script></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6325"></a>Writing your Own LoginModule</h3></div></div></div><p>If you want to implement your own custom LoginModule, there are two
classes to be familiar with <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/AbstractLoginModule.html" target="_top">org.eclipse.jetty.jaas.spi.AbstractLoginModule</a></code>
and <code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/jaas/spi/UserInfo.html" target="_top">org.eclipse.jetty.jaas.spi.UserInfo</a></code>.</p><p>The
<code class="classname">org.eclipse.jetty.jaas.spi.AbstractLoginModule</code>
implements all of the
<code class="classname">javax.security.auth.spi.LoginModule</code> methods. All
you need to do is to implement the getUserInfo method to return a
<code class="classname">org.eclipse.jetty.jaas.UserInfo</code> instance which
encapsulates the username, password and role names (note: as
java.lang.Strings) for a user.</p><p>The AbstractLoginModule does not support any caching, so if you want
to cache UserInfo (eg as does the
<code class="classname">org.eclipse.jetty.jaas.spi.PropertyFileLoginModule</code>)
then you must provide this yourself.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6354"></a>Other Goodies</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6357"></a>RequestParameterCallback</h4></div></div></div><p>As all servlet containers intercept and process a form submission
with action j_security_check, it is usually not possible to insert any
extra input fields onto a login form with which to perform
authentication: you may only pass <code class="code">j_username</code> and
<code class="code">j_password</code>. For those rare occasions when this is not good
enough, and you require more information from the user in order to
authenticate them, you can use the JAAS callback handler
<code class="classname"><a class="link" href="http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/jaas/callback/RequestParameterCallback.html" target="_top">org.eclipse.jetty.jaas.callback.RequestParameterCallback</a></code>.
This callback handler gives you access to all parameters that were
passed in the form submission. To use it, in the login() method of your
custom login module, add the RequestParameterCallback to the list of
callback handlers the login module uses, tell it which params you are
interested in, and then get the value of the parameter back. Here's an
example:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[
public class FooLoginModule extends AbstractLoginModule
{
public boolean login()
throws LoginException
{
Callback[] callbacks = new Callback[3];
callbacks[0] = new NameCallback();
callbacks[1] = new ObjectCallback();
//as an example, look for a param named "extrainfo" in the request
//use one RequestParameterCallback() instance for each param you want to access
callbacks[2] = new RequestParameterCallback ();
((RequestParameterCallback)callbacks[2]).setParameterName ("extrainfo");
callbackHandler.handle(callbacks);
String userName = ((NameCallback)callbacks[0]).getName();
Object pwd = ((ObjectCallback)callbacks[1]).getObject();
List paramValues = ((RequestParameterCallback)callbacks[2]).getParameterValues();
//use the userName, pwd and the value(s) of the parameter named "extrainfo" to
//authenticate the user
}
]]>
</script></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6375"></a>Example JAAS WebApp</h4></div></div></div><p>An example webapp using jaas can be found in our git repo:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><a class="link" href="http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/tests/test-webapps/test-jaas-webapp" target="_top">http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/tests/test-webapps/test-jaas-webapp</a></p></li></ul></div></div></div></div><script type="text/javascript">
SyntaxHighlighter.all()
</script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="configuring-security-secure-passwords.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="configuring-security.html"><i class="icon-chevron-up"></i> Top</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="spnego-support.html">Next <i class="icon-chevron-right"></i></a></td></tr><tr><td width="40%" align="left" valign="top">Secure Password Obfuscation&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html"><i class="icon-home"></i> Home</a></td><td width="40%" align="right" valign="top">&nbsp;Spnego Support</td></tr></table></div><p xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><div class="jetty-callout">
See an error or something missing?
<span class="callout"><a href="http://github.com/jetty-project/jetty-documentation">Contribute to this documentation at
<span class="website"><i class="icon-github"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2015-06-15T13:18:16-05:00)</i></span></div></p><script xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1149868-7']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script></body></html>