Juan Hernandez has uploaded a new change for review.

Change subject: core: Add header authenticator
......................................................................

core: Add header authenticator

This patch introduces a new authenticator that assumes that the
authentication has already been performed by the web server and that
takes the user name from a configurable request header.

To use this authenticator the web server has to be configured to
populate a header with the name of the authenticated user. An overly
simple example is the following:

  <Location /webadmin>
    RequestHeader set X-Remote-User jdoe
  </Location>

This tells the web server to add the "X-Remote-User" header with the
value "jdoe" to all the requests for URLs starting with "/webadmin".
After doing this the engine can be configured creating a "header.conf"
file inside "/etc/ovirt-engine/auth.d" with the following content:

  #
  # The name of the authentication profile:
  #
  name=simple

  #
  # The types of the authencitator and the directory to use:
  #
  authenticator.type=header
  directory.type=nop

  #
  # The name of the header to extract the user name from:
  #
  authenticator.header=X-Remote-User

The net result is that users connecting to the "/webadmin" URL will be
automatically authenticated as "jdoe" without having to provide any
credentials.

A more realistic example of the web server configuration is the
following:

  <Location /webadmin>
    AuthType Basic
    AuthName "Protected"
    AuthBasicProvider file
    AuthUserFile /etc/httpd/conf/users
    Require valid-user

    #
    # This is needed in order to enable the rewrite engine later,
    # otherwise the web server refuses to enable it because it
    # allows similar mechanism to cincumvent directory
    # restrictions:
    #
    Options +FollowSymLinks

    #
    # This rewrite rules are intended to copy the value of the
    # REMOTE_USER CGI environment variable into a header, as
    # JBoss AS 7 doesn't currently # have a mechanism to
    # access the environment variable:
    #
    RewriteEngine On
    RewriteCond %{REMOTE_USER} ^(.*)$
    RewriteRule ^(.*)$ - [E=REMOTE_USER:%1]
    RequestHeader set X-Remote-User %{REMOTE_USER}e
  </Location>

With this web server configuration and the same engine "header.conf"
engine configuration described above users will be asked for credentials
by the web server. Those credentials will be checked by the web server
using the /etc/httpd/conf/users file, and then the user will be
automatically logged in to the engine without having to provide any
additional credentials.

Change-Id: If2e212641d41f30fee753edff9581bd5c4fc31e2
Signed-off-by: Juan Hernandez <juan.hernan...@redhat.com>
---
A 
backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticator.java
A 
backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticatorFactory.java
M 
backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
3 files changed, 159 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/28/21028/1

diff --git 
a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticator.java
 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticator.java
