| <noautolink> |
| |
| [[index][::Go back to Oozie Documentation Index::]] |
| |
| ---+!! Creating Custom Authentication |
| |
| %TOC% |
| |
| ---++ Hadoop-Auth Authentication Interfaces and classes |
| |
| 1. =org.apache.hadoop.security.authentication.client.Authenticator:= Interface for client authentication mechanisms. |
| |
| The following authenticators are provided in hadoop-auth: |
| |
| * KerberosAuthenticator : the authenticator implements the Kerberos SPNEGO authentication sequence. |
| * PseudoAuthenticator : the authenticator implementation provides an authentication equivalent to Hadoop's Simple |
| authentication, it trusts the value of the 'user.name' Java System property. |
| |
| 2. =org.apache.hadoop.security.authentication.server.AuthenticationHandler:= Interface for server authentication mechanisms. |
| |
| * KerberosAuthenticationHandler : the authenticator handler implements the Kerberos SPNEGO authentication mechanism for HTTP. |
| * AltKerberosAuthenticationHandler: the authenticator handler allows for Kerberos SPNEGO authentication for non-browsers and an alternate form of authentication for browsers. A subclass must implement the alternate authentication (see [[ENG_Custom_Authentication#LoginServerExample][Example Login Server]]) |
| * PseudoAuthenticationHandler : the authenticator handler provides a pseudo authentication mechanism that accepts the user |
| name specified as a query string parameter. |
| |
| 3. =org.apache.hadoop.security.authentication.server.AuthenticationFilter:= A servlet filter enables protecting web application |
| resources with different authentication mechanisms provided by AuthenticationHandler. To enable the filter, web application |
| resources file (ex. web.xml) needs to include a filter class derived from =AuthenticationFilter=. |
| |
| For more information have a look at the appropriate |
| [[https://hadoop.apache.org/docs/r2.7.2/hadoop-auth/index.html][Hadoop documentation]]. |
| |
| ---++ Provide Custom Authentication to Oozie Client |
| |
| Apache Oozie contains a default class =org.apache.oozie.client.AuthOozieClient= to support Kerberos HTTP SPNEGO authentication, |
| pseudo/simple authentication and anonymous access for client connections. |
| |
| To provide other authentication mechanisms, an Oozie client should extend from =AuthOozieClient= and provide the following |
| methods should be overridden by derived classes to provide custom authentication: |
| |
| * getAuthenticator() : return corresponding Authenticator based on value specified by user at =auth= command option. |
| * createConnection() : create a singleton class at Authenticator to allow client set and get key-value configuration for |
| authentication. |
| |
| ---++ Provide Custom Authentication to Oozie Server |
| |
| To accept custom authentication in Oozie server, a filter extends from AuthenticationFilter must be provided. This filter |
| delegates to the configured authentication handler for authentication and once it obtains an =AuthenticationToken= from it, sets |
| a signed HTTP cookie with the token. If HTTP cookie is provided with different key name, its cookie value can be retrieved by |
| overriding =getToken()= method. Please note, only when =getToken()= return NULL, a custom authentication can be invoked and |
| processed in =AuthenticationFilter.doFilter()=. |
| |
| The following method explains how to read it and return NULL token. |
| <verbatim> |
| protected AuthenticationToken getToken(HttpServletRequest request) throws IOException, AuthenticationException { |
| String tokenStr = null; |
| Cookie[] cookies = request.getCookies(); |
| |
| if (cookies != null) { |
| for (Cookie cookie : cookies) { |
| if (cookie.getName().equals(AuthenticatedURL.AUTH_COOKIE)) { |
| tokenStr = cookie.getValue(); |
| LOG.info("Got 'hadoop.auth' cookie from request = " + tokenStr); |
| if (tokenStr != null && !tokenStr.trim().isEmpty()) { |
| AuthenticationToken retToken = super.getToken(request); |
| return retToken; |
| } |
| } else if (cookie.getName().equals("NEWAUTH")) { |
| tokenStr = cookie.getValue(); |
| // DO NOT return the token string so request can authenticated. |
| } |
| } |
| } |
| return null; |
| } |
| </verbatim> |
| |
| #LoginServerExample |
| ---++ Login Server Example |
| |
| ---+++ Overview |
| |
| The Login Server Example is a web application that is an example of how to create a login server for Oozie. It provides two example |
| servlets: LoginServlet and LDAPLoginServlet. The LoginServlet example is very primitive and simply authenticates users whose |
| username and password match (e.g. user=foo and pass=foo). The LDAPLoginServlet example can be configured against an LDAP server to |
| authenticate users from that LDAP server. Once authenticated, both example servlets write the username to a cookie that Oozie |
| checks via the ExampleAltAuthenticationHandler (which uses that cookie for authentication for browsers but Kerberos otherwise). |
| |
| The LoginServlet and LDAPLoginServlet are run from a separate WAR file called oozie-login.war; its web.xml can be used to configure |
| which servlet is used as well as some additional properties. The ExampleAltAuthenticationHandler is run as part of the Oozie server |
| but is built as a separate jar: oozie-login.jar. |
| |
| ---+++ ExampleAltAuthenticationHandler |
| |
| This is a subclass of the abstract AltKerberosAuthenticationHandler, which is an AuthenticationHandler that allows for a "mixed" |
| mode of authentication. When a non-browser is used, Kerberos will be used for authentication; when a browser is used, some other |
| authentication method will be used. In the case of ExampleAltAuthenticationHandler, the other authentication method is to look for |
| a cookie named =oozie.web.login.auth= and create an AuthenticationToken using the value of the cookie as the username. If the |
| cookie cannot be found, it will redirect the browser to a page where the user can (presumably) login to a server that can |
| authenticate the user and create the cookie. As this is obviously a very primitive method of authentication that is not secure, it |
| should NOT be used in production; it is only provided as an example of how the AltKerberosAuthenticationHandler can be used. |
| |
| To reiterate: %RED%ExampleAltAuthenticationHandler IS NOT SECURE -- DO NOT USE IT IN A PRODUCTION ENVIRONMENT%ENDCOLOR% |
| |
| To use the ExampleAltAuthenticationHandler, make at least the following two changes to your oozie-site.xml. All of the existing |
| Kerberos-related settings are still applicable (for when a non-browser is used) so make sure to configure them appropriately. |
| <verbatim> |
| <property> |
| <name>oozie.authentication.type</name> |
| <value>org.apache.oozie.authentication.ExampleAltAuthenticationHandler</value> |
| </property> |
| <property> |
| <name>oozie.service.HadoopAccessorService.kerberos.enabled</name> |
| <value>true</value> |
| </property> |
| </verbatim> |
| Note: The ExampleAltAuthenticationHandler is included in the oozie-login.jar file and not normally included with Oozie core. |
| Additionally, you can configure which user-agents AltKerberosAuthenticationHandler (and thus ExampleAltAuthenticationHandler) |
| consider to be non-browsers by setting the following property in oozie-site.xml to a comma separated list. When any of the values |
| in this property are contained in the user-agent of the request, Kerberos will be used; otherwise, the alternate authentication will |
| be used. |
| <verbatim> |
| <property> |
| <name>oozie.authentication.alt-kerberos.non-browser.user-agents</name> |
| <value>java,curl,wget,perl</value> |
| </property> |
| </verbatim> |
| The above values, which are the default, will cause a user-agent such as "java" (the user-agent used by Java programs) to use |
| Kerberos. Note that this would also match with user-agents such as "java6" and "I am not a JaVa program". |
| |
| When the ExampleAltAuthenticationHandler cannot find the =oozie.web.login.auth= cookie, it will redirect the user to another URL, |
| which can be configured by setting the following property in oozie-site.xml. Typically, this URL should take the user to a server |
| where they can login to acquire the cookie and then get redirected back to the Oozie web console (the Login Server Example does this |
| and will be explained in more detail later). |
| <verbatim> |
| <property> |
| <name>oozie.authentication.ExampleAltAuthenticationHandler.redirect.url</name> |
| <value>http://localhost:11000/oozie-login/?backurl={0}</value> |
| </property> |
| </verbatim> |
| The above value, which is the default, will cause the user to be redirected to the Login Server Example if its running in the same |
| tomcat as Oozie and on the default port. If ={0}= appears anywhere in this URL, it will be replaced by the URL of Oozie's web |
| console so that the Login Server Example can know where to send the user back while staying independent of Oozie. |
| |
| ---+++ LoginServlet |
| |
| This is a web servlet that gets bundled in the oozie-login.war web application. It is a very primitive example of a login server |
| implementation that is compatible with the ExampleAltAuthenticationHandler. When users visit this servlet, they are shown a simple |
| login page that allows them to enter their username and password. It authenticates them if their username and password are the same |
| (e.g. user=foo and pass=foo), which is not secure and should not be used in production; it is only provided as an example. |
| |
| To reiterate: %RED%LoginServlet IS NOT SECURE -- DO NOT USE IT IN A PRODUCTION ENVIRONMENT%ENDCOLOR% |
| |
| Sending it a GET request returns the login page; the =backurl= parameter is required (so it knows where to redirect the user back to |
| once they are authenticated), but there is also an optional =username= parameter that will pre-populate the username field if given. |
| |
| Sending it a POST request will also return the login page, but only if an error occurs (e.g. invalid username or password). As with |
| the GET request, the =backurl= parameter is required, but now the =username= and =password= parameters are also required. If they |
| match, the LoginServlet will write the =oozie.web.login.auth= cookie containing the username and redirect the user to the =backurl=, |
| which is presumably the Oozie web console. |
| |
| The login page can be configured to look differently by changing the following parameter in the web.xml in the oozie-login.war file |
| (or in the login/src/main/webapp/WEB-INF/ directory before building it). The file needs to be located in the |
| login/src/main/resources/ directory and should contain ={0}= for where an error message can go, ={1}= for where the username |
| included with a GET request will go, and ={2}= for where the =backurl= goes. |
| <verbatim> |
| <init-param> |
| <param-name>login.page.template</param-name> |
| <param-value>login-page-template.html</param-value> |
| </init-param> |
| </verbatim> |
| The above value, which is the default, is a basic html page that has fields for the username and password and meets the previously |
| stated requirements. |
| |
| The =oozie.web.login.auth= cookie will expire 3 minutes after being given to the user. Once the user has been redirected back to |
| the Oozie web console and given the AuthenticationToken, the =oozie.web.login.auth= cookie is no longer used. If the |
| AuthenticationToken expires but the user still has a valid =oozie.web.login.auth= cookie, the ExampleAltAuthenticationHandler will |
| simply give out a new AuthenticationToken; the desired behavior is that the user is bounced back to the oozie-login.war server to |
| re-authenticate, hence the very short lifetime of the =oozie.web.login.auth= cookie. However, the expiration time of the cookie |
| is configurable by changing the following parameter in the web.xml in the oozie-login.war file (or in the |
| login/src/main/webapp/WEB-INF/ directory before building it). It is given in seconds. A positive value indicates that the cookie |
| will expire after that many seconds have passed; make sure this value is high enough to allow the user to be forwarded to the |
| backurl before the cookie expires. A negative value indicates that the cookie will be deleted when the browser exits. |
| <verbatim> |
| <init-param> |
| <param-name>login.auth.cookie.expire.time</param-name> |
| <param-value>180</param-value> |
| </init-param> |
| </verbatim> |
| The above value, which is the default, is the number of seconds in 3 minutes. |
| |
| ---+++ LDAPLoginServlet |
| |
| This is a second web servlet that gets bundled in the oozie-login.war web application. It inherits from the LoginServlet, so the |
| previous configuration information (e.g. login.page.template) still applies to this servlet. The only difference between the |
| LDAPLoginServlet and the LoginServlet, is that the LDAPLoginServlet is configured against an LDAP server to provide the |
| authentication instead of simply checking that the username and password are equal. As before, this is not secure and should not be |
| used in production; it is only provided as an example. |
| |
| To reiterate: %RED%LDAPLoginServlet IS NOT SECURE -- DO NOT USE IT IN A PRODUCTION ENVIRONMENT%ENDCOLOR% |
| |
| The oozie-login.war web application is configured to use LoginServlet by default. To switch it to use the LDAPLoginServlet, you |
| have to change the following line in the web.xml from: |
| <verbatim> |
| <servlet-class>org.apache.oozie.servlet.login.LoginServlet</servlet-class> |
| </verbatim> |
| to: |
| <verbatim> |
| <servlet-class>org.apache.oozie.servlet.login.LDAPLoginServlet</servlet-class> |
| </verbatim> |
| |
| There are three additional parameters related to LDAP that you should configure in the web.xml: |
| <verbatim> |
| <init-param> |
| <param-name>ldap.provider.url</param-name> |
| <param-value>ldap://localhost:389</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ldap.context.factory</param-name> |
| <param-value>com.sun.jndi.ldap.LdapCtxFactory</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ldap.security.authentication</param-name> |
| <param-value>simple</param-value> |
| </init-param> |
| </verbatim> |
| The ldap.provider.url is the LDAP provider URL to use, the ldap.context.factory is the LDAP context factory to use, and the |
| ldap.security.authentication is the LDAP security authentication type to use. |
| |
| ---+++ Building and Deploying |
| The README.txt file in the =login= directory contains instructions on how to build and deploy the Login Server Example |
| |
| |
| |
| [[index][::Go back to Oozie Documentation Index::]] |
| |
| </noautolink> |