001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with this 004 * work for additional information regarding copyright ownership. The ASF 005 * licenses this file to you under the Apache License, Version 2.0 (the 006 * "License"); you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations under 015 * the License. 016 */ 017package org.apache.hadoop.hdfs.server.namenode; 018 019import java.io.DataOutputStream; 020import java.io.IOException; 021import java.security.PrivilegedExceptionAction; 022 023import javax.servlet.ServletContext; 024import javax.servlet.ServletException; 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpServletResponse; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager; 032import org.apache.hadoop.hdfs.security.token.delegation.DelegationUtilsClient; 033import org.apache.hadoop.security.Credentials; 034import org.apache.hadoop.security.UserGroupInformation; 035 036/** 037 * Serve delegation tokens over http for use in hftp. 038 */ 039@SuppressWarnings("serial") 040public class GetDelegationTokenServlet extends DfsServlet { 041 private static final Log LOG = LogFactory.getLog(GetDelegationTokenServlet.class); 042 043 @Override 044 protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) 045 throws ServletException, IOException { 046 final UserGroupInformation ugi; 047 final ServletContext context = getServletContext(); 048 final Configuration conf = NameNodeHttpServer.getConfFromContext(context); 049 try { 050 ugi = getUGI(req, conf); 051 } catch(IOException ioe) { 052 LOG.info("Request for token received with no authentication from " 053 + req.getRemoteAddr(), ioe); 054 resp.sendError(HttpServletResponse.SC_FORBIDDEN, 055 "Unable to identify or authenticate user"); 056 return; 057 } 058 LOG.info("Sending token: {" + ugi.getUserName() + "," + req.getRemoteAddr() +"}"); 059 final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(context); 060 String renewer = req.getParameter(DelegationUtilsClient.RENEWER); 061 final String renewerFinal = (renewer == null) ? 062 req.getUserPrincipal().getName() : renewer; 063 064 DataOutputStream dos = null; 065 try { 066 dos = new DataOutputStream(resp.getOutputStream()); 067 final DataOutputStream dosFinal = dos; // for doAs block 068 ugi.doAs(new PrivilegedExceptionAction<Void>() { 069 @Override 070 public Void run() throws IOException { 071 final Credentials ts = DelegationTokenSecretManager.createCredentials( 072 nn, ugi, renewerFinal); 073 ts.write(dosFinal); 074 return null; 075 } 076 }); 077 078 } catch(Exception e) { 079 LOG.info("Exception while sending token. Re-throwing ", e); 080 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 081 } finally { 082 if(dos != null) dos.close(); 083 } 084 } 085}