new file mode 100644
index 0000000..214109b
--- /dev/null
+++ 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticator.java
@@ -0,0 +1,104 @@
+package org.ovirt.engine.core.authentication.header;
+
+import static org.apache.commons.lang.StringUtils.isEmpty;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ovirt.engine.core.authentication.NegotiatingAuthenticator;
+import org.ovirt.engine.core.authentication.NegotiationResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This authenticator assumes that the web server has already performed the 
authentication and takes the user from a
+ * request header. The Apache web server, for example, can be configured to 
perform authentication and then populate a
+ * header as follows:
+ *
+ * <pre>
+ * &lt;Location /webadmin&gt;
+ *   AuthType Basic
+ *   AuthName "Protected"
+ *   AuthBasicProvider file
+ *   AuthUserFile /etc/httpd/conf/users
+ *   Require valid-user
+ *
+ *   #
+ *   # This is needed in order to enable the rewrite engine later, otherwise
+ *   # the web server refuses to enable it because it allows similar mechanism 
to
+ *   # cincumvent directory restrictions:
+ *   #
+ *   Options +FollowSymLinks
+ *
+ *   #
+ *   # This rewrite rules are intended to copy the value of the REMOTE_USER
+ *   # CGI environment variable into a header, as JBoss AS 7 doesn't currently
+ *   # have a mechanism to access the remote user name:
+ *   #
+ *   RewriteEngine On
+ *   RewriteCond %{REMOTE_USER} ^(.*)$
+ *   RewriteRule ^(.*)$ - [E=REMOTE_USER:%1]
+ *   RequestHeader set X-Remote-User %{REMOTE_USER}e
+ * &lt;/Location&gt;
+ * </pre>
+ *
+ * Once the web server is configured this authenticator can be included in an 
authentication profile with a
+ * configuraion file similar to this one:
+ *
+ * <pre>
+ * name=myprofile
+ * module=org.ovirt.engine.core.authentication
+ * authenticator.type=header
+ * authenticator.header=X-Remote-User
+ * directory.type=nop
+ * </pre>
+ */
+public class HeaderAuthenticator implements NegotiatingAuthenticator {
+    // The log:
+    private static final Logger log = 
LoggerFactory.getLogger(HeaderAuthenticator.class);
+
+    // The name of the authenticator:
+    private String name;
+
+    // The name of the header that contains the name of the user already 
authenticated by the web server:
+    private String header;
+
+    /**
+     * Create a new header authenticator.
+     *
+     * @param name the name of the authenticator
+     * @param header the name of the header containing the name of the user 
already authenticated by the web server
+     */
+    public HeaderAuthenticator(String name, String header) {
+        this.name = name;
+        this.header = header;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public NegotiationResult negotiate(HttpServletRequest req, 
HttpServletResponse rsp) {
+        // Get the value of the header, if it isn't available send a warning 
explaining that the web server may not be
+        // correctly configured:
+        String value = req.getHeader(header);
+        if (isEmpty(value)) {
+            log.warn(
+                "Can't authenticate the user because the header \"{}\" doesn't 
contain the name of the user, check" +
+                "the configuration of the web server."
+            );
+            return new NegotiationResult(false, null);
+        }
+
+        // We are good, the user has already been authenticated by the web 
server:
+        return new NegotiationResult(true, value);
+    }
+}
diff --git 
a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticatorFactory.java
 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticatorFactory.java
new file mode 100644
index 0000000..be4eb85
--- /dev/null
+++ 
b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/header/HeaderAuthenticatorFactory.java
@@ -0,0 +1,54 @@
+package org.ovirt.engine.core.authentication.header;
+
+import java.io.File;
+
+import org.ovirt.engine.core.authentication.Authenticator;
+import org.ovirt.engine.core.authentication.AuthenticatorFactory;
+import org.ovirt.engine.core.authentication.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HeaderAuthenticatorFactory implements AuthenticatorFactory {
+    // The log:
+    private static final Logger log = 
LoggerFactory.getLogger(HeaderAuthenticatorFactory.class);
+
+    // The type supported by this factory:
+    private static final String TYPE = "header";
+
+    // Names of the configuration parameters:
+    private static final String NAME_PARAMETER = "name";
+    private static final String HEADER_PARAMETER = "header";
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
+
+    @Override
+    public Authenticator create(File file, Configuration config) {
+        // Get the name of the authenticator:
+        String name = config.getInheritedString(NAME_PARAMETER);
+        if (name == null) {
+            log.error(
+                "The configuration file \"{}\" doesn't contain the name of the 
authenticator.",
+                file.getAbsolutePath()
+            );
+            return null;
+        }
+
+        // Get the name of the header:
+        String header = config.getString(HEADER_PARAMETER);
+        if (header == null) {
+            log.error(
+                "The configuration file \"{}\" doesn't contain the parameter 
\"{}\" that specifies the name of " +
+                "the header containing the remote user name.",
+                file.getAbsolutePath(),
+                config.getAbsoluteKey(NAME_PARAMETER)
+            );
+            return null;
+        }
+
+        // We are good, create the authenticator:
+        return new HeaderAuthenticator(name, header);
+    }
+}
diff --git 
a/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
 
b/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
index 73a291a..d9c5f32 100644
--- 
a/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
+++ 
b/backend/manager/modules/authentication/src/main/resources/META-INF/services/org.ovirt.engine.core.authentication.AuthenticatorFactory
@@ -2,4 +2,5 @@
 # This file contains one line per each authenticator factory to be
 # automatically registered with the authenticator manager:
 #
+org.ovirt.engine.core.authentication.header.HeaderAuthenticatorFactory
 org.ovirt.engine.core.authentication.nop.NopAuthenticatorFactory


-- 
To view, visit http://gerrit.ovirt.org/21028
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If2e212641d41f30fee753edff9581bd5c4fc31e2
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <juan.hernan...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to