Merge remote-tracking branch 'origin/jetty-10.0.x' into jetty-11.0.x

This commit is contained in:
Joakim Erdfelt 2020-10-21 15:34:43 -05:00
commit 7bf4a007ce
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
5 changed files with 365 additions and 5 deletions

View File

@ -37,3 +37,4 @@ include::quickstart/chapter.adoc[]
include::annotations/chapter.adoc[]
include::jsp/chapter.adoc[]
include::jndi/chapter.adoc[]
include::jaas/chapter.adoc[]

View File

@ -31,10 +31,11 @@ If you know Eclipse Jetty already, jump to a feature:
* xref:og-sessions[HTTP Session Caching and Clustering]
* xref:og-protocols-http2[HTTP/2 Support]
* xref:og-quickstart[Faster Web Application Deployment]
* xref:og-annotations[Annotations]
* xref:og-jsp[JSP]
* xref:og-quickstart[Faster Web Application Deployment]
* xref:og-jaas[JAAS]
* xref:og-jndi[JNDI]
* xref:og-jsp[JSP]
TODO

View File

@ -0,0 +1,349 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
[[og-jaas]]
=== JAAS
JAAS implements a Java version of the standard Pluggable Authentication Module (PAM) framework.
JAAS can be used for two purposes:
* 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
* for authorization of users to ensure they have the access control rights (permissions) required to do the actions performed
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.
See Java Authentication and Authorization Service (JAAS) http://java.sun.com/javase/7/docs/technotes/guides/security/jaas/JAASRefGuide.html[Reference Guide] for more information about JAAS.
The Jetty JAAS support aims to dictate as little as possible whilst providing a sufficiently flexible infrastructure to allow users to drop either one of the link:#og-jaas-loginmodules[JAAS Login Modules that ships with Jetty], or their
own custom https://docs.oracle.com/javase/7/docs/api/javax/security/auth/spi/LoginModule.html[LoginModules].
[[og-jaas-configuration]]
==== Configuration
[[og-jaas-module]]
===== The `jaas` module
Enable the `jaas` module:
----
include::{JETTY_HOME}/modules/jaas.mod[]
----
The configurable items in the resulting `$jetty.base/start.d/jaas.ini` file are:
jetty.jaas.login.conf::
This is the location of the file that will be referenced by the System property `java.security.auth.login.config`: Jetty sets this System property for you based on the value of this property.
The value of this property is assumed to be _relative to the ``$jetty.base``_.
The default value is `etc/login.conf`, which resolves to `$jetty.base/etc/login.conf`.
If you don't want to put your login module configuration file here, you can change this property to point to where it is.
See more about the contents of this file in the link:#og-jaas-loginconf[Configuring JAAS] section.
[[og-jaas-webapp]]
===== Configure the webapp for JAAS
The `<realm-name>` in `web.xml` will be used to identify the `org.eclipse.jetty.jaas.JAASLoginService` declaration that integrates JAAS with Jetty.
For example, this `web.xml` contains a realm called `Test JAAS Realm`:
[source,xml,subs=verbatim]
----
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Test JAAS Realm</realm-name> <1>
<form-login-config>
<form-login-page>/login/login</form-login-page>
<form-error-page>/login/error</form-error-page>
</form-login-config>
</login-config>
----
<1> The name of the realm, which must be _identical_ to the name of an `org.eclipse.jetty.jaas.JAASLoginService` declaration.
We now need to declare an `org.eclipse.jetty.jaas.JAASLoginService` that references the realm name of `Test JAAS Realm`.
Here's an example of a suitable XML snippet:
[source, xml, subs=verbatim]
----
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="Name">Test JAAS Realm</Set> <1>
<Set name="LoginModuleName">xyz</Set> <2>
</New>
----
<1> The name is the _same_ as that declared in the `<realm-name>` in `web.xml`.
<2> The name that identifies a set of `javax.security.auth.spi.LoginModule` configurations that comprise the link:#og-jaas-loginconf[JAAS config file] identified in the `jetty.jaas.login.conf` property of the link:#og-jaas-module[`jaas` module].
The `org.eclipse.jetty.jaas.JAASLoginService` can be declared in a couple of different places, pick whichever suits your purposes best:
* If you have more than one webapp that you would like to use the same security infrastructure, then you can declare your `org.eclipse.jetty.jaas.JAASLoginService` as a bean that is added to the `org.eclipse.jetty.server.Server`.
The file in which you declare this needs to be on Jetty's execution path.
The recommended procedure is to create a file in your `$jetty.base/etc` directory and then ensure it is on the classpath either by adding it to the Jetty link:#og-start-jar[start command line], or more conveniently to a link:#custom-modules[custom module].
+
Here's an example of this type of XML file:
[source, xml, subs=verbatim]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<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>
----
* Alternatively, if you want to use JAAS with a specific webapp only, you declare your `org.eclipse.jetty.jaas.JAASLoginService` in a context XLM file specific to that webapp:
+
[source, xml, subs=verbatim]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<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>
----
[[og-jaas-loginconf]]
===== Configure JAAS
We now need to setup the contents of the file we specified as the `jetty.jaas.login.conf` property when we link:#og-jaas-module[configured the `jaas` module].
Refer to the https://docs.oracle.com/javase/7/docs/api/javax/security/auth/login/Configuration.html[syntax rules] of this file for a full description.
Remembering the example we set up link:#og-jaas-webapp[previously], the contents of the `$jetty.base/etc/login.conf` file could look as follows:
[source, ini, subs=verbatim]
----
xyz { <1>
com.acme.SomeLoginModule required debug=true; <2>
com.other.OtherLoginModule optional; <3>
};
----
<1> The name of the configuration _exactly_ as specified in your `org.eclipse.jetty.jaas.JAASLoginService` declaration.
<2> The first `LoginModule` declaration, containing the classname of the `LoginModule` and its configuration properties.
<3> A second `LoginModule` declaration.
You can provide as many `LoginModule` alternatives as you like, with a minimum of one.
Refer to the https://docs.oracle.com/javase/7/docs/api/javax/security/auth/login/Configuration.html[JAAS documentation] for more information on the standard configuration properties, and how JAAS interprets this file.
[[og-jaas-loginmodules]]
==== Provided LoginModules
* link:{JDURL}/org/eclipse/jetty/jaas/spi/JDBCLoginModule.html[`org.eclipse.jetty.jaas.spi.JDBCLoginModule`]
* link:{JDURL}/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.html[`org.eclipse.jetty.jaas.spi.PropertyFileLoginModule`]
* link:{JDURL}/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.html[`org.eclipse.jetty.jaas.spi.DataSourceLoginModule`]
* link:{JDURL}/org/eclipse/jetty/jaas/spi/LdapLoginModule.html[`org.eclipse.jetty.jaas.ldap.LdapLoginModule`]
____
[NOTE]
Passwords can be stored in clear text, obfuscated or checksummed.
The class link:{JDURL}/org/eclipse/jetty/util/security/Password.html[`org.eclipse.jetty.util.security.Password`] should be used to generate all varieties of passwords,the output from which can be put in to property files or entered into database tables.
____
===== JDBCLoginModule
The `org.eclipse.jetty.jaas.spi.JDBCLoginModule` stores user passwords and roles in a database 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 names of the table and columns storing the roles.
Here is an example link:#og-jaas-loginconf[login module configuration file] entry for it using an HSQLDB driver:
[source, ini, subs=verbatim]
----
jdbc { <1>
org.eclipse.jetty.jaas.spi.JDBCLoginModule required <2><3>
dbUrl="jdbc:hsqldb:." <4>
dbUserName="sa" <5>
dbDriver="org.hsqldb.jdbcDriver" <6>
userTable="myusers" <7>
userField="myuser" <8>
credentialField="mypassword" <9>
userRoleTable="myuserroles" <10>
userRoleUserField="myuser" <11>
userRoleRoleField="myrole"; <12>
};
----
<1> The name of the configuration.
<2> The name of the `LoginModule` class.
<3> A standard JAAS flag making successful authentication via this `LoginModule` mandatory.
<4> The JDBC url used to connect to the database.
<5> The name of the JDBC user to use for the connection.
<6> The name of the JDBC Driver class.
<7> The name of the table holding the user authenication information.
<8> The name of the column holding the user name.
<9> The name of the column holding the user credential.
<10> The name of the table holding the user authorization information.
<11> The name of the column holding the user name.
<12> The name of the column holding the user role.
The properties *7*-*12* are used to format the following queries:
[source,sql]
----
select <credentialField> from <userTable>
where <userField> =?
select <userRoleRoleField> from <userRoleTable>
where <userRoleUserField> =?
----
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.
Note that passwords can be stored in the database in plain text or encoded formats - see the note on "Passwords/Credentials" above.
===== DataSourceLoginModule
Similar to the `org.eclipse.jetty.jaas.spi.JDBCLoginModule`, but using a `javax.sql.DataSource` to connect to the database instead of a JDBC driver.
The `javax.sql.DataSource` is obtained at runtime by performing a JNDI lookup on `java:comp/env/${dnJNDIName}`.
A sample login module configuration for this `LoginModule`:
[source subs=verbatim]
----
ds { <1>
org.eclipse.jetty.jaas.spi.DataSourceLoginModule required <2><3>
dbJNDIName="ds" <4>
userTable="myusers" <5>
userField="myuser" <6>
credentialField="mypassword" <7>
userRoleTable="myuserroles" <8>
userRoleUserField="myuser" <9>
userRoleRoleField="myrole"; <10>
};
----
<1> The name of the configuration.
<2> The name of the `LoginModule` class.
<3> A standard JAAS flag making successful authentication via this `LoginModule` mandatory.
<4> The JNDI name, relative to `java:comp/env/` to lookup to obtain the `javax.sql.DataSource`.
<5> The name of the table holding the user authenication information.
<6> The name of the column holding the user name.
<7> The name of the column holding the user credential.
<8> The name of the table holding the user authorization information.
<9> The name of the column holding the user name.
<10> The name of the column holding the user role.
===== PropertyFileLoginModule
With this login module implementation, the authentication and role information is read from a property file.
[source subs=verbatim]
----
props { <1>
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required <2><3>
file="/somewhere/somefile.props"; <4>
};
----
<1> The name of the configuration.
<2> The name of the `LoginModule` class.
<3> A standard JAAS flag making successful authentication via this `LoginModule` mandatory.
<4> The location of a properties file containing the authentication and authorization information.
The property file must be of the format:
[source,text subs=verbatim]
----
<username>: <password> [,<rolename> ...]
----
Here's an example:
[source,ini]
----
fred: OBF:1xmk1w261u9r1w1c1xmq,user,admin
harry: changeme,user,developer
tom: MD5:164c88b302622e17050af52c89945d44,user
dick: CRYPT:adpexzg3FUZAk,admin
----
The contents of the file are fully read in and cached in memory the first time a user requests authentication.
===== LdapLoginModule
The `org.eclipse.jetty.jaas.spi.LdapLoginModule` uses LDAP to access authentication and authorization information stored in a directory.
The LDAP connection information and structure of the authentication/authorization data can be configured.
Here's an example:
[source,ini]
----
example { <1>
org.eclipse.jetty.jaas.spi.LdapLoginModule required <2><3>
contextFactory="com.sun.jndi.ldap.LdapCtxFactory" <4>
hostname="ldap.example.com" <5>
port="389" <6>
bindDn="cn=Directory Manager" <7>
bindPassword="directory" <8>
authenticationMethod="simple" <9>
useLdaps="true" <10>
userBaseDn="ou=people,dc=alcatel" <11>
userRdnAttribute="uid" <12>
userIdAttribute="cn" <13>
userPasswordAttribute="userPassword" <14>
userObjectClass="inetOrgPerson" <15>
roleBaseDn="ou=groups,dc=example,dc=com" <16>
roleNameAttribute="cn" <17>
roleMemberAttribute="uniqueMember" <18>
roleObjectClass="groupOfUniqueNames"; <19>
forceBindingLogin="false" <20>
debug="false" <21>
};
----
<1> The name of the configuration.
<2> The name of the `LoginModule` class.
<3> A standard JAAS flag making successful authentication via this `LoginModule` mandatory.
<4> The name of the context factory to use for the LDAP connection.
<5> The hostname for the LDAP connection. Optional.
<6> The port for the LDAP connection. Optional.
<7> The caller security Principal. Optional.
<8> The caller security credential. Optional.
<9> The security level for the LDAP connection environment. Optional.
<10> If true, use `ldaps` instead of `ldap` for the connection url.
<11> The distinguished name of the directory to search for user information.
<12> The name of the attribute for the user roles.
<13> The name of the attribute for the user id.
<14> The name of the attribute for the user password.
<15> The `ObjectClass` for users.
<16> The distinguished name of the directory to search for role information.
<17> The name of the attribute for roles.
<18> The name of the attribute storing the user for the roles `ObjectClass`.
<19> The name of the `ObjectClass` for roles.
<20> If true, the authentication proceeds on the basis of a successful LDAP binding using the username and credential provided by the user.
If false, then authentication proceeds based on username and password information retrieved from LDAP.
<21> If true, failed login attempts are logged on the server.

View File

@ -536,6 +536,8 @@
<goal>single</goal>
</goals>
<configuration>
<overrideUid>0</overrideUid>
<overrideGid>0</overrideGid>
<descriptors>
<descriptor>src/main/assembly/jetty-assembly.xml</descriptor>
</descriptors>

View File

@ -17,8 +17,14 @@
<!-- we'll build up shell scripts with execute in separate file-set -->
<exclude>bin/*.sh</exclude>
</excludes>
<fileMode>0400</fileMode>
<directoryMode>0700</directoryMode>
<!-- The archive is generated with the uid / gid of the user that
built the jetty release. which is highly unlikely to
exist on the target machines that unpack this tarball.
We set the user / group / other to have read-only access
to files, and read-execute access to directories
in the unpacked contents. -->
<fileMode>0444</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
<fileSet>
<directory>${assembly-directory}</directory>
@ -26,7 +32,8 @@
<includes>
<include>bin/*.sh</include>
</includes>
<fileMode>0500</fileMode>
<!-- Set read-execute for shell scripts -->
<fileMode>0555</fileMode>
</fileSet>
</fileSets>
</assembly>