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.IOException; 020import java.io.OutputStreamWriter; 021import java.io.PrintWriter; 022import java.security.PrivilegedExceptionAction; 023 024import javax.servlet.ServletContext; 025import javax.servlet.ServletException; 026import javax.servlet.http.HttpServletRequest; 027import javax.servlet.http.HttpServletResponse; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.apache.hadoop.conf.Configuration; 032import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier; 033import org.apache.hadoop.hdfs.security.token.delegation.DelegationUtilsClient; 034import org.apache.hadoop.security.UserGroupInformation; 035import org.apache.hadoop.security.token.Token; 036 037import com.google.common.base.Charsets; 038 039/** 040 * Renew delegation tokens over http for use in hftp. 041 */ 042@SuppressWarnings("serial") 043public class RenewDelegationTokenServlet extends DfsServlet { 044 private static final Log LOG = LogFactory.getLog(RenewDelegationTokenServlet.class); 045 046 @Override 047 protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) 048 throws ServletException, IOException { 049 final UserGroupInformation ugi; 050 final ServletContext context = getServletContext(); 051 final Configuration conf = NameNodeHttpServer.getConfFromContext(context); 052 try { 053 ugi = getUGI(req, conf); 054 } catch(IOException ioe) { 055 LOG.info("Request for token received with no authentication from " 056 + req.getRemoteAddr(), ioe); 057 resp.sendError(HttpServletResponse.SC_FORBIDDEN, 058 "Unable to identify or authenticate user"); 059 return; 060 } 061 final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(context); 062 String tokenString = req.getParameter(DelegationUtilsClient.TOKEN); 063 if (tokenString == null) { 064 resp.sendError(HttpServletResponse.SC_MULTIPLE_CHOICES, 065 "Token to renew not specified"); 066 } 067 final Token<DelegationTokenIdentifier> token = 068 new Token<DelegationTokenIdentifier>(); 069 token.decodeFromUrlString(tokenString); 070 071 try { 072 long result = ugi.doAs(new PrivilegedExceptionAction<Long>() { 073 @Override 074 public Long run() throws Exception { 075 return nn.getRpcServer().renewDelegationToken(token); 076 } 077 }); 078 final PrintWriter os = new PrintWriter(new OutputStreamWriter( 079 resp.getOutputStream(), Charsets.UTF_8)); 080 os.println(result); 081 os.close(); 082 } catch(Exception e) { 083 // transfer exception over the http 084 String exceptionClass = e.getClass().getName(); 085 String exceptionMsg = e.getLocalizedMessage(); 086 String strException = exceptionClass + ";" + exceptionMsg; 087 LOG.info("Exception while renewing token. Re-throwing. s=" + strException, e); 088 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, strException); 089 } 090 } 091}