Repository: lens Updated Branches: refs/heads/master 8c66a64f5 -> 26d8f57a2
LENS-1514:Support HDFS delegation token authentication Project: http://git-wip-us.apache.org/repos/asf/lens/repo Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/0edb80f1 Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/0edb80f1 Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/0edb80f1 Branch: refs/heads/master Commit: 0edb80f1a46f10f2470b5eaac4272bf6ee9fe418 Parents: 8c66a64 Author: Rajitha.R <[email protected]> Authored: Thu May 24 19:56:48 2018 +0530 Committer: Rajitha.R <[email protected]> Committed: Thu May 24 19:56:48 2018 +0530 ---------------------------------------------------------------------- contrib/clients/python/lens/client/log.py | 7 ++++-- contrib/clients/python/lens/client/main.py | 4 ++-- contrib/clients/python/lens/client/query.py | 25 ++++++++++++++------ contrib/clients/python/lens/client/session.py | 5 ++-- .../lens/client/LensConnectionParams.java | 1 + .../lens/server/api/LensConfConstants.java | 3 ++- .../server/auth/SpnegoAuthenticationFilter.java | 10 +++++--- 7 files changed, 38 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/contrib/clients/python/lens/client/log.py ---------------------------------------------------------------------- diff --git a/contrib/clients/python/lens/client/log.py b/contrib/clients/python/lens/client/log.py index a10798f..e427f7f 100644 --- a/contrib/clients/python/lens/client/log.py +++ b/contrib/clients/python/lens/client/log.py @@ -14,12 +14,15 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .auth import SpnegoAuth import requests class LensLogClient(object): - def __init__(self, base_url): + def __init__(self, base_url, conf): self.base_url = base_url + "logs/" + self.keytab = conf.get('lens.client.authentication.kerberos.keytab') + self.principal = conf.get('lens.client.authentication.kerberos.principal') def __getitem__(self, item): - return requests.get(self.base_url + str(item)).text + return requests.get(self.base_url + str(item), auth=SpnegoAuth(self.keytab, self.principal)).text http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/contrib/clients/python/lens/client/main.py ---------------------------------------------------------------------- diff --git a/contrib/clients/python/lens/client/main.py b/contrib/clients/python/lens/client/main.py index b1846ad..9eae6fc 100644 --- a/contrib/clients/python/lens/client/main.py +++ b/contrib/clients/python/lens/client/main.py @@ -41,8 +41,8 @@ class LensClient(object): username = username or conf.get('lens.client.user.name', "anonymous") database = database or conf.get('lens.client.dbname') self.session = LensSessionClient(self.base_url, username, password, database, conf) - self.queries = LensQueryClient(self.base_url, self.session) - self.logs = LensLogClient(self.base_url) + self.queries = LensQueryClient(self.base_url, self.session, conf) + self.logs = LensLogClient(self.base_url, conf) def __enter__(self): return self http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/contrib/clients/python/lens/client/query.py ---------------------------------------------------------------------- diff --git a/contrib/clients/python/lens/client/query.py b/contrib/clients/python/lens/client/query.py index 1cd3291..b09ff19 100644 --- a/contrib/clients/python/lens/client/query.py +++ b/contrib/clients/python/lens/client/query.py @@ -24,6 +24,7 @@ import requests from requests.exceptions import HTTPError from six import string_types, BytesIO, PY2, PY3 +from .auth import SpnegoAuth from .models import WrappedJson from .utils import conf_to_xml @@ -148,7 +149,7 @@ class LensPersistentResult(LensQueryResult): class LensQueryClient(object): - def __init__(self, base_url, session): + def __init__(self, base_url, session, conf): self._session = session self.base_url = base_url + "queryapi/" self.launched_queries = [] @@ -156,10 +157,15 @@ class LensQueryClient(object): self.query_confs = {} self.is_header_present_in_result = self._session['lens.query.output.write.header'].lower() \ in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup'] + self.keytab = conf.get('lens.client.authentication.kerberos.keytab') + self.principal = conf.get('lens.client.authentication.kerberos.principal') def __call__(self, **filters): filters['sessionid'] = self._session._sessionid - resp = requests.get(self.base_url + "queries/", params=filters, headers={'accept': 'application/json'}) + resp = requests.get(self.base_url + "queries/", + params=filters, + headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) return self.sanitize_response(resp) def __getitem__(self, item): @@ -167,7 +173,8 @@ class LensQueryClient(object): if item in self.finished_queries: return self.finished_queries[item] resp = requests.get(self.base_url + "queries/" + item, params={'sessionid': self._session._sessionid}, - headers={'accept': 'application/json'}) + headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) resp.raise_for_status() query = LensQuery(self, resp.json(object_hook=WrappedJson)) if query.finished: @@ -194,7 +201,8 @@ class LensQueryClient(object): operation = "execute_with_timeout" if timeout else "execute" payload.append(('operation', operation)) payload.append(('conf', conf_to_xml(conf))) - resp = requests.post(self.base_url + "queries/", files=payload, headers={'accept': 'application/json'}) + resp = requests.post(self.base_url + "queries/", files=payload, headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) query = self.sanitize_response(resp) logger.info("Submitted query %s", query) if conf: @@ -218,11 +226,13 @@ class LensQueryClient(object): handle = str(query.query_handle) if query.status.status == 'SUCCESSFUL' and query.status.is_result_set_available: resp = requests.get(self.base_url + "queries/" + handle + "/resultsetmetadata", - params={'sessionid': self._session._sessionid}, headers={'accept': 'application/json'}) + params={'sessionid': self._session._sessionid}, headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) metadata = self.sanitize_response(resp) # Try getting the result through http result resp = requests.get(self.base_url + "queries/" + handle + "/httpresultset", - params={'sessionid': self._session._sessionid}, stream=True) + params={'sessionid': self._session._sessionid}, stream=True, + auth=SpnegoAuth(self.keytab, self.principal)) if resp.ok: is_header_present = self.is_header_present_in_result if handle in self.query_confs and 'lens.query.output.write.header' in self.query_confs[handle]: @@ -231,7 +241,8 @@ class LensQueryClient(object): else: response = requests.get(self.base_url + "queries/" + handle + "/resultset", params={'sessionid': self._session._sessionid}, - headers={'accept': 'application/json'}) + headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) resp = self.sanitize_response(response) # If it has in memory result, return inmemory result iterator if resp._is_wrapper and resp._wrapped_key == u'inMemoryQueryResult': http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/contrib/clients/python/lens/client/session.py ---------------------------------------------------------------------- diff --git a/contrib/clients/python/lens/client/session.py b/contrib/clients/python/lens/client/session.py index e63da1e..3b527e0 100644 --- a/contrib/clients/python/lens/client/session.py +++ b/contrib/clients/python/lens/client/session.py @@ -26,13 +26,14 @@ class LensSessionClient(object): def __init__(self, base_url, username, password, database, conf): self.base_url = base_url + "session/" self.keytab = conf.get('lens.client.authentication.kerberos.keytab') - self.principal = username or conf.get('lens.client.authentication.kerberos.principal') + self.principal = conf.get('lens.client.authentication.kerberos.principal') self.open(username, password, database, conf) def __getitem__(self, key): resp = requests.get(self.base_url + "params", params={'sessionid': self._sessionid, 'key': key}, - headers={'accept': 'application/json'}) + headers={'accept': 'application/json'}, + auth=SpnegoAuth(self.keytab, self.principal)) if resp.ok: params = resp.json(object_hook=WrappedJson) text = params.elements[0] http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/lens-client/src/main/java/org/apache/lens/client/LensConnectionParams.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensConnectionParams.java b/lens-client/src/main/java/org/apache/lens/client/LensConnectionParams.java index 90c70c8..01ae4dc 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensConnectionParams.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensConnectionParams.java @@ -53,6 +53,7 @@ public class LensConnectionParams { private Set<Class<?>> requestFilters = new HashSet<Class<?>>(); private void setupRequestFilters() { + requestFilters.add(DelegationTokenClientFilter.class); requestFilters.add(SpnegoClientFilter.class); // add default filter if (this.conf.get(LensClientConfig.SESSION_FILTER_NAMES) != null) { String[] filterNames = this.conf.getStrings(LensClientConfig.SESSION_FILTER_NAMES); http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java ---------------------------------------------------------------------- diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java index bda995d..b81d0a8 100644 --- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java +++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java @@ -1313,5 +1313,6 @@ public final class LensConfConstants { public static final String ALLOWED_PROXY_USERS = SERVER_PFX + "authentication.allowed.proxy.users"; - + public static final String DELEGATION_TOKEN_AUTH_HDFS_PATH_TO_CHECK = SERVER_PFX + + "delegation.token.auth.hdfs.path.to.check"; } http://git-wip-us.apache.org/repos/asf/lens/blob/0edb80f1/lens-server/src/main/java/org/apache/lens/server/auth/SpnegoAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/lens-server/src/main/java/org/apache/lens/server/auth/SpnegoAuthenticationFilter.java b/lens-server/src/main/java/org/apache/lens/server/auth/SpnegoAuthenticationFilter.java index a6a0abf..2477381 100644 --- a/lens-server/src/main/java/org/apache/lens/server/auth/SpnegoAuthenticationFilter.java +++ b/lens-server/src/main/java/org/apache/lens/server/auth/SpnegoAuthenticationFilter.java @@ -20,6 +20,7 @@ package org.apache.lens.server.auth; import java.io.File; +import java.security.Principal; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.HashMap; @@ -33,7 +34,6 @@ import javax.security.auth.login.Configuration; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.ws.rs.NotAuthorizedException; -import javax.ws.rs.Priorities; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; @@ -73,9 +73,8 @@ import lombok.extern.slf4j.Slf4j; * {@code lens.server.authentication.kerberos.keytab} : Keytab of lens SPN * </pre> */ - +@Priority(20) @Slf4j -@Priority(Priorities.AUTHENTICATION) public class SpnegoAuthenticationFilter implements ContainerRequestFilter { private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; private static final String KERBEROS_LOGIN_MODULE_NAME = @@ -119,6 +118,11 @@ public class SpnegoAuthenticationFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext context) { + Principal userPrincipal = context.getSecurityContext().getUserPrincipal(); + if (userPrincipal != null) { + log.info("Authentication already done for principal {}, skipping this filter...", userPrincipal.getName()); + return; + } // only authenticate when @Authenticate is present on resource if (resourceInfo.getResourceClass() == null || resourceInfo.getResourceMethod() == null) { return;
