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> + * <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 remote user name: + * # + * RewriteEngine On + * RewriteCond %{REMOTE_USER} ^(.*)$ + * RewriteRule ^(.*)$ - [E=REMOTE_USER:%1] + * RequestHeader set X-Remote-User %{REMOTE_USER}e + * </Location> + * </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