Merge branch 'jetty-9.4.x'
This commit is contained in:
commit
c3bcce1ce4
|
@ -77,7 +77,7 @@ Otherwise, create a `webapps/myapp.xml` file as follows:
|
||||||
==== Avoiding TLD Scans with precompiled JSPs
|
==== Avoiding TLD Scans with precompiled JSPs
|
||||||
|
|
||||||
Of course precompiling JSPs is an excellent way to improve the start time of a web application.
|
Of course precompiling JSPs is an excellent way to improve the start time of a web application.
|
||||||
Since jetty 9.2.0, the Apache Jasper JSP implementation has been used and has been augmented to allow the TLD scan to be skipped.
|
As of Jetty 9.2 the Apache Jasper JSP implementation has been used and has been augmented to allow the TLD scan to be skipped.
|
||||||
This can be done by adding a `context-param` to the `web.xml` file (this is done automatically by the Jetty Maven JSPC plugin):
|
This can be done by adding a `context-param` to the `web.xml` file (this is done automatically by the Jetty Maven JSPC plugin):
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
|
|
|
@ -17,41 +17,21 @@
|
||||||
[[configuring-security-authentication]]
|
[[configuring-security-authentication]]
|
||||||
=== Authentication
|
=== Authentication
|
||||||
|
|
||||||
There are two aspects to securing a web application(or context) within
|
There are two aspects to securing a web application(or context) within the Jetty server:
|
||||||
the Jetty server:
|
|
||||||
|
|
||||||
Authentication::
|
Authentication::
|
||||||
The web application can be configured with a mechanism to determine
|
The web application can be configured with a mechanism to determine the identity of the user.
|
||||||
the identity of the user. This is configured by a mix of standard
|
This is configured by a mix of standard declarations and jetty specific mechanisms and is covered in this section.
|
||||||
declarations and jetty specific mechanisms and is covered in this
|
|
||||||
section.
|
|
||||||
Authorization::
|
Authorization::
|
||||||
Once the identify of the user is known (or not known), the web
|
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.
|
||||||
application can be configured via standard descriptors with security
|
|
||||||
constraints that declare what resources that user may access.
|
|
||||||
|
|
||||||
==== Configuring an Authentication mechanism
|
==== Configuring an Authentication mechanism
|
||||||
|
|
||||||
The jetty server supports several standard authentication mechanisms:
|
The jetty server supports several standard authentication mechanisms: http://en.wikipedia.org/wiki/Basic_access_authentication[BASIC]; http://en.wikipedia.org/wiki/Digest_authentication[DIGEST]; http://en.wikipedia.org/wiki/Form-based_authentication[FORM]; CLIENT-CERT; and other mechanisms can be plugged in using the extensible http://docs.oracle.com/cd/E19462-01/819-6717/gcszc/index.html[JASPI] or http://en.wikipedia.org/wiki/SPNEGO[SPNEGO] mechanisms.
|
||||||
http://en.wikipedia.org/wiki/Basic_access_authentication[BASIC];
|
|
||||||
http://en.wikipedia.org/wiki/Digest_authentication[DIGEST];
|
|
||||||
http://en.wikipedia.org/wiki/Form-based_authentication[FORM];
|
|
||||||
CLIENT-CERT; and other mechanisms can be plugged in using the extensible
|
|
||||||
http://docs.oracle.com/cd/E19462-01/819-6717/gcszc/index.html[JASPI] or
|
|
||||||
http://en.wikipedia.org/wiki/SPNEGO[SPNEGO] mechanisms.
|
|
||||||
|
|
||||||
Internally, configurating an authentication mechanism is done by setting
|
Internally, configuring an authentication mechanism is done by setting an instance of a the link:{JDURL}/org/eclipse/jetty/security/Authenticator.html[Authenticator] interface onto the link:{JDURL}/org/eclipse/jetty/security/SecurityHandler.html[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.
|
||||||
an instance of a the
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/Authenticator.html[Authenticator]
|
|
||||||
interface onto the
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/SecurityHandler.html[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
|
Below is an example taken from the link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9[jetty-test-webapp web.xml] that configures BASIC authentication:
|
||||||
link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9[jetty-test-webapp
|
|
||||||
web.xml] that configures BASIC authentication:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -59,13 +39,10 @@ web.xml] that configures BASIC authentication:
|
||||||
<auth-method>BASIC</auth-method>
|
<auth-method>BASIC</auth-method>
|
||||||
<realm-name>Test Realm</realm-name>
|
<realm-name>Test Realm</realm-name>
|
||||||
</login-config>
|
</login-config>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
The
|
The link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9[jetty-test-webapp web.xml] also includes commented out examples of other DIGEST and FORM configuration:
|
||||||
link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9[jetty-test-webapp
|
|
||||||
web.xml] also includes commented out examples of other DIGEST and FORM
|
|
||||||
configuration:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -77,14 +54,11 @@ configuration:
|
||||||
<form-error-page>/logonError.html?param=test</form-error-page>
|
<form-error-page>/logonError.html?param=test</form-error-page>
|
||||||
</form-login-config>
|
</form-login-config>
|
||||||
</login-config>
|
</login-config>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
With FORM Authentication, you must also configure URLs of pages to
|
With FORM Authentication, you must also configure URLs of pages to generate a login form and handle errors.
|
||||||
generate a login form and handle errors. Below is a simple HTML form
|
Below is a simple HTML form from the link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/logon.html?h=release-9[test webapp logon.html]:
|
||||||
from the
|
|
||||||
link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/webapp/logon.html?h=release-9[test
|
|
||||||
webapp logon.html]:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -108,78 +82,49 @@ webapp logon.html]:
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</HTML>
|
</HTML>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
The Authentication mechanism declared for a context / web application
|
The Authentication mechanism declared for a context / web application defines how the server obtain authentication credentials from the
|
||||||
defines how the server obtain authentication credentials from the
|
client, but it does not define how the server checks if those credentials are valid.
|
||||||
client, but it does not define how the server checks if those
|
To check credentials, the server and/or context also need to be configured with a link:{JDURL}/org/eclipse/jetty/security/LoginService.html[LoginService] instance, which may be matched by the declared realm-name.
|
||||||
credentials are valid. To check credentials, the server and/or context
|
|
||||||
also need to be configured with a
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/LoginService.html[LoginService]
|
|
||||||
instance, which may be matched by the declared realm-name.
|
|
||||||
|
|
||||||
[[security-realms]]
|
[[security-realms]]
|
||||||
==== Security Realms
|
==== Security Realms
|
||||||
|
|
||||||
Security realms allow you to secure your web applications against
|
Security realms allow you to secure your web applications against unauthorized access.
|
||||||
unauthorized access. Protection is based on authentication that
|
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.
|
||||||
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
|
A webapp statically declares its security requirements in its web.xml file.
|
||||||
file. Authentication is controlled by the <login-config> element. Access
|
Authentication is controlled by the `<login-config>` element.
|
||||||
controls are specified by <security-constraint> and <security-role-ref>
|
Access controls are specified by `<security-constraint>` and `<security-role-ref>` elements.
|
||||||
elements. When a request is received for a protected resource, the web
|
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.
|
||||||
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
|
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.
|
||||||
information in the `WEB-INF/web.xml` file is mapped to the runtime
|
For Jetty, the link:{JDURL}/org/eclipse/jetty/security/LoginService.html[LoginService] performs this function.
|
||||||
environment of the container. For Jetty, the
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/LoginService.html[LoginService]
|
|
||||||
performs this function.
|
|
||||||
|
|
||||||
A LoginService has a unique name, and gives access to information about
|
A LoginService has a unique name, and gives access to information about a set of users.
|
||||||
a set of users. Each user has authentication information (e.g. a
|
Each user has authentication information (e.g. a password) and a set of roles associated with him/herself.
|
||||||
password) and a set of roles associated with him/herself.
|
|
||||||
|
|
||||||
You may configure one or many different LoginServices depending on your
|
You may configure one or many different LoginServices depending on your needs.
|
||||||
needs. A single realm would indicate that you wish to share common
|
A single realm would indicate that you wish to share common security information across all of your web applications.
|
||||||
security information across all of your web applications. Distinct
|
Distinct realms allow you to partition your security information webapp by webapp.
|
||||||
realms allow you to partition your security information webapp by
|
|
||||||
webapp.
|
|
||||||
|
|
||||||
When a request to a web application requires authentication or
|
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.
|
||||||
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
|
==== Scoping Security Realms
|
||||||
|
|
||||||
A LoginService has a unique name, and is composed of a set of users.
|
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.
|
||||||
Each user has authentication information (for example, a password) and a
|
You can configure one or many different realms depending on your needs.
|
||||||
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
|
* Configure a single LoginService to share common security information across all of your web applications.
|
||||||
across all of your web applications.
|
* Configure distinct LoginServices to partition your security information webapp by webapp.
|
||||||
* Configure distinct LoginServices to partition your security
|
|
||||||
information webapp by webapp.
|
|
||||||
|
|
||||||
===== Globally Scoped
|
===== Globally Scoped
|
||||||
|
|
||||||
A LoginService is available to all web applications on a Server instance
|
A LoginService is available to all web applications on a Server instance if you add it as a bean to the Server.
|
||||||
if you add it as a bean to the Server. Such a definition would go into
|
Such a definition would go into an xml file in your `${jetty.base}/etc` directory, e.g. `${jetty.base}/etc/my-realm.xml` and you would add this xml file to the execution path via `start.ini` or `start.d` (you may want to review the material in the link:#startup[Starting Jetty] chapter).
|
||||||
an xml file in your $\{jetty.base}/etc directory, eg
|
Here's an example of an xml file that defines an in-memory type of LoginService called the link:{JDURL}/org/eclipse/jetty/security/HashLoginService.html[HashLoginService]:
|
||||||
$\{jetty.base}/etc/my-realm.xml and you would add this xml file to the
|
|
||||||
execution path via start.ini or start.d (you may want to review the
|
|
||||||
material in the link:#startup[Starting Jetty] chapter). Here's an
|
|
||||||
example of an xml file that defines an in-memory type of LoginService
|
|
||||||
called the
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/HashLoginService.html[HashLoginService]:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -196,14 +141,12 @@ link:{JDURL}/org/eclipse/jetty/security/HashLoginService.html[HashLoginService]:
|
||||||
</Call>
|
</Call>
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
If you define more than one LoginService on a Server, you will need to
|
If you define more than one LoginService on a Server, you will need to specify which one you want used for each context.
|
||||||
specify which one you want used for each context. You can do that by
|
You can do that by telling the context the name of the LoginService, or passing it the LoginService instance.
|
||||||
telling the context the name of the LoginService, or passing it the
|
Here's an example of doing both of these, using a link:#deployable-descriptor-file[context xml file]:
|
||||||
LoginService instance. Here's an example of doing both of these, using a
|
|
||||||
link:#deployable-descriptor-file[context xml file]:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -216,20 +159,19 @@ link:#deployable-descriptor-file[context xml file]:
|
||||||
<Set name="name">Test Realm</Set>
|
<Set name="name">Test Realm</Set>
|
||||||
</New>
|
</New>
|
||||||
</Set>
|
</Set>
|
||||||
|
|
||||||
<!-- or if you defined a LoginService called "Test Realm" in jetty.xml : -->
|
<!-- or if you defined a LoginService called "Test Realm" in jetty.xml : -->
|
||||||
<Set name="realmName">Test Realm</Set>
|
<Set name="realmName">Test Realm</Set>
|
||||||
|
|
||||||
</Get>
|
</Get>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
===== Per-Webapp Scoped
|
===== Per-Webapp Scoped
|
||||||
|
|
||||||
Alternatively, you can define a LoginService for just a single web
|
Alternatively, you can define a LoginService for just a single web application.
|
||||||
application. Here's how to define the same HashLoginService, but inside
|
Here's how to define the same HashLoginService, but inside a link:#deployable-descriptor-file[context xml file]:
|
||||||
a link:#deployable-descriptor-file[context xml file]:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -247,67 +189,47 @@ a link:#deployable-descriptor-file[context xml file]:
|
||||||
</Get>
|
</Get>
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Jetty provides a number of different LoginService types which can be
|
Jetty provides a number of different LoginService types which can be seen in the next section.
|
||||||
seen in the next section.
|
|
||||||
|
|
||||||
[[configuring-login-service]]
|
[[configuring-login-service]]
|
||||||
==== Configuring a LoginService
|
==== Configuring a LoginService
|
||||||
|
|
||||||
A
|
A link:{JDURL}/org/eclipse/jetty/security/LoginService.html[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:
|
||||||
link:{JDURL}/org/eclipse/jetty/security/LoginService.html[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:
|
|
||||||
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/HashLoginService.html[HashLoginService]::
|
link:{JDURL}/org/eclipse/jetty/security/HashLoginService.html[HashLoginService]::
|
||||||
A user realm that is backed by a hash map that is filled either
|
A user realm that is backed by a hash map that is filled either programatically or from a Java properties file.
|
||||||
programatically or from a java properties file.
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/JDBCLoginService.html[JDBCLoginService]::
|
link:{JDURL}/org/eclipse/jetty/security/JDBCLoginService.html[JDBCLoginService]::
|
||||||
Uses a JDBC connection to an SQL database for authentication
|
Uses a JDBC connection to an SQL database for authentication
|
||||||
link:{JDURL}/org/eclipse/jetty/plus/security/DataSourceLoginService.html[DataSourceLoginService]::
|
link:{JDURL}/org/eclipse/jetty/plus/security/DataSourceLoginService.html[DataSourceLoginService]::
|
||||||
Uses a JNDI defined
|
Uses a JNDI defined http://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html[DataSource] for authentication
|
||||||
http://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html[DataSource]
|
|
||||||
for authentication
|
|
||||||
link:{JDURL}/org/eclipse/jetty/jaas/JAASLoginService.html[JAASLoginService]::
|
link:{JDURL}/org/eclipse/jetty/jaas/JAASLoginService.html[JAASLoginService]::
|
||||||
Uses a
|
Uses a http://en.wikipedia.org/wiki/Java_Authentication_and_Authorization_Service[JAAS] provider for authentication; see the section on
|
||||||
http://en.wikipedia.org/wiki/Java_Authentication_and_Authorization_Service[JAAS]
|
link:#jaas-support[JAAS support] for more information
|
||||||
provider for authentication, See the section on
|
|
||||||
link:#jaas-support[JAAS support] for more information.
|
|
||||||
link:{JDURL}/org/eclipse/jetty/security/SpnegoLoginService.html[SpnegoLoginService]::
|
link:{JDURL}/org/eclipse/jetty/security/SpnegoLoginService.html[SpnegoLoginService]::
|
||||||
http://en.wikipedia.org/wiki/SPNEGO[SPNEGO] Authentication, See the
|
http://en.wikipedia.org/wiki/SPNEGO[SPNEGO] Authentication; see the section on link:#spnego-support[SPNEGO support] for more information.
|
||||||
section on link:#spnego-support[SPNEGO support] for more information.
|
|
||||||
|
|
||||||
An instance of a LoginService can be matched to a context/webapp either
|
An instance of a LoginService can be matched to a context/webapp by:
|
||||||
by:
|
|
||||||
|
|
||||||
* A LoginService instance may be set directly on the SecurityHandler
|
* A LoginService instance may be set directly on the SecurityHandler instance via embedded code or IoC XML
|
||||||
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
|
||||||
* Matching the realm-name defined in web.xml with the name of a
|
* If only a single LoginService instance has been set on the Server then it is used as the login service for the context
|
||||||
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.
|
|
||||||
|
|
||||||
[[hash-login-service]]
|
[[hash-login-service]]
|
||||||
===== HashLoginService
|
===== HashLoginService
|
||||||
|
|
||||||
The HashLoginService is a simple and efficient login service that loads
|
The HashLoginService is a simple and efficient login service that loads usernames, credentials and roles from a Java properties file in the format:
|
||||||
usernames, credentials and roles from a java properties file in the
|
|
||||||
format:
|
|
||||||
|
|
||||||
[source,properties]
|
[source,properties]
|
||||||
----
|
----
|
||||||
|
|
||||||
username: password[,rolename ...]
|
username: password[,rolename ...]
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
where:
|
Where:
|
||||||
|
|
||||||
username::
|
username::
|
||||||
is the user's unique identity
|
is the user's unique identity
|
||||||
|
@ -325,11 +247,9 @@ admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
|
||||||
other: OBF:1xmk1w261u9r1w1c1xmq
|
other: OBF:1xmk1w261u9r1w1c1xmq
|
||||||
guest: guest,read-only
|
guest: guest,read-only
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
You configure the HashLoginService with a name and a reference to the
|
You configure the HashLoginService with a name and a reference to the location of the properties file:
|
||||||
location of the properties file:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -341,12 +261,10 @@ location of the properties file:
|
||||||
</New>
|
</New>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
You can also configure it to check the properties file regularly for
|
You can also configure it to check the properties file regularly for changes and reload when changes are detected.
|
||||||
changes and reload when changes are detected. The reloadInterval is in
|
The `reloadInterval` is in seconds:
|
||||||
seconds:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -357,17 +275,15 @@ seconds:
|
||||||
<Set name="reloadInterval">5</Set>
|
<Set name="reloadInterval">5</Set>
|
||||||
<Call name="start"></Call>
|
<Call name="start"></Call>
|
||||||
</New>
|
</New>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
[[jdbc-login-service]]
|
[[jdbc-login-service]]
|
||||||
===== JDBCLoginService
|
===== JDBCLoginService
|
||||||
|
|
||||||
In this implementation, authentication and role information is stored in
|
In this implementation, authentication and role information is stored in a database accessed via JDBC.
|
||||||
a database accessed via JDBC. A properties file defines the JDBC
|
A properties file defines the JDBC connection and database table information.
|
||||||
connection and database table information. Here is an example of a
|
Here is an example of a properties file for this realm implementation:
|
||||||
properties file for this realm implementation:
|
|
||||||
|
|
||||||
[source,properties]
|
[source,properties]
|
||||||
----
|
----
|
||||||
|
@ -388,7 +304,6 @@ userroletableuserkey = user_id
|
||||||
userroletablerolekey = role_id
|
userroletablerolekey = role_id
|
||||||
cachetime = 300
|
cachetime = 300
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
The format of the database tables is (pseudo-sql):
|
The format of the database tables is (pseudo-sql):
|
||||||
|
@ -415,7 +330,6 @@ roles
|
||||||
role varchar(100) NOT NULL UNIQUE KEY
|
role varchar(100) NOT NULL UNIQUE KEY
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
@ -442,13 +356,9 @@ id::
|
||||||
role::
|
role::
|
||||||
a human-readable name for a role
|
a human-readable name for a role
|
||||||
|
|
||||||
If you want to use obfuscated, MD5 hashed or encrypted passwords the
|
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.
|
||||||
'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
|
You define a `JDBCLoginService` with the name of the realm and the location of the properties file describing the database:
|
||||||
location of the properties file describing the database:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -458,30 +368,22 @@ location of the properties file describing the database:
|
||||||
<Set name="config">etc/jdbcRealm.properties</Set>
|
<Set name="config">etc/jdbcRealm.properties</Set>
|
||||||
</New>
|
</New>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Authorization
|
==== Authorization
|
||||||
|
|
||||||
As far as the
|
As far as the http://jcp.org/aboutJava/communityprocess/final/jsr340/[Servlet Specification] is concerned, authorization is based on roles.
|
||||||
http://jcp.org/aboutJava/communityprocess/final/jsr340/[Servlet
|
As we have seen, a LoginService associates a user with a set of roles.
|
||||||
Specification] is concerned, authorization is based on roles. As we have
|
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.
|
||||||
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:
|
Until Servlet 3.1, role-based authorization could define:
|
||||||
|
|
||||||
* access granted to a set of named roles
|
* access granted to a set of named roles
|
||||||
* access totally forbidden, regardless of role
|
* access totally forbidden, regardless of role
|
||||||
* access granted to a user in any of the roles defined in the effective
|
* access granted to a user in any of the roles defined in the effective web.xml.
|
||||||
web.xml. This is indicated by the special value of "*" for the
|
This is indicated by the special value of "*" for the `<role-name>` of a `<auth-constraint> `in the `<security-constraint>`
|
||||||
<role-name> of a <auth-constraint> in the <security-constraint>
|
|
||||||
|
|
||||||
With the advent of Servlet 3.1, there is now another authorization:
|
With the advent of Servlet 3.1, there is now another authorization:
|
||||||
|
|
||||||
* access granted to any user who is authenticated, regardless of roles.
|
* 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
|
This is indicated by the special value of "**" for the `<role-name>` of a `<auth-constraint>` in the `<security-constraint>`
|
||||||
<auth-constraint> in the <security-constraint>
|
|
||||||
|
|
|
@ -17,52 +17,42 @@
|
||||||
[[configuring-form-size]]
|
[[configuring-form-size]]
|
||||||
=== Limiting Form Content
|
=== Limiting Form Content
|
||||||
|
|
||||||
Form content sent to the server is processed by Jetty into a map of
|
Form content sent to the server is processed by Jetty into a map of parameters to be used by the web application.
|
||||||
parameters to be used by the web application. This can be vulnerable to
|
This can be vulnerable to denial of service (DOS) attacks since significant memory and CPU can be consumed if a malicious clients sends very large form content or large number of form keys.
|
||||||
denial of service (DOS) attacks since significant memory and CPU can be
|
Thus Jetty limits the amount of data and keys that can be in a form posted to Jetty.
|
||||||
consumed if a malicious clients sends very large form content or large
|
|
||||||
number of form keys. Thus Jetty limits the amount of data and keys that
|
|
||||||
can be in a form posted to Jetty.
|
|
||||||
|
|
||||||
The default maximum size Jetty permits is 200000 bytes and 1000 keys.
|
The default maximum size Jetty permits is 200000 bytes and 1000 keys.
|
||||||
You can change this default for a particular webapp or for all webapps
|
You can change this default for a particular webapp or for all webapps on a particular Server instance.
|
||||||
on a particular Server instance.
|
|
||||||
|
|
||||||
==== Configuring Form Limits for a Webapp
|
==== Configuring Form Limits for a Webapp
|
||||||
|
|
||||||
To configure the form limits for a sinlge webapplication, the context
|
To configure the form limits for a single web application, the context handler (or webappContext) instance must be configured using the following methods:
|
||||||
handler (or webappContext) instance must be configured using the
|
|
||||||
following methods:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
ContextHandler.setMaxFormContentSize(int maxSizeInBytes);
|
ContextHandler.setMaxFormContentSize(int maxSizeInBytes);
|
||||||
ContextHandler.setMaxFormKeys(int formKeys);
|
ContextHandler.setMaxFormKeys(int formKeys);
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
These methods may be called directly when embedding jetty, but more
|
These methods may be called directly when embedding Jetty, but more commonly are configured from a context XML file or WEB-INF/jetty-web.xml file:
|
||||||
commonly are configured from a context XML file or WEB-INF/jetty-web.xml
|
|
||||||
file:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
<Set name="maxFormContentSize">200000</Set>
|
<Set name="maxFormContentSize">200000</Set>
|
||||||
<Set name="maxFormKeys">200</Set>
|
<Set name="maxFormKeys">200</Set>
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
==== Configuring Form Limits for the Server
|
==== Configuring Form Limits for the Server
|
||||||
|
|
||||||
If a context does not have specific form limits configured, then the
|
If a context does not have specific form limits configured, then the server attributes are inspected to see if a server wide limit has been set on the size or keys.
|
||||||
server attributes are inspected to see if a server wide limit has been
|
The following XML shows how these attributes can be set in `jetty.xml`:
|
||||||
set on the size or keys. The following XML shows how these attributes
|
|
||||||
can be set in jetty.xml:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -78,6 +68,6 @@ can be set in jetty.xml:
|
||||||
<Arg>org.eclipse.jetty.server.Request.maxFormKeys</Arg>
|
<Arg>org.eclipse.jetty.server.Request.maxFormKeys</Arg>
|
||||||
<Arg>2000</Arg>
|
<Arg>2000</Arg>
|
||||||
</Call>
|
</Call>
|
||||||
</configure>
|
</configure>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,59 +17,40 @@
|
||||||
[[jaas-support]]
|
[[jaas-support]]
|
||||||
=== JAAS Support
|
=== JAAS Support
|
||||||
|
|
||||||
JAAS implements a Java version of the standard Pluggable Authentication
|
JAAS implements a Java version of the standard Pluggable Authentication Module (PAM) framework.
|
||||||
Module (PAM) framework.
|
|
||||||
|
|
||||||
JAAS can be used for two purposes:
|
JAAS can be used for two purposes:
|
||||||
|
|
||||||
* for authentication of users, to reliably and securely determine who is
|
* 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
|
||||||
currently executing Java code, regardless of whether the code is running
|
* for authorization of users to ensure they have the access control rights (permissions) required to do the actions performed
|
||||||
as an application, an applet, a bean, or a servlet; and
|
|
||||||
* 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
|
JAAS authentication is performed in a pluggable fashion.
|
||||||
applications to remain independent from underlying authentication
|
This permits applications to remain independent from underlying authentication technologies.
|
||||||
technologies. New or updated authentication technologies can be plugged
|
New or updated authentication technologies can be plugged under an application without requiring modifications to the application itself.
|
||||||
under an application without requiring modifications to the application
|
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.
|
||||||
itself. Applications enable the authentication process by instantiating
|
Typical `LoginModules` may prompt for and verify a username and password.
|
||||||
a LoginContext object, which in turn references a Configuration to
|
Others may read and verify a voice or fingerprint sample.
|
||||||
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.
|
|
||||||
|
|
||||||
See Java Authentication and Authorization Service (JAAS)
|
See Java Authentication and Authorization Service (JAAS) http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html[Reference Guide] for more information about JAAS.
|
||||||
http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html[Reference
|
|
||||||
Guide] for more information about JAAS.
|
|
||||||
|
|
||||||
[[jetty-jaas]]
|
[[jetty-jaas]]
|
||||||
==== Jetty and JAAS
|
==== Jetty and JAAS
|
||||||
|
|
||||||
Many application servers support JAAS as a means of bringing greater
|
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) http://java.sun.com/javaee/index.jsp[specification].
|
||||||
flexibility to the declarative security models of the J2EE (now known as
|
Jetty support for JAAS provides greater alternatives for servlet security, and increases the portability of web applications.
|
||||||
the JavaEE) http://java.sun.com/javaee/index.jsp[specification]. Jetty
|
|
||||||
support for JAAS provides greater alternatives for servlet security, and
|
|
||||||
increases the portability of web applications.
|
|
||||||
|
|
||||||
The JAAS support aims to dictate as little as possible whilst providing
|
The JAAS support aims to dictate as little as possible whilst providing a sufficiently flexible infrastructure to allow users to drop in their
|
||||||
a sufficiently flexible infrastructure to allow users to drop in their
|
own custom http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html[LoginModules].
|
||||||
own custom
|
|
||||||
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html[LoginModules].
|
|
||||||
|
|
||||||
[[jaas-configuration]]
|
[[jaas-configuration]]
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
Using JAAS with jetty is very simply a matter of declaring a
|
Using JAAS with Jetty is very simply a matter of declaring a `org.eclipse.jetty.jaas.JAASLoginService`, creating a JAAS login module configuration file and specifying it on the Jetty run line.
|
||||||
`org.eclipse.jetty.jaas.JAASLoginService`, creating a jaas login module
|
Let's look at an example.
|
||||||
configuration file and specifying it on the jetty run line. Let's look
|
|
||||||
at an example.
|
|
||||||
|
|
||||||
===== Step 1
|
===== Step 1
|
||||||
|
|
||||||
Configure a jetty `org.eclipse.jetty.jaas.JAASLoginService` to match the
|
Configure a Jetty `org.eclipse.jetty.jaas.JAASLoginService` to match the `<realm-name>` in your `web.xml` file. For example, if the `web.xml` contains a realm called "xyz" like so:
|
||||||
<realm-name> in your web.xml file. For example, if the `web.xml`
|
|
||||||
contains a realm called "xyz" like so:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -83,8 +64,7 @@ contains a realm called "xyz" like so:
|
||||||
</login-config>
|
</login-config>
|
||||||
----
|
----
|
||||||
|
|
||||||
Then you need to create a JAASLoginService with the matching name of
|
Then you need to create a `JAASLoginService` with the matching name of "xyz":
|
||||||
"xyz":
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -96,15 +76,13 @@ Then you need to create a JAASLoginService with the matching name of
|
||||||
|
|
||||||
____
|
____
|
||||||
[CAUTION]
|
[CAUTION]
|
||||||
The name of the realm-name that you declare in `web.xml` must match exactly the name of your JAASLoginService.
|
The name of the realm-name that you declare in `web.xml` must match exactly the name of your `JAASLoginService`.
|
||||||
____
|
____
|
||||||
|
|
||||||
You can declare your JAASLoginService in a couple of different ways:
|
You can declare your `JAASLoginService` in a couple of different ways:
|
||||||
|
|
||||||
1. If you have more than one webapp that you would like to use the same
|
1. 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`.
|
||||||
security infrastructure, then you can declare your JAASLoginService in a
|
An example:
|
||||||
top-level jetty xml file as a bean that is added to the
|
|
||||||
org.eclipse.jetty.server.Server. Here's an example:
|
|
||||||
+
|
+
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -121,9 +99,7 @@ org.eclipse.jetty.server.Server. Here's an example:
|
||||||
|
|
||||||
</Configure>
|
</Configure>
|
||||||
----
|
----
|
||||||
2. Alternatively, you can use a JAASLoginService with just a specific
|
2. Alternatively, you can use a `JAASLoginService` with just a specific webapp by creating a link:#deployable-descriptor-file[context xml] file for the webapp, and specifying the `JAASLoginService` in it:
|
||||||
webapp by creating a link:#deployable-descriptor-file[context xml] file
|
|
||||||
for the webapp, and specifying the JAASLoginService in it:
|
|
||||||
+
|
+
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -146,9 +122,7 @@ for the webapp, and specifying the JAASLoginService in it:
|
||||||
[[jaas-step-2]]
|
[[jaas-step-2]]
|
||||||
===== Step 2
|
===== Step 2
|
||||||
|
|
||||||
Set up your `LoginModule` in a configuration file, following the
|
Set up your `LoginModule` in a configuration file, following the http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html[syntax rules] :
|
||||||
http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html[syntax
|
|
||||||
rules] :
|
|
||||||
|
|
||||||
[source,ini]
|
[source,ini]
|
||||||
----
|
----
|
||||||
|
@ -159,24 +133,20 @@ xyz {
|
||||||
|
|
||||||
____
|
____
|
||||||
[CAUTION]
|
[CAUTION]
|
||||||
It is imperative that the application name on the first line is exactly the same as the `LoginModuleName` of your JAASLoginService.
|
It is imperative that the application name on the first line is exactly the same as the `LoginModuleName` of your `JAASLoginService`.
|
||||||
____
|
____
|
||||||
|
|
||||||
You may find it convenient to name this configuration file as
|
You may find it convenient to name this configuration file as `etc/login.conf` because, as we will see below, some of the wiring up for JAAS has been done for you.
|
||||||
`etc/login.conf` because, as we will see below, some of the wiring up
|
|
||||||
for jaas has been done for you.
|
|
||||||
|
|
||||||
===== Step 3
|
===== Step 3
|
||||||
|
|
||||||
You now need to invoke jetty with support for jaas. There are 2 aspects
|
You now need to invoke Jetty with support for JAAS.
|
||||||
to this:
|
There are 2 aspects to this:
|
||||||
|
|
||||||
* adding jaas-related jars to the jetty container classpath
|
* adding JAAS-related jars to the Jetty container classpath
|
||||||
* setting the System property `java.security.auth.login.config`
|
* setting the System property `java.security.auth.login.config`
|
||||||
|
|
||||||
To accomplish the above, use the jetty link:#startup-overview[startup]
|
To accomplish the above, use the Jetty link:#startup-overview[startup] link:#startup-modules[modules mechanism] to add the JAAS link:#startup-modules[module]:
|
||||||
link:#startup-modules[modules mechanism] to add the jaas
|
|
||||||
link:#startup-modules[module]:
|
|
||||||
|
|
||||||
[source,bash]
|
[source,bash]
|
||||||
----
|
----
|
||||||
|
@ -185,10 +155,8 @@ java -jar start.jar --add-to-startd=jaas
|
||||||
|
|
||||||
____
|
____
|
||||||
[NOTE]
|
[NOTE]
|
||||||
The top level of the distribution does not have the jaas module enabled
|
The top level of the distribution does not have the JAAS module enabled by default.
|
||||||
by default. However, there are several link:#demo-webapps-base[demo
|
However, there are several link:#demo-webapps-base[demo webapps] - including a JAAS webapp - available in the `demo-base` directory of the distribution which has pre-enabled the JAAS module.
|
||||||
webapps] - including a jaas webapp - available in the `demo-base`
|
|
||||||
directory of the distribution which has pre-enabled the jaas module.
|
|
||||||
____
|
____
|
||||||
|
|
||||||
Now you will have a file named `start.d/jaas.ini`, which contains:
|
Now you will have a file named `start.d/jaas.ini`, which contains:
|
||||||
|
@ -199,28 +167,19 @@ Now you will have a file named `start.d/jaas.ini`, which contains:
|
||||||
jaas.login.conf=etc/login.conf
|
jaas.login.conf=etc/login.conf
|
||||||
----
|
----
|
||||||
|
|
||||||
The `jaas.login.conf` property refers to the location of your
|
The `jaas.login.conf` property refers to the location of your `LoginModule` configuration file that you established in link:#jaas-step-2[Step 2].
|
||||||
LoginModule configuration file that you established in
|
If you called it `etc/login.conf`, then your work is done. Otherwise, change the value of the `jaas.login.conf` property to be the location of your LoginModule configuration file.
|
||||||
link:#jaas-step-2[Step 2]. If you called it `etc/login.conf`, then your
|
Jetty will automatically use this property to set the value of the System property `java.security.auth.login.config.`
|
||||||
work is done. Otherwise, change the value of the` jaas.login.conf`
|
|
||||||
property to be the location of your LoginModule configuration file.
|
|
||||||
Jetty will automatically use this property to set the value of the
|
|
||||||
System property `java.security.auth.login.config.`
|
|
||||||
|
|
||||||
==== A Closer Look at JAASLoginService
|
==== A Closer Look at JAASLoginService
|
||||||
|
|
||||||
To allow the greatest degree of flexibility in using JAAS with web
|
To allow the greatest degree of flexibility in using JAAS with web applications, the `JAASLoginService` supports a couple of configuration options.
|
||||||
applications, the `JAASLoginService` supports a couple of configuration
|
Note that you don't ordinarily need to set these explicitly, as Jetty has defaults which will work in 99% of cases.
|
||||||
options. Note that you don't ordinarily need to set these explicitly, as
|
However, should you need to, you can configure:
|
||||||
jetty has defaults which will work in 99% of cases. However, should you
|
|
||||||
need to, you can configure:
|
|
||||||
|
|
||||||
* a policy for role-based authorization (Default:
|
* a policy for role-based authorization (Default: `org.eclipse.jetty.jaas.StrictRoleCheckPolicy`)
|
||||||
`org.eclipse.jetty.jaas.StrictRoleCheckPolicy`)
|
* a CallbackHandler (Default: `org.eclipse.jetty.jaas.callback.DefaultCallbackHandler`)
|
||||||
* a CallbackHandler (Default:
|
* a list of classnames for the Principal implementation that equate to a user role (Default: `org.eclipse.jetty.jaas.JAASRole`)
|
||||||
`org.eclipse.jetty.jaas.callback.DefaultCallbackHandler`)
|
|
||||||
* a list of classnames for the Principal implementation that equate to a
|
|
||||||
user role (Default: `org.eclipse.jetty.jaas.JAASRole`)
|
|
||||||
|
|
||||||
Here's an example of setting each of these (to their default values):
|
Here's an example of setting each of these (to their default values):
|
||||||
|
|
||||||
|
@ -245,46 +204,25 @@ Here's an example of setting each of these (to their default values):
|
||||||
|
|
||||||
===== RoleCheckPolicy
|
===== RoleCheckPolicy
|
||||||
|
|
||||||
The RoleCheckPolicy must be an implementation of the
|
The `RoleCheckPolicy` must be an implementation of the `org.eclipse.jetty.jaas.RoleCheckPolicy` interface and its purpose is to help answer the question "is User X in Role Y" for role-based authorization requests.
|
||||||
`org.eclipse.jetty.jaas.RoleCheckPolicy` interface and its purpose is to
|
The default implementation distributed with Jetty is the `org.eclipse.jetty.jaas.StrictRoleCheckPolicy`, which will assess a user as having a particular role if that role is at the top of the stack of roles that have been temporarily pushed onto the user.
|
||||||
help answer the question "is User X in Role Y" for role-based
|
If the user has no temporarily assigned roles, the role is amongst those configured for the user.
|
||||||
authorization requests. The default implementation distributed with
|
|
||||||
jetty is the `org.eclipse.jetty.jaas.StrictRoleCheckPolicy`, 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.
|
|
||||||
|
|
||||||
Roles can be temporarily assigned to a user programmatically by using
|
Roles can be temporarily assigned to a user programmatically by using the `pushRole(String rolename)` method of the `org.eclipse.jetty.jaas.JAASUserPrincipal` class.
|
||||||
the pushRole(String rolename) method of the
|
|
||||||
`org.eclipse.jetty.jaas.JAASUserPrincipal` class.
|
|
||||||
|
|
||||||
For the majority of webapps, the default StrictRoleCheckPolicy will be
|
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.
|
||||||
quite adequate, however you may provide your own implementation and set
|
|
||||||
it on your JAASLoginService instance.
|
|
||||||
|
|
||||||
===== CallbackHandler
|
===== CallbackHandler
|
||||||
|
|
||||||
A CallbackHandler is responsible for interfacing with the user to obtain
|
A CallbackHandler is responsible for interfacing with the user to obtain usernames and credentials to be authenticated.
|
||||||
usernames and credentials to be authenticated.
|
|
||||||
|
|
||||||
Jetty ships with the `org.eclipse.jetty.jaas.DefaultCallbackHandler`
|
Jetty ships with the `org.eclipse.jetty.jaas.DefaultCallbackHandler` which interfaces the information contained in the request to the Callbacks that are requested by `LoginModules`.
|
||||||
which interfaces the information contained in the request to the
|
You can replace this default with your own implementation if you have specific requirements not covered by the default.
|
||||||
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.
|
|
||||||
|
|
||||||
===== Role Principal Implementation Class
|
===== Role Principal Implementation Class
|
||||||
|
|
||||||
When LoginModules authenticate a user, they usually also gather all of
|
When `LoginModules` authenticate a user, they usually also gather all of the roles that a user has and place them inside the JAAS Subject.
|
||||||
the roles that a user has and place them inside the JAAS Subject. As
|
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 `<security-constraint>`. The example `LoginModules` that ship with Jetty all use the `org.eclipse.jetty.jaas.JAASRole` class. However, if you have plugged in other `LoginModules`, you must configure the classnames of their role Principal implementations.
|
||||||
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 <security-constraint>s. The example LoginModules
|
|
||||||
that ship with jetty all use the `org.eclipse.jetty.jaas.JAASRole`
|
|
||||||
class. However, if you have plugged in some other LoginModules, you must
|
|
||||||
configure the classnames of their role Principal implementations.
|
|
||||||
|
|
||||||
===== Sample LoginModules
|
===== Sample LoginModules
|
||||||
|
|
||||||
|
@ -296,21 +234,16 @@ configure the classnames of their role Principal implementations.
|
||||||
____
|
____
|
||||||
[NOTE]
|
[NOTE]
|
||||||
Passwords can be stored in clear text, obfuscated or checksummed.
|
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 cut and pasted into property files or entered into database tables.
|
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.
|
||||||
+
|
|
||||||
See more on this under the Configuration section on link:#configuring-security-secure-passwords[securing passwords].
|
See more on this under the Configuration section on link:#configuring-security-secure-passwords[securing passwords].
|
||||||
____
|
____
|
||||||
|
|
||||||
===== JDBCLoginModule
|
===== JDBCLoginModule
|
||||||
|
|
||||||
The JDBCLoginModule stores user passwords and roles in a database that
|
The `JDBCLoginModule` stores user passwords and roles in a database that are accessed via JDBC calls.
|
||||||
are accessed via JDBC calls. You can configure the JDBC connection
|
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.
|
||||||
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.
|
|
||||||
|
|
||||||
Here is an example login module configuration file entry for it using an
|
Here is an example login module configuration file entry for it using an HSQLDB driver:
|
||||||
HSQLDB driver:
|
|
||||||
|
|
||||||
[source,ini]
|
[source,ini]
|
||||||
----
|
----
|
||||||
|
@ -330,34 +263,28 @@ jdbc {
|
||||||
};
|
};
|
||||||
----
|
----
|
||||||
|
|
||||||
There is no particular schema required for the database tables storing
|
There is no particular schema required for the database tables storing the authentication and role information.
|
||||||
the authentication and role information. The properties userTable,
|
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:
|
||||||
userField, credentialField, userRoleTable, userRoleUserField,
|
|
||||||
userRoleRoleField configure the names of the tables and the columns
|
|
||||||
within them that are used to format the following queries:
|
|
||||||
|
|
||||||
* `select <credentialField> from <userTable>
|
[source,sql]
|
||||||
where <userField> =?`
|
----
|
||||||
* `select <userRoleRoleField> from
|
select <credentialField> from <userTable>
|
||||||
<userRoleTable> where <userRoleUserField>
|
where <userField> =?
|
||||||
=?`
|
select <userRoleRoleField> from <userRoleTable>
|
||||||
|
where <userRoleUserField> =?
|
||||||
|
----
|
||||||
|
|
||||||
Credential and role information is lazily read from the database when a
|
Credential and role information is lazily read from the database when a previously unauthenticated user requests authentication.
|
||||||
previously unauthenticated user requests authentication. Note that this
|
Note that this information is _only_ cached for the length of the authenticated session.
|
||||||
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.
|
||||||
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
|
Note that passwords can be stored in the database in plain text or encoded formats - see the note on "Passwords/Credentials" above.
|
||||||
encoded formats - see "Passwords/Credentials" note above.
|
|
||||||
|
|
||||||
===== DataSourceLoginModule
|
===== DataSourceLoginModule
|
||||||
|
|
||||||
Similar to the JDBCLoginModule, but this LoginModule uses a DataSource
|
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 performing a JNDI lookup on `java:comp/env/${dnJNDIName}`.
|
||||||
to connect to the database instead of a jdbc driver. The DataSource is
|
|
||||||
obtained by doing a jndi lookup on `java:comp/env/${dnJNDIName}`
|
|
||||||
|
|
||||||
Here is a sample login module configuration for it:
|
A sample login module configuration using this method:
|
||||||
|
|
||||||
[source,ini]
|
[source,ini]
|
||||||
----
|
----
|
||||||
|
@ -377,12 +304,10 @@ ds {
|
||||||
|
|
||||||
===== PropertyFileLoginModule
|
===== PropertyFileLoginModule
|
||||||
|
|
||||||
With this login module implementation, the authentication and role
|
With this login module implementation, the authentication and role information is read from a property file.
|
||||||
information is read from a property file.
|
|
||||||
|
|
||||||
[source,ini]
|
[source,ini]
|
||||||
----
|
----
|
||||||
|
|
||||||
props {
|
props {
|
||||||
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
|
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
|
||||||
debug="true"
|
debug="true"
|
||||||
|
@ -390,12 +315,11 @@ props {
|
||||||
};
|
};
|
||||||
----
|
----
|
||||||
|
|
||||||
The file parameter is the location of a properties file of the same
|
The file parameter is the location of a properties file of the same format as the `etc/realm.properties` example file.
|
||||||
format as the etc/realm.properties example file. The format is:
|
The format is:
|
||||||
|
|
||||||
[source,text]
|
[source,text]
|
||||||
----
|
----
|
||||||
|
|
||||||
<username>: <password>[,<rolename> ...]
|
<username>: <password>[,<rolename> ...]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -403,15 +327,13 @@ Here's an example:
|
||||||
|
|
||||||
[source,ini]
|
[source,ini]
|
||||||
----
|
----
|
||||||
|
|
||||||
fred: OBF:1xmk1w261u9r1w1c1xmq,user,admin
|
fred: OBF:1xmk1w261u9r1w1c1xmq,user,admin
|
||||||
harry: changeme,user,developer
|
harry: changeme,user,developer
|
||||||
tom: MD5:164c88b302622e17050af52c89945d44,user
|
tom: MD5:164c88b302622e17050af52c89945d44,user
|
||||||
dick: CRYPT:adpexzg3FUZAk,admin
|
dick: CRYPT:adpexzg3FUZAk,admin
|
||||||
----
|
----
|
||||||
|
|
||||||
The contents of the file are fully read in and cached in memory the
|
The contents of the file are fully read in and cached in memory the first time a user requests authentication.
|
||||||
first time a user requests authentication.
|
|
||||||
|
|
||||||
===== LdapLoginModule
|
===== LdapLoginModule
|
||||||
|
|
||||||
|
@ -444,47 +366,28 @@ ldaploginmodule {
|
||||||
|
|
||||||
==== Writing your Own LoginModule
|
==== Writing your Own LoginModule
|
||||||
|
|
||||||
If you want to implement your own custom LoginModule, there are two
|
If you want to implement your own custom `LoginModule`, there are two classes to be familiar with: `org.eclipse.jetty.jaas.spi.AbstractLoginModule` and `org.eclipse.jetty.jaas.spi.UserInfo`.
|
||||||
classes to be familiar with
|
|
||||||
`org.eclipse.jetty.jaas.spi.AbstractLoginModule` and
|
|
||||||
`org.eclipse.jetty.jaas.spi.UserInfo`.
|
|
||||||
|
|
||||||
The `org.eclipse.jetty.jaas.spi.AbstractLoginModule` implements all of
|
The `org.eclipse.jetty.jaas.spi.AbstractLoginModule` implements all of the `javax.security.auth.spi.LoginModule` methods.
|
||||||
the `javax.security.auth.spi.LoginModule` methods. All you need to do is
|
All you need to do is to implement the `getUserInfo` method to return a `org.eclipse.jetty.jaas.UserInfo` instance which encapsulates the username, password and role names (note: as `java.lang.Strings`) for a user.
|
||||||
to implement the getUserInfo method to return a
|
|
||||||
`org.eclipse.jetty.jaas.UserInfo` instance which encapsulates the
|
|
||||||
username, password and role names (note: as java.lang.Strings) for a
|
|
||||||
user.
|
|
||||||
|
|
||||||
The AbstractLoginModule does not support any caching, so if you want to
|
The `AbstractLoginModule` does not support any caching, so if you want to cache UserInfo (eg as does the `org.eclipse.jetty.jaas.spi.PropertyFileLoginModule`) then you must provide this yourself.
|
||||||
cache UserInfo (eg as does the
|
|
||||||
`org.eclipse.jetty.jaas.spi.PropertyFileLoginModule`) then you must
|
|
||||||
provide this yourself.
|
|
||||||
|
|
||||||
==== Other Goodies
|
==== Other Goodies
|
||||||
|
|
||||||
===== RequestParameterCallback
|
===== RequestParameterCallback
|
||||||
|
|
||||||
As all servlet containers intercept and process a form submission with
|
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 `j_username` and `j_password`.
|
||||||
action j_security_check, it is usually not possible to insert any extra
|
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 `org.eclipse.jetty.jaas.callback.RequestParameterCallback`.
|
||||||
input fields onto a login form with which to perform authentication: you
|
This callback handler gives you access to all parameters that were passed in the form submission.
|
||||||
may only pass `j_username` and `j_password`. For those rare occasions
|
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.
|
||||||
when this is not good enough, and you require more information from the
|
Here is an example:
|
||||||
user in order to authenticate them, you can use the JAAS callback
|
|
||||||
handler `org.eclipse.jetty.jaas.callback.RequestParameterCallback`. 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:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
||||||
public class FooLoginModule extends AbstractLoginModule
|
public class FooLoginModule extends AbstractLoginModule
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public boolean login()
|
public boolean login()
|
||||||
throws LoginException
|
throws LoginException
|
||||||
{
|
{
|
||||||
|
@ -497,7 +400,7 @@ public class FooLoginModule extends AbstractLoginModule
|
||||||
//use one RequestParameterCallback() instance for each param you want to access
|
//use one RequestParameterCallback() instance for each param you want to access
|
||||||
callbacks[2] = new RequestParameterCallback ();
|
callbacks[2] = new RequestParameterCallback ();
|
||||||
((RequestParameterCallback)callbacks[2]).setParameterName ("extrainfo");
|
((RequestParameterCallback)callbacks[2]).setParameterName ("extrainfo");
|
||||||
|
|
||||||
|
|
||||||
callbackHandler.handle(callbacks);
|
callbackHandler.handle(callbacks);
|
||||||
String userName = ((NameCallback)callbacks[0]).getName();
|
String userName = ((NameCallback)callbacks[0]).getName();
|
||||||
|
@ -508,12 +411,11 @@ public class FooLoginModule extends AbstractLoginModule
|
||||||
//authenticate the user
|
//authenticate the user
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
===== Example JAAS WebApp
|
===== Example JAAS WebApp
|
||||||
|
|
||||||
An example webapp using jaas can be found in our git repo:
|
An example webapp using JAAS can be found in the Jetty GitHub repository:
|
||||||
|
|
||||||
* link:{GITBROWSEURL}/tests/test-webapps/test-jaas-webapp[https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jaas-webapp]
|
* link:{GITBROWSEURL}/tests/test-webapps/test-jaas-webapp[https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jaas-webapp]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,46 +18,36 @@
|
||||||
=== Using the $\{jetty.home} and $\{jetty.base} Concepts to Configure
|
=== Using the $\{jetty.home} and $\{jetty.base} Concepts to Configure
|
||||||
Security
|
Security
|
||||||
|
|
||||||
Jetty 9.1 introduces `${jetty.base}` and `${jetty.home}`.
|
Jetty 9.1 introduced `${jetty.base}` and `${jetty.home}`.
|
||||||
|
|
||||||
* `${jetty.home}` is the directory location for the jetty distribution
|
* `${jetty.home}` is the directory location for the jetty distribution (the binaries).
|
||||||
(the binaries).
|
* `${jetty.base}` is the directory location for your customizations to the distribution.
|
||||||
* `${jetty.base}` is the directory location for your customizations to
|
|
||||||
the distribution.
|
|
||||||
|
|
||||||
This separation:
|
This separation:
|
||||||
|
|
||||||
* Allows you to manage multiple Jetty installations.
|
* Allows you to manage multiple Jetty installations.
|
||||||
* Makes it simple to retain your current configuration when you upgrade
|
* Makes it simple to retain your current configuration when you upgrade your Jetty distribution.
|
||||||
your Jetty distribution.
|
|
||||||
|
|
||||||
For more information, see xref:startup-base-and-home[].
|
For more information, see xref:startup-base-and-home[].
|
||||||
|
|
||||||
Further, Jetty 9.1 parameterizes all of the standard configuration XMLs.
|
Further, Jetty 9.1 parameterized all of the standard configuration XMLs.
|
||||||
For SSL, parameters are now just properties in the `start.ini`, reducing
|
For SSL, parameters are now properties in the `start.ini` or `start.d\ssl.ini`, reducing to eliminating the need to edit XML files.
|
||||||
to eliminating the need to edit XML files.
|
|
||||||
|
|
||||||
Jetty 9.1 also introduces modules. Instead of explicitly listing all the
|
Instead of explicitly listing all the libraries, properties, and XML files for a feature, Jetty 9.1 introduced a new module system.
|
||||||
libraries, properties, and XML files for a feature, Jetty includes
|
A module is defined in a `modules/*.mod` file, including the libraries, dependencies, XML, and template INI files for a Jetty feature.
|
||||||
software modules, and the `start.jar` mechanism allows you to create new
|
Thus you can use a single `--module=name` command line option as the equivalent of specifying many `--lib=location, feature.xml, name=value` arguments for a feature and all its dependencies.
|
||||||
modules. You define a module in a `modules/*.mod` file, including the
|
Modules use their dependencies to control the ordering of libraries and XML files.
|
||||||
libraries, dependencies, XML, and template INI files for a Jetty
|
For more information, see xref:startup-modules[].
|
||||||
feature. Thus you can use a single `--module=name` command line option
|
|
||||||
as the equivalent of specifying many `--lib=location, feature.xml,
|
|
||||||
name=value` arguments for a feature and all its dependencies. Modules
|
|
||||||
use their dependencies to control the ordering of libraries and XML
|
|
||||||
files. For more information, see xref:startup-modules[].
|
|
||||||
|
|
||||||
[[configuring-security-jetty91]]
|
[[configuring-security-jetty91]]
|
||||||
==== Configuring SSL in with modules
|
==== Configuring SSL in with modules
|
||||||
|
|
||||||
This page describes how to configure SSL in Jetty with modules. It
|
This page describes how to configure SSL in Jetty with modules.
|
||||||
provides an example of using the `${jetty.home}` and `${jetty.base}` to
|
It provides an example of using the `${jetty.home}` and `${jetty.base}` to maximum effect.
|
||||||
maximum effect. It also includes a detailed explanation of how modules
|
It also includes a detailed explanation of how modules work.
|
||||||
work.
|
|
||||||
|
|
||||||
This example assumes you have the jetty-distribution unpacked in
|
This example assumes you have the jetty-distribution unpacked in `/home/user/jetty-distribution-{VERSION}`.
|
||||||
`/home/user/jetty-distribution-{VERSION}.`
|
It also assumes you are using `start.ini` to configure your server features.
|
||||||
|
|
||||||
1. Create a base directory anywhere.
|
1. Create a base directory anywhere.
|
||||||
+
|
+
|
||||||
|
@ -67,6 +57,7 @@ This example assumes you have the jetty-distribution unpacked in
|
||||||
[/home/user]$ cd my-base
|
[/home/user]$ cd my-base
|
||||||
....
|
....
|
||||||
2. Add the modules for SSL, HTTP, and webapp deployment.
|
2. Add the modules for SSL, HTTP, and webapp deployment.
|
||||||
|
Adding modules in this way will append the associated module properties to the `${jetty.base}/start.ini` file.
|
||||||
+
|
+
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
....
|
||||||
|
@ -214,7 +205,7 @@ Properties:
|
||||||
Jetty Server Classpath:
|
Jetty Server Classpath:
|
||||||
-----------------------
|
-----------------------
|
||||||
Version Information on 11 entries in the classpath.
|
Version Information on 11 entries in the classpath.
|
||||||
Note: order presented here is how they would appear on the classpath.
|
: order presented here is how they would appear on the classpath.
|
||||||
changes to the --module=name command line options will be reflected here.
|
changes to the --module=name command line options will be reflected here.
|
||||||
0: 3.1.0 | ${jetty.home}/lib/servlet-api-3.1.jar
|
0: 3.1.0 | ${jetty.home}/lib/servlet-api-3.1.jar
|
||||||
1: 3.1.RC0 | ${jetty.home}/lib/jetty-schemas-3.1.jar
|
1: 3.1.RC0 | ${jetty.home}/lib/jetty-schemas-3.1.jar
|
||||||
|
@ -262,9 +253,7 @@ First notice the separation of `${jetty.base}` and `${jetty.home}`.
|
||||||
[[modules]]
|
[[modules]]
|
||||||
===== Modules
|
===== Modules
|
||||||
|
|
||||||
Notice that you have `--module=<name>` here and there; you have wrapped
|
Notice that you have `--module=<name>` here and there; you have wrapped up the goal of a module (libs, configuration XMLs, and properties) into a single unit, with dependencies on other modules.
|
||||||
up the goal of a module (libs, configuration XMLs, and properties) into
|
|
||||||
a single unit, with dependencies on other modules.
|
|
||||||
|
|
||||||
You can see the list of modules:
|
You can see the list of modules:
|
||||||
|
|
||||||
|
@ -449,12 +438,9 @@ Jetty Active Module Tree:
|
||||||
+ Module: deploy [enabled]
|
+ Module: deploy [enabled]
|
||||||
....
|
....
|
||||||
|
|
||||||
These are the modules by name, the libraries they bring in, the XML
|
These are the modules by name, the libraries they bring in, the XML configurations they use, the other modules they depend on (even optional ones), and if the module is in use, where it was enabled.
|
||||||
configurations they use, the other modules they depend on (even optional
|
|
||||||
ones), and if the module is in use, where it was enabled.
|
|
||||||
|
|
||||||
While you can manage the list of active modules yourself, it is much
|
While you can manage the list of active modules yourself, it is much easier to edit the `${jetty.base}/start.ini`.
|
||||||
easier to edit the `${jetty.base}/start.ini`.
|
|
||||||
|
|
||||||
If you want to start using a new module:
|
If you want to start using a new module:
|
||||||
|
|
||||||
|
@ -463,71 +449,58 @@ If you want to start using a new module:
|
||||||
[my-base] $ java -jar ../jetty-distribution-{VERSION}/start.jar --add-to-start=https
|
[my-base] $ java -jar ../jetty-distribution-{VERSION}/start.jar --add-to-start=https
|
||||||
....
|
....
|
||||||
|
|
||||||
This adds the `--module=` lines and associated properties (the
|
This adds the `--module=` lines and associated properties (the parameterized values mentioned above), to your `start.ini`.
|
||||||
parameterized values mentioned above), to your `start.ini`.
|
|
||||||
|
|
||||||
____
|
____
|
||||||
[IMPORTANT]
|
[IMPORTANT]
|
||||||
Leave the modules and XML files alone in the `${jetty.home}` directory; there is no need to be moving or copying them unless you want to make your own modules or override the behavior of an existing module.
|
Do not edit the modules and XML files in the `${jetty.home}` directory; there is no need to be moving or copying them unless you want to make your own modules or override the behavior of an existing module.
|
||||||
____
|
____
|
||||||
|
|
||||||
Notice that your `${jetty.base}/start.ini` has no references to the XML
|
Notice that your `${jetty.base}/start.ini` has no references to the XML files.
|
||||||
files. That's because the module system and its graph of dependencies
|
That's because the module system and its graph of dependencies now dictate all of the XML files, and their load order.
|
||||||
now dictate all of the XML files, and their load order.
|
|
||||||
|
|
||||||
[[parameterizing]]
|
[[parameterizing]]
|
||||||
===== Parameters
|
===== Parameters
|
||||||
|
|
||||||
Next is parameterizing all of the standard configuration XMLs. In this
|
Next is parameterizing all of the standard configuration XMLs.
|
||||||
example all of the SSL parameters are now just properties in the
|
In this example all of the SSL parameters are now just properties in the `start.ini`, reducing or eliminating the need to edit XML files.
|
||||||
`start.ini`, reducing or eliminating the need to edit XML files.
|
|
||||||
|
|
||||||
[[override-jetty.home]]
|
[[override-jetty.home]]
|
||||||
===== Overriding $\{jetty.home} in $\{jetty.base}
|
===== Overriding $\{jetty.home} in $\{jetty.base}
|
||||||
|
|
||||||
Finally, you can override anything you see in `${jetty.home}` in
|
Finally, you can override anything you see in `${jetty.home}` in `${jetty.base}`, even XML configurations and libraries.
|
||||||
`${jetty.base}`, even XML configurations and libraries.
|
|
||||||
|
|
||||||
For more information on the `start.jar` in 9.1, see xref:start-jar[].
|
For more information on the `start.jar` in 9.1, see xref:start-jar[].
|
||||||
|
|
||||||
[[summary-configuring-SSL-Jetty-91]]
|
[[summary-configuring-SSL-Jetty]]
|
||||||
==== Summary of Configuring SSL in Jetty 9.1
|
==== Summary of Configuring SSL
|
||||||
|
|
||||||
1. Download and unpack Jetty 9.1 into
|
1. Download and unpack Jetty into `/home/user/jetty-distribution-{VERSION}`.
|
||||||
`/home/user/jetty-distribution-{VERSION}`.
|
|
||||||
2. Go to your base directory and just use the distribution, no editing.
|
2. Go to your base directory and just use the distribution, no editing.
|
||||||
+
|
+
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
....
|
||||||
[my-base]$ java -jar /home/user/jetty-distribution-{VERSION}/start.jar
|
[my-base]$ java -jar /home/user/jetty-distribution-{VERSION}/start.jar
|
||||||
....
|
....
|
||||||
* The Jetty 9.1 distribution provides, out of the box, the XML
|
* The Jetty distribution provides, out of the box, the XML configuration files, in this case `jetty-http.xml` and `jetty-ssl.xml`.
|
||||||
configuration files, in this case `jetty-http.xml` and `jetty-ssl.xml`.
|
These can be found in the `${jetty.home}/etc/` directory.
|
||||||
You can find them in `${jetty.home}/etc/` directory.
|
|
||||||
* We have parameterized all of the configurable values in those XMLs.
|
* We have parameterized all of the configurable values in those XMLs.
|
||||||
You can now set the values using simple properties, either on the
|
You can now set the values using simple properties, either on the command line, or within the `${jetty.base}/start.ini`.
|
||||||
command line, or within the `${jetty.base}/start.ini`.
|
* When you activate the module for HTTP or HTTPs, Jetty automatically adds the appropriate libraries and XML to start Jetty.
|
||||||
* When you activate the module for HTTP or HTTPs, Jetty automatically
|
Unless you have a highly custom setup (such as listening on two different ports, using SSL on each, each with its own keystore and configuration), there is no need to muck around in XML files.
|
||||||
adds the appropriate libraries and XML to start Jetty. Unless you have a
|
|
||||||
highly custom setup (such as listening on two different ports, using SSL
|
|
||||||
on each, each with its own keystore and configuration), you should have
|
|
||||||
no need to be mucking around in XML files.
|
|
||||||
3. Use modules to configure HTTPS:
|
3. Use modules to configure HTTPS:
|
||||||
* http -> server
|
* http -> server
|
||||||
* https -> ssl -> server
|
* https -> ssl -> server
|
||||||
+
|
+
|
||||||
You can find the details about the modules in `${jetty.home}/modules/`.
|
You can find the details about the modules in `${jetty.home}/modules/`.
|
||||||
For SSL they include `modules/http.mod`, `modules/https.mod`,
|
For SSL they include `modules/http.mod`, `modules/https.mod`, `modules/ssl.mod`, and `modules/server.mod`.
|
||||||
`modules/ssl.mod`, and `modules/server.mod`.
|
|
||||||
+
|
+
|
||||||
Ideally, this level of detail is not important to you. What is important
|
Ideally, this level of detail is not important to you.
|
||||||
is that you want to use HTTPS and want to configure it. You accomplish
|
What is important is that you want to use HTTPS and want to configure it.
|
||||||
that by adding the `--module=https` to your `start.ini`. By default, the
|
You accomplish that by adding the `--module=https` to your `start.ini`.
|
||||||
module system keeps things sane, and transitively includes all dependent
|
By default, the module system keeps things sane, and transitively includes all dependent modules as well.
|
||||||
modules as well.
|
|
||||||
|
|
||||||
You can see what the configuration looks like, after all of the modules
|
You can see what the configuration looks like, after all of the modules are resolved, without starting Jetty via:
|
||||||
are resolved, without starting Jetty via:
|
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
....
|
||||||
|
@ -537,9 +510,9 @@ are resolved, without starting Jetty via:
|
||||||
Just because the JARs exist on disk does not mean that they are in use.
|
Just because the JARs exist on disk does not mean that they are in use.
|
||||||
The configuration controls what is used.
|
The configuration controls what is used.
|
||||||
|
|
||||||
Use the `--list-config` to see the configuration. Notice that only a
|
Use the `--list-config` to see the configuration.
|
||||||
subset of the JARs from the distribution are in use. The modules you
|
Notice that only a subset of the JARs from the distribution are in use.
|
||||||
have anabled determine that subset.
|
The modules you have enabled determine that subset.
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
....
|
||||||
|
|
|
@ -17,24 +17,16 @@
|
||||||
[[configuring-security-secure-passwords]]
|
[[configuring-security-secure-passwords]]
|
||||||
=== Secure Password Obfuscation
|
=== Secure Password Obfuscation
|
||||||
|
|
||||||
There are many places where you might want to use and store a password,
|
There are many places where you might want to use and store a password, for example for the SSL connectors and user passwords in realms.
|
||||||
for example for the SSL connectors and user passwords in realms.
|
|
||||||
|
|
||||||
Passwords can be stored in clear text, obfuscated, checksummed or
|
Passwords can be stored in clear text, obfuscated, checksummed or encrypted in order of increasing security.
|
||||||
encrypted in order of increasing security. The choice of method to
|
The choice of method to secure a password depends on where you are using the password.
|
||||||
secure a password depends on where you are using the password. In some
|
In some cases such as keystore passwords and digest authentication, the system must retrieve the original password, which requires the obfuscation method.
|
||||||
cases such as keystore passwords and digest authentication, the system
|
The drawback of the obfuscation algorithm is that it protects passwords from casual viewing only.
|
||||||
must retrieve the original password, which requires the obfuscation
|
|
||||||
method. The drawback of the obfuscation algorithm is that it protects
|
|
||||||
passwords from casual viewing only.
|
|
||||||
|
|
||||||
When the stored password is compared to one a user enters, the handling
|
When the stored password is compared to one a user enters, the handling code can apply the same algorithm that secures the stored password to the user input and compare results, making password authentication more secure.
|
||||||
code can apply the same algorithm that secures the stored password to
|
|
||||||
the user input and compare results, making password authentication more
|
|
||||||
secure.
|
|
||||||
|
|
||||||
The class `org.eclipse.jetty.util.security.Password` can be used to
|
The class `org.eclipse.jetty.util.security.Password` can be used to generate all varieties of passwords.
|
||||||
generate all varieties of passwords.
|
|
||||||
|
|
||||||
Run it without arguments to see usage instructions:
|
Run it without arguments to see usage instructions:
|
||||||
|
|
||||||
|
@ -47,11 +39,9 @@ $ java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Pas
|
||||||
Usage - java org.eclipse.jetty.util.security.Password [<user>] <password>
|
Usage - java org.eclipse.jetty.util.security.Password [<user>] <password>
|
||||||
If the password is ?, the user will be prompted for the password
|
If the password is ?, the user will be prompted for the password
|
||||||
|
|
||||||
|
|
||||||
....
|
....
|
||||||
|
|
||||||
For example, to generate a secured version of the password "blah" for
|
For example, to generate a secured version of the password "blah" for the user "me":
|
||||||
the user "me", do:
|
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
....
|
||||||
|
@ -63,15 +53,11 @@ OBF:20771x1b206z
|
||||||
MD5:639bae9ac6b3e1a84cebb7b403297b79
|
MD5:639bae9ac6b3e1a84cebb7b403297b79
|
||||||
CRYPT:me/ks90E221EY
|
CRYPT:me/ks90E221EY
|
||||||
|
|
||||||
|
|
||||||
....
|
....
|
||||||
|
|
||||||
You can now cut and paste whichever secure version you choose into your
|
You can now cut and paste whichever secure version you choose into your configuration file or Java code.
|
||||||
configuration file or java code.
|
|
||||||
|
|
||||||
For example, the last line below shows how you would cut and paste the
|
For example, the last line below shows how you would implement the encrypted password generated above into the properties file for a `LoginService`:
|
||||||
encrypted password generated above into the properties file for a
|
|
||||||
`LoginService`:
|
|
||||||
|
|
||||||
[source,bash]
|
[source,bash]
|
||||||
----
|
----
|
||||||
|
@ -81,7 +67,6 @@ other: OBF:1xmk1w261u9r1w1c1xmq
|
||||||
guest: guest,read-only
|
guest: guest,read-only
|
||||||
me:CRYPT:me/ks90E221EY
|
me:CRYPT:me/ks90E221EY
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
____
|
____
|
||||||
|
@ -89,9 +74,8 @@ ____
|
||||||
Don't forget to also copy the OBF:, MD5: or CRYPT: prefix on the generated password. It will not be usable by Jetty without it.
|
Don't forget to also copy the OBF:, MD5: or CRYPT: prefix on the generated password. It will not be usable by Jetty without it.
|
||||||
____
|
____
|
||||||
|
|
||||||
You can also use obfuscated passwords in jetty xml files where a plain
|
You can also use obfuscated passwords in jetty xml files where a plain text password is usually needed.
|
||||||
text password is usually needed. Here's an example setting the password
|
Here's an example setting the password for a JDBC Datasource with obfuscation:
|
||||||
for a JDBC Datasource with obfuscation:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -116,7 +100,5 @@ for a JDBC Datasource with obfuscation:
|
||||||
</New>
|
</New>
|
||||||
</Arg>
|
</Arg>
|
||||||
</New>
|
</New>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,104 +17,61 @@
|
||||||
[[serving-aliased-files]]
|
[[serving-aliased-files]]
|
||||||
=== Aliased Files and Symbolic links
|
=== Aliased Files and Symbolic links
|
||||||
|
|
||||||
Web applciations will often server static content from the file system
|
Web applications will often server static content from the file system provided by the operating system running underneath the JVM.
|
||||||
provided by the operating system running underneatth the JVM. However
|
However because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings my inadvertently be bypassed by aliases.
|
||||||
because file systems often implement multiple aliased names for the same
|
|
||||||
file, then security constraints and other servlet URI space mappings my
|
|
||||||
inadvertantly be bypassed by aliases.
|
|
||||||
|
|
||||||
I key example of this is case insensitivety and 8.3 names implemented by
|
A key example of this is case insensitivity and 8.3 filenames implemented by the Windows file system.
|
||||||
the Windows File system. If a file within a webapplication called
|
If a file within a web application called `/mysecretfile.txt` is protected by a security constraint on the URI `/mysecretfile.txt`, then a request to `/MySecretFile.TXT` will not match the URI constraint because URIs are case sensitive, but the Windows file system will report that a file does exist at that name and it will be served despite the security constraint.
|
||||||
`/mysecretfile.txt` is protected by a security constraint on the URI
|
Less well known than case insensitivity is that Windows files systems also support http://en.wikipedia.org/wiki/8.3_filename[8.3 filenames] for compatibility with legacy programs.
|
||||||
` /mysecretfile.txt`, then a request to `/MySecretFile.TXT` will not
|
Thus a request to a URI like `/MYSECR~1.TXT` will again not match the security constraint, but will be reported as an existing file by the file system and served.
|
||||||
match the URI constraint because URIs are case sensitive, but the
|
|
||||||
windows file system will report that a file does exist at that name and
|
|
||||||
it will be served despite the security constraint. Less well known than
|
|
||||||
case insensitivity is that windows files systems also support
|
|
||||||
http://en.wikipedia.org/wiki/8.3_filename[8.3 filenames] for
|
|
||||||
compatibility with legacy programs. Thus a request to a URI like
|
|
||||||
`/MYSECR~1.TXT` will again not match the security constraint, but will
|
|
||||||
be reported as an existing file by the file system and served.
|
|
||||||
|
|
||||||
There are many examples of aliases, not just on windows:
|
There are many examples of aliases, not just on Windows:
|
||||||
|
|
||||||
* NTFS Alternate stream names like c:\test\file.txt::$DATA:name
|
* NTFS Alternate stream names like `c:\test\file.txt::$DATA:name`
|
||||||
* OpenVMS support file versionig so that `/mysecret.txt;N` refers to
|
* OpenVMS support file versionig so that `/mysecret.txt;N` refers to version N of `/mysecret.txt` and is essentially an alias.
|
||||||
version N of `
|
* The clearcase software configuration management system provides a file system where `@@` in a file name is an alias to a specific version.
|
||||||
/mysecret.txt` and is essentially an alias.
|
* The Unix files system supports `/./foo.txt` as and alias for `/foo.txt`
|
||||||
* The clearcase software configuration management system provides a file
|
* Many JVM implementations incorrectly assume the null character is a string terminator, so that a file name resulting from `/foobar.txt%00` is an alias for `/foobar.txt`
|
||||||
system where @@ in a file name is an alias to a specific version.
|
* Unix symbolic links and hard links are a form of aliases that allow the same file or directory to have multiple names.
|
||||||
* The unix files system supports `/./foo.txt` as and alias for
|
|
||||||
`/foo.txt`
|
|
||||||
* Many JVM implementations incorrectly assume the null character is a
|
|
||||||
string terminator, so that a file name resulting from `/foobar.txt%00`
|
|
||||||
is an alias for `/foobar.txt`
|
|
||||||
* Unix symbolic links and hard links are a form of aliases that allow
|
|
||||||
the same file or directory to have multiple names.
|
|
||||||
|
|
||||||
In addition, it is not just URI security constraints that can be
|
In addition, it is not just URI security constraints that can be bypassed. For example the mapping of the URI pattern `*.jsp` to the JSP
|
||||||
bypassed. For example the mapping of the URI pattern `*.jsp` to the JSP
|
Servlet may be bypassed by an a request to an alias like `/foobar.jsp%00`, thus rather than execute the JSP, the source code of the JSP is returned by the file system.
|
||||||
Servlet may be bypassed by an a request to an alias like `
|
|
||||||
/foobar.jsp%00`, thus rather than execute the JSP, the source code of
|
|
||||||
the JSP is returned by the file system.
|
|
||||||
|
|
||||||
==== Good Security Practise
|
==== Good Security Practise
|
||||||
|
|
||||||
Part of the problem with aliases is that the standard web application
|
Part of the problem with aliases is that the standard web application security model is to allow all requests except the ones that are specifically denied by security constraints.
|
||||||
security model is to allow all requests except the ones that are
|
A best practice for security is to deny all requests and to permit only those that are specifically identified as allowable.
|
||||||
specifically denied by security constraints. A best practise for
|
While it is possible to design web application security constraints in this style, it can be difficult in all circumstances and it is not the default. T
|
||||||
security is to deny all requests and to permit only those that are
|
hus it is important for Jetty to be able to detect and deny requests to aliased static content.
|
||||||
specifically identified as allowable. While it is possible to design web
|
|
||||||
application security constraints in this style, it can be difficult in
|
|
||||||
all circumstances and it is not the default. Thus it is important for
|
|
||||||
Jetty to be able to detect and deny requests to aliased static content.
|
|
||||||
|
|
||||||
[[file-alias-detection]]
|
[[file-alias-detection]]
|
||||||
==== Alias detection
|
==== Alias detection
|
||||||
|
|
||||||
It is impossible for Jetty to know of all the aliases that may be
|
It is impossible for Jetty to know of all the aliases that may be implemented by the file system running beneath it, thus it does not attempt to make any specific checks for any know aliases.
|
||||||
implemented by the file system running beneath it, thus it does not
|
Instead Jetty detects aliases by using the canonical path of a file.
|
||||||
attempt to make any specific checks for any know aliases. Instead jetty
|
If a file resource handled by jetty has a canonical name that differs from the name used to request the resource, then Jetty determines that the resource is an aliased request and it will not be returned by the `ServletContext.getResource(String)` method (or similar) and thus will not be served as static content nor used as the basis of a JSP.
|
||||||
detects aliases by using the canonical path of a file. If a file
|
|
||||||
resource handled by jetty has a canonical name that differs from the
|
|
||||||
name used to request the resource, then Jetty determines that the
|
|
||||||
resource is an aliased request and it will not be returned by the
|
|
||||||
`ServletContext.getResource(String)` method (or similar) and thus will
|
|
||||||
not be served as static content nor used as the basis of a JSP.
|
|
||||||
|
|
||||||
This if Jetty is running on a windows operation system, then a file
|
This if Jetty is running on a Windows operating system, then a file called `/MySecret.TXT` will have a canonical name that exactly matches that case.
|
||||||
called `/MySecret.TXT` will have a canonical name that exactly matches
|
So while a request to `/mysecret.txt` or `/MYSECR~1.TXT` will result in a File Resource that matches the file, the different canonical name will indicate that those requests are aliases and they will not be served as static content and instead a 404 response returned.
|
||||||
that case. So while a request to `/mysecret.txt` or ` /MYSECR~1.TXT`
|
|
||||||
will result in a File Resource that matches the file, the different
|
|
||||||
canonical name will indicate that those requests are aliases and they
|
|
||||||
will not be served as static content and instead a 404 response
|
|
||||||
returned.
|
|
||||||
|
|
||||||
Unfortunately this approach denies all aliases, including symbolic
|
Unfortunately this approach denies all aliases, including symbolic links, which can be useful in assembling complex web applications.
|
||||||
links, which can be useful in assembling complex web applications.
|
|
||||||
|
|
||||||
[[file-alias-serving]]
|
[[file-alias-serving]]
|
||||||
==== Serving Aliases and Symbolic Links
|
==== Serving Aliases and Symbolic Links
|
||||||
|
|
||||||
Not all aliases are bad nor should be seen as attempts to subvert
|
Not all aliases are bad nor should be seen as attempts to subvert security constraints.
|
||||||
security constraints. Specifically symbolic links can be very useful
|
Specifically symbolic links can be very useful when assembling complex web applications, yet by default Jetty will not serve them.
|
||||||
when assembling complex web applications, yet by default Jetty will not
|
Thus Jetty contexts support an extensible `AliasCheck` mechanism to allow aliases resources to be inspected an conditionally served.
|
||||||
serve them. Thus Jetty contexts support an extensible AliasCheck
|
In this way, "good" aliases can be detected and served.
|
||||||
mechanism to allow aliases resources to be inspected an conditionally
|
Jetty provides several utility implementations of the `AliasCheck` interface as nested classes with `ContextHandler`:
|
||||||
served. In this way, "good" aliases can be detected and served. Jetty
|
|
||||||
provides several utility implementations of the AliasCheck interface as
|
|
||||||
nested classes with ContextHandler:
|
|
||||||
|
|
||||||
ApproveAliases::
|
ApproveAliases::
|
||||||
Approve all aliases (USE WITH CAUTION!).
|
Approve all aliases (*Use with caution!*).
|
||||||
AllowSymLinkAliasChecker::
|
AllowSymLinkAliasChecker::
|
||||||
Approve Aliases using the java-7 Files.readSymbolicLink(path) and
|
Approve Aliases using the java-7 `Files.readSymbolicLink(path)` and `Path.toRealPath(...)` APIs to check that aliases are valid symbolic links.
|
||||||
Path.toRealPath(...) APIs to check that alias are valid symbolic
|
|
||||||
links.
|
|
||||||
|
|
||||||
An application is free to implement its own Alias checking. Alias
|
An application is free to implement its own Alias checking.
|
||||||
Checkers can be installed in a context via the following XML used in a
|
Alias Checkers can be installed in a context via the following XML used in a context deployer file or `WEB-INF/jetty-web.xml`:
|
||||||
context deployer file or `WEB-INF/jetty-web.xml`:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -122,5 +79,5 @@ context deployer file or `WEB-INF/jetty-web.xml`:
|
||||||
<Call name="addAliasCheck">
|
<Call name="addAliasCheck">
|
||||||
<Arg><New class="org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker"/></Arg>
|
<Arg><New class="org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker"/></Arg>
|
||||||
</Call>
|
</Call>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,47 +17,33 @@
|
||||||
[[spnego-support]]
|
[[spnego-support]]
|
||||||
=== Spnego Support
|
=== Spnego Support
|
||||||
|
|
||||||
Spnego or Simple and Protected GSSAPI Negotiation Mechanism is a way for
|
Simple and Protected GSSAPI Negotiation Mechanism (Spnego) is a way for users to be seamlessly authenticated when running on a Windows or Active Directory based network.
|
||||||
users to be seamlessly authenticated when running on a Windows or Active
|
Jetty supports this type of authentication and authorization through the JDK (which has been enabled since the later versions of Java 6 and 7).
|
||||||
Directory based network. Jetty supports this type of authentication and
|
Also important to note is that this is an _incredibly_ fragile setup where everything needs to be configured just right for things to work, otherwise it can fail in fun and exciting, not to mention obscure, ways.
|
||||||
authorization through the JDK so you must be using a JDK that supports
|
|
||||||
it, which recent versions of Java 6 and 7 do. Also important to note is
|
|
||||||
that this is an incredibly fragile setup where everything needs to be
|
|
||||||
configured just right for things to work, otherwise it can fail in fun
|
|
||||||
and exciting, not to mention obscure ways.
|
|
||||||
|
|
||||||
There is a substantial amount of configuration and testing required to
|
There is a substantial amount of configuration and testing required to enable this feature as well as knowledge and access to central systems on a Windows network such as the Active Domain Controller and the ability to create and maintain service users.
|
||||||
enable this feature as well as knowledge and access to central systems
|
|
||||||
on a Windows network such as the Active Domain Controller and the
|
|
||||||
ability to create and maintain service users.
|
|
||||||
|
|
||||||
==== Configuring Jetty and Spnego
|
==== Configuring Jetty and Spnego
|
||||||
|
|
||||||
To run with spengo enabled the following command line options are
|
To run with Spengo enabled the following command line options are required:
|
||||||
required:
|
|
||||||
|
|
||||||
....
|
|
||||||
|
|
||||||
|
[source,screen, subs="{sub-order}"]
|
||||||
|
----
|
||||||
-Djava.security.krb5.conf=/path/to/jetty/etc/krb5.ini \
|
-Djava.security.krb5.conf=/path/to/jetty/etc/krb5.ini \
|
||||||
-Djava.security.auth.login.config=/path/to/jetty/etc/spnego.conf \
|
-Djava.security.auth.login.config=/path/to/jetty/etc/spnego.conf \
|
||||||
-Djavax.security.auth.useSubjectCredsOnly=false
|
-Djavax.security.auth.useSubjectCredsOnly=false
|
||||||
|
----
|
||||||
|
|
||||||
....
|
|
||||||
|
|
||||||
For debugging the spengo authentication the following options are very
|
For debugging the Spengo authentication the following options are very helpful:
|
||||||
helpful:
|
|
||||||
|
|
||||||
....
|
|
||||||
|
|
||||||
|
[source,screen, subs="{sub-order}"]
|
||||||
|
----
|
||||||
-Dorg.eclipse.jetty.LEVEL=debug \
|
-Dorg.eclipse.jetty.LEVEL=debug \
|
||||||
-Dsun.security.spnego.debug=all
|
-Dsun.security.spnego.debug=all
|
||||||
|
----
|
||||||
|
|
||||||
|
Spengo Authentication must be enabled in the webapp in the following way.
|
||||||
....
|
The name of the role will be different for your network.
|
||||||
|
|
||||||
Spengo Authentication must be enabled in the webapp in the following
|
|
||||||
way. The name of the role will be different for your network.
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -69,7 +55,7 @@ way. The name of the role will be different for your network.
|
||||||
</web-resource-collection>
|
</web-resource-collection>
|
||||||
<auth-constraint>
|
<auth-constraint>
|
||||||
<!-- this is the domain that the user is a member of -->
|
<!-- this is the domain that the user is a member of -->
|
||||||
<role-name>MORTBAY.ORG</role-name>
|
<role-name>MORTBAY.ORG</role-name>
|
||||||
</auth-constraint>
|
</auth-constraint>
|
||||||
</security-constraint>
|
</security-constraint>
|
||||||
<login-config>
|
<login-config>
|
||||||
|
@ -81,13 +67,11 @@ way. The name of the role will be different for your network.
|
||||||
</spnego-login-config>
|
</spnego-login-config>
|
||||||
</login-config>
|
</login-config>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
A corresponding UserRealm needs to be created either programmatically if
|
A corresponding `UserRealm` needs to be created either programmatically if embedded, via the `jetty.xml` or in a context file for the webapp.
|
||||||
embedded, via the jetty.xml or in a context file for the webapp.
|
|
||||||
|
|
||||||
This is what the configuration within a jetty xml file would look like.
|
This is what the configuration within a Jetty xml file would look like.
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -101,11 +85,9 @@ This is what the configuration within a jetty xml file would look like.
|
||||||
</Arg>
|
</Arg>
|
||||||
</Call>
|
</Call>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
This is what the configuration within a context xml file would look
|
This is what the configuration within a context xml file would look like.
|
||||||
like.
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -113,7 +95,7 @@ like.
|
||||||
<Get name="securityHandler">
|
<Get name="securityHandler">
|
||||||
<Set name="loginService">
|
<Set name="loginService">
|
||||||
<New class="org.eclipse.jetty.security.SpnegoLoginService">
|
<New class="org.eclipse.jetty.security.SpnegoLoginService">
|
||||||
<Set name="name">Test Realm</Set>
|
<Set name="name">Test Realm</Set>
|
||||||
<Set name="config">
|
<Set name="config">
|
||||||
<SystemProperty name="jetty.home" default="."/>/etc/spnego.properties
|
<SystemProperty name="jetty.home" default="."/>/etc/spnego.properties
|
||||||
</Set>
|
</Set>
|
||||||
|
@ -122,12 +104,11 @@ like.
|
||||||
<Set name="checkWelcomeFiles">true</Set>
|
<Set name="checkWelcomeFiles">true</Set>
|
||||||
</Get>
|
</Get>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
There are a number of important configuration files with spnego that are
|
There are a number of important configuration files with S3pnego that are required. The default values for these configuration files from this
|
||||||
required. The default values for these configuration files from this
|
test example are found in the `/etc` folder of the Jetty distribution.
|
||||||
test example are found in the jetty-distribution.
|
|
||||||
|
|
||||||
spnego.properties::
|
spnego.properties::
|
||||||
configures the user realm with runtime properties
|
configures the user realm with runtime properties
|
||||||
|
@ -136,70 +117,55 @@ krb5.ini::
|
||||||
spnego.conf::
|
spnego.conf::
|
||||||
configures the glue between gssapi and kerberos
|
configures the glue between gssapi and kerberos
|
||||||
|
|
||||||
It is important to note that the keytab file referenced in the krb5.ini
|
It is important to note that the keytab file referenced in the `krb5.ini` and the `spengo.conf` files needs to contain the keytab for the `targetName` for the http server.
|
||||||
and the spengo.conf files needs to contain the keytab for the targetName
|
To do this use a process similar to this:
|
||||||
for the http server. To do this use a process similar to this:
|
|
||||||
|
|
||||||
On the windows active domain controller run:
|
On the Windows Active Domain Controller run:
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
----
|
||||||
|
|
||||||
$ setspn -A HTTP/linux.mortbay.org ADUser
|
$ setspn -A HTTP/linux.mortbay.org ADUser
|
||||||
|
----
|
||||||
|
|
||||||
....
|
|
||||||
|
|
||||||
To create the keytab file use the following process:
|
To create the keytab file use the following process:
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
||||||
....
|
----
|
||||||
|
|
||||||
$ ktpass -out c:\dir\krb5.keytab -princ HTTP/linux.mortbay.org@MORTBAY.ORG -mapUser ADUser -mapOp set -pass ADUserPWD -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL
|
$ ktpass -out c:\dir\krb5.keytab -princ HTTP/linux.mortbay.org@MORTBAY.ORG -mapUser ADUser -mapOp set -pass ADUserPWD -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL
|
||||||
|
----
|
||||||
|
|
||||||
|
This step will give you the keytab file which should then be copied to the machine running the http server and referenced from the configuration files.
|
||||||
....
|
For our testing we put the keytab into the `/etc` directory of Jetty and referenced it from there.
|
||||||
|
|
||||||
This step should give you the keytab file which should then be copied
|
|
||||||
over to the machine running this http server and referenced from the
|
|
||||||
configuration files. For our testing we put the keytab into the etc
|
|
||||||
directory of jetty and referenced it from there.
|
|
||||||
|
|
||||||
==== Configuring Firefox
|
==== Configuring Firefox
|
||||||
|
|
||||||
The follows steps have been required to inform Firefox that it should
|
The follows steps have been required to inform Firefox that it should use a negotiation dialog to authenticate.
|
||||||
use a negotiation dialog to authenticate.
|
|
||||||
|
|
||||||
1. browse to about:config and agree to the warnings
|
1. Browse to about:config and agree to the warnings
|
||||||
2. search through to find the 'network' settings
|
2. Search through to find the 'network' settings
|
||||||
3. set network.negotiate-auth.delegation-uris to http://,https://
|
3. Set `network.negotiate-auth.delegation-uris` to http://,https://
|
||||||
4. set network.negotiate-auth.trusted-uris to http://,https://
|
4. Set `network.negotiate-auth.trusted-uris` to http://,https://
|
||||||
|
|
||||||
==== Configuring Internet Explorer
|
==== Configuring Internet Explorer
|
||||||
|
|
||||||
The follows steps have been required to inform Internet Explorer that it
|
The follows steps have been required to inform Internet Explorer that it should use a negotiation dialog to authenticate.
|
||||||
should use a negotiation dialog to authenticate.
|
|
||||||
|
|
||||||
1. Tools -> Options -> Security -> Local Intranet -> Sites (everything
|
1. Tools -> Options -> Security -> Local Intranet -> Sites (everything should be checked here)
|
||||||
should be checked here)
|
2. Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced (add url to server (http:// and/or https:// use the hostname!)
|
||||||
2. Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced
|
3. Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced -> Close
|
||||||
(add url to server (http:// and/or https:// use the hostname!)
|
|
||||||
3. Tools -> Options -> Security -> Local Intranet -> Sites -> Advanced
|
|
||||||
-> Close
|
|
||||||
4. Tools -> Options -> Security -> Local Intranet -> Sites -> Ok
|
4. Tools -> Options -> Security -> Local Intranet -> Sites -> Ok
|
||||||
5. Tools -> Options -> Advanced -> Security (in the checkbox list)
|
5. Tools -> Options -> Advanced -> Security (in the checkbox list)
|
||||||
6. locate and check 'Enable Integrated Windows Authentication'
|
6. Locate and check 'Enable Integrated Windows Authentication'
|
||||||
7. Tools -> Options -> Advanced -> Security -> Ok
|
7. Tools -> Options -> Advanced -> Security -> Ok
|
||||||
8. close IE then reopen and browse to your spengo protected resource
|
8. Close IE then reopen and browse to your Spengo protected resource
|
||||||
|
|
||||||
____
|
____
|
||||||
[NOTE]
|
[NOTE]
|
||||||
You must go to the hostname and not the IP, if you go to the IP it will default to NTLM authentication...the following conditions must be
|
You must go to the hostname and not the IP.
|
||||||
true for Spnego authentication to work.
|
If you go to the IP it will default to NTLM authentication...the following conditions must be true for Spnego authentication to work:
|
||||||
+
|
|
||||||
* You must be within the Intranet Zone of the network
|
* You must be within the Intranet Zone of the network
|
||||||
* Accessing the server using a Hostname rather then IP
|
* Accessing the server using a Hostname rather thAn IP
|
||||||
* Integrated Windows Authentication in IE is enabled and the host is trusted in Firefox
|
* Integrated Windows Authentication in IE is enabled and the host is trusted in Firefox
|
||||||
* The server is not local to the browser, it can't be running on localhost.
|
* The server is not local to the browser, it can't be running on localhost
|
||||||
* The client's Kerberos system is authenticated to a domain controller
|
* The client's Kerberos system is authenticated to a domain controller
|
||||||
____
|
____
|
||||||
|
|
|
@ -29,9 +29,11 @@ import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Symbolic Link AliasChecker.
|
|
||||||
|
/**
|
||||||
|
* Symbolic Link AliasChecker.
|
||||||
* <p>An instance of this class can be registered with {@link ContextHandler#addAliasCheck(AliasCheck)}
|
* <p>An instance of this class can be registered with {@link ContextHandler#addAliasCheck(AliasCheck)}
|
||||||
* to check resources that are aliased to other locations. The checker uses the
|
* to check resources that are aliased to other locations. The checker uses the
|
||||||
* Java {@link Files#readSymbolicLink(Path)} and {@link Path#toRealPath(java.nio.file.LinkOption...)}
|
* Java {@link Files#readSymbolicLink(Path)} and {@link Path#toRealPath(java.nio.file.LinkOption...)}
|
||||||
* APIs to check if a file is aliased with symbolic links.</p>
|
* APIs to check if a file is aliased with symbolic links.</p>
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +48,7 @@ public class AllowSymLinkAliasChecker implements AliasCheck
|
||||||
if (!(resource instanceof PathResource))
|
if (!(resource instanceof PathResource))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PathResource pathResource = (PathResource)resource;
|
PathResource pathResource = (PathResource) resource;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -56,62 +58,14 @@ public class AllowSymLinkAliasChecker implements AliasCheck
|
||||||
if (path.equals(alias))
|
if (path.equals(alias))
|
||||||
return false; // Unknown why this is an alias
|
return false; // Unknown why this is an alias
|
||||||
|
|
||||||
// is the file itself a symlink?
|
if (hasSymbolicLink(path) && Files.isSameFile(path, alias))
|
||||||
if (Files.isSymbolicLink(path))
|
|
||||||
{
|
|
||||||
alias = path.getParent().resolve(alias);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOG.debug("path ={}",path);
|
|
||||||
LOG.debug("alias={}",alias);
|
|
||||||
}
|
|
||||||
if (Files.isSameFile(path,alias))
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Allow symlink {} --> {}",resource,pathResource.getAliasPath());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No, so let's check each element ourselves
|
|
||||||
boolean linked=true;
|
|
||||||
Path target=path;
|
|
||||||
int loops=0;
|
|
||||||
while (linked)
|
|
||||||
{
|
|
||||||
if (++loops>100)
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Too many symlinks {} --> {}",resource,target);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
linked=false;
|
|
||||||
Path d = target.getRoot();
|
|
||||||
for (Path e:target)
|
|
||||||
{
|
|
||||||
Path r=d.resolve(e);
|
|
||||||
d=r;
|
|
||||||
|
|
||||||
while (Files.exists(d) && Files.isSymbolicLink(d))
|
|
||||||
{
|
|
||||||
Path link=Files.readSymbolicLink(d);
|
|
||||||
if (!link.isAbsolute())
|
|
||||||
link=d.getParent().resolve(link).normalize();
|
|
||||||
d=link;
|
|
||||||
linked=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
target=d;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathResource.getAliasPath().equals(target))
|
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Allow path symlink {} --> {}",resource,target);
|
LOG.debug("Allow symlink {} --> {}", resource, pathResource.getAliasPath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOG.ignore(e);
|
LOG.ignore(e);
|
||||||
}
|
}
|
||||||
|
@ -119,4 +73,26 @@ public class AllowSymLinkAliasChecker implements AliasCheck
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasSymbolicLink(Path path)
|
||||||
|
{
|
||||||
|
// Is file itself a symlink?
|
||||||
|
if (Files.isSymbolicLink(path))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lets try each path segment
|
||||||
|
Path base = path.getRoot();
|
||||||
|
for (Path segment : path)
|
||||||
|
{
|
||||||
|
base = base.resolve(segment);
|
||||||
|
if (Files.isSymbolicLink(base))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue