Github user sohami commented on a diff in the pull request: https://github.com/apache/drill/pull/1040#discussion_r158117082 --- Diff: exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillSpnegoLoginService.java --- @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.drill.exec.server.rest.auth; + + +import org.apache.drill.common.exceptions.DrillException; +import org.apache.drill.exec.ExecConstants; +import org.apache.drill.exec.server.DrillbitContext; +import org.apache.drill.exec.server.options.SystemOptionManager; +import org.apache.drill.exec.util.ImpersonationUtil; +import org.apache.hadoop.security.UserGroupInformation; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.SpnegoLoginService; +import org.eclipse.jetty.server.UserIdentity; +import org.eclipse.jetty.util.B64Code; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; + +import javax.security.auth.Subject; +import java.lang.reflect.Field; +import java.security.Principal; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.List; + +/** + * Custom implementation of DrillSpnegoLoginService to avoid the need of passing targetName in a config file, + * to include the SPNEGO OID and the way UserIdentity is created. + */ +public class DrillSpnegoLoginService extends SpnegoLoginService { + private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillSpnegoLoginService.class); + + private static final String TARGET_NAME_FIELD_NAME = "_targetName"; + + private final DrillbitContext drillContext; + + private final SpnegoUtil spnegoUtil; + + private final UserGroupInformation loggedInUgi; + + public DrillSpnegoLoginService(DrillbitContext drillBitContext) throws DrillException { + super(DrillSpnegoLoginService.class.getName()); + setIdentityService(new DefaultIdentityService()); + drillContext = drillBitContext; + + // Load and verify SPNEGO config. Then Login using creds to get an UGI instance + spnegoUtil = new SpnegoUtil(drillBitContext.getConfig()); + spnegoUtil.validateSpnegoConfig(); + loggedInUgi = spnegoUtil.getLoggedInUgi(); + } + + @Override + protected void doStart() throws Exception { + // Override the parent implementation, setting _targetName to be the serverPrincipal + // without the need for a one-line file to do the same thing. + final Field targetNameField = SpnegoLoginService.class.getDeclaredField(TARGET_NAME_FIELD_NAME); + targetNameField.setAccessible(true); + targetNameField.set(this, spnegoUtil.getSpnegoPrincipal()); + } + + @Override + public UserIdentity login(final String username, final Object credentials) { + + UserIdentity identity = null; + try { + identity = loggedInUgi.doAs(new PrivilegedExceptionAction<UserIdentity>() { + @Override + public UserIdentity run() { + return spnegoLogin(username, credentials); + } + }); + } catch (Exception e) { + logger.error("Failed to login using SPNEGO"); --- End diff -- Done.
---