5.2. BASIC Authentication with JAAS
Overview
The HTTP BASIC authentication protocol is a simple username/password authentication mechanism that is integrated into HTTP and is supported by most Web browsers. To enable BASIC authentication in Jetty, you use the Jetty security API, which enables BASIC authentication by associating a security handler with the Jetty endpoint.
Jetty also enables you to plug in a JAAS login module to perform the credentials check. Using this feature, it is possible to integrate credentials checking with any JAAS realm provided by the Red Hat JBoss Fuse OSGi container. In the example shown here, the Jetty authentication is integrated with the default JAAS realm,
karaf
.
Prerequisites
This example builds on the project created in Section 5.1, “Enabling SSL/TLS Security”. You must complete the steps in the Jetty SSL/TLS example before proceeding with this tutorial.
Note
In any case, it is highly recommended that you always enable SSL/TLS in combination with BASIC authentication, in order to protect against password snooping.
Authentication steps
To configure HTTP BASIC authentication for a Camel Jetty endpoint deployed in the OSGi container, perform the following steps:
Add the Jetty security handler configuration
In the
jetty-security
project, edit the jetty-spring.xml
file from the src/main/resources/META-INF/spring
directory. To configure the Jetty security handler with BASIC authentication, add the following bean definitions:
<?xml version="1.0" encoding="UTF-8"?> <beans ...> ... <!-- --> <bean id="loginService" class="org.eclipse.jetty.plus.jaas.JAASLoginService"> <property name="name" value="karaf"/> <property name="loginModuleName" value="karaf"/> <property name="roleClassNames"> <list> <value>org.apache.karaf.jaas.boot.principal.RolePrincipal</value> </list> </property> </bean> <bean id="identityService" class="org.eclipse.jetty.security.DefaultIdentityService"/> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="BASIC"/> <property name="roles" value="Administrator"/> <property name="authenticate" value="true"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator"> <bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/> </property> <property name="constraintMappings"> <list> <ref bean="constraintMapping"/> </list> </property> <property name="loginService" ref="loginService"/> <property name="strict" value="false"/> <property name="identityService" ref="identityService"/> </bean> ... </beans>
Two aspects of Jetty authentication are configured by the preceding bean definitions:
- HTTP BASIC authentication—the
constraint
bean enables HTTP BASIC authentication on the Jetty security handler. Theroles
property (ofString[]
type) is used to define which roles have access to the Jetty container. In this example, this property is set toAdministrator
, so only users with theAdministrator
role can access this Jetty container. - JAAS login service—the
loginService
bean specifies that the requisite authentication data is extracted from a JAAS realm. TheloginModuleName
property specifies that the Jetty login service uses thekaraf
JAAS realm, which is the OSGi container's default JAAS realm (see Section 1.1, “OSGi Container Security”).
Modify Camel Jetty endpoint
After creating the Jetty
securityHandler
bean, you must modify the Jetty endpoint URI in the Apache Camel route, so that it hooks into the security handler. To add the security handler to the Jetty endpoint, set the handlers
option equal to the security handler's bean ID, as shown in the following example:
<beans ...>
<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jetty:https://0.0.0.0:8282/services?handlers=securityHandler&matchOnUriPrefix=true"/>
<transform>
<constant><html><body>Hello from Fuse ESB server</body></html></constant>
</transform>
</route>
</camelContext>
</beans>
Note
URI options must be separated by the
&
entity, instead of the plain &
character, in the context of an XML file.
Add required package imports to POM
Edit the
jetty-security
project's POM file, jetty-security/pom.xml
. Near the start of the POM file, define the jetty-version
property as follows:
<project ... >
...
<properties>
...
<jetty-version>8.1.17.v20150415</jetty-version>
</properties>
...
</project>
Further down the POM file, in the configuration of the Maven bundle plug-in, modify the bundle instructions to import additional Java packages, as follows:
<project ... > ... <build> ... <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName> ${project.artifactId} </Bundle-SymbolicName> <Import-Package> javax.security.auth, javax.security.auth.callback, javax.security.auth.login, javax.security.auth.spi, org.apache.karaf.jaas.modules, org.apache.karaf.jaas.boot.principal, org.eclipse.jetty.plus.jaas;version=${jetty-version}, org.eclipse.jetty.security;version=${jetty-version}, * </Import-Package> <Private-Package>org.apache.camel.jaas</Private-Package> </instructions> </configuration> </plugin> </plugins> </build> ... </project>
Note
These extra imports are required, because the Maven bundle plug-in is not capable of scanning Spring files to determine their package dependencies automatically.
Build the bundle
Use Maven to build the bundle. Open a command prompt, switch the current directory to
ProjectDir/jetty-security
, and enter the following command:
mvn install
Install the required features
If you have not already done so, start up the JBoss Fuse container by entering the following command in a new command prompt:
./fuse
Install the
jetty
and camel-jetty
features, by entering the following console commands:
karaf@root> features:install jetty karaf@root> features:install camel-jetty
Deploy the bundle
To deploy and activate the bundle, enter the following console command:
JBossFuse:karaf@root> osgi:install -s mvn:org.jbossfuse.example/jetty-security
Test the bundle
To test the Jetty service, enter the following
curl
command at a comand-line prompt:
curl https://0.0.0.0:8282/services -k --user Username:Password
Note
Don't forget to use
https:
instead of http:
in the URL!
The
--user
option is needed to specify the BASIC authentication credentials. For the Username
and Password
values, specify valid JAAS credentials (the valid credentials you can use for this step are specified in the EsbInstallDir/etc/users.properties
file). You should now receive the following HTTP reply message:
<html><body>Hello from Fuse ESB server</body></html>