/* * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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.hadoop.hbase.security.token; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.CoprocessorEnvironment; import org.apache.hadoop.hbase.coprocessor.BaseEndpointCoprocessor; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; import org.apache.hadoop.hbase.ipc.HBaseServer; import org.apache.hadoop.hbase.ipc.RequestContext; import org.apache.hadoop.hbase.ipc.RpcServer; import org.apache.hadoop.hbase.security.AccessDeniedException; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.token.SecretManager; import org.apache.hadoop.security.token.Token; /** * Provides a service for obtaining authentication tokens via the * {@link AuthenticationProtocol} coprocessor protocol. */ public class TokenProvider extends BaseEndpointCoprocessor implements AuthenticationProtocol { public static final long VERSION = 0L; private static Log LOG = LogFactory.getLog(TokenProvider.class); private AuthenticationTokenSecretManager secretManager; @Override public void start(CoprocessorEnvironment env) { super.start(env); // if running at region if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment regionEnv = (RegionCoprocessorEnvironment)env; RpcServer server = regionEnv.getRegionServerServices().getRpcServer(); SecretManager<?> mgr = ((HBaseServer)server).getSecretManager(); if (mgr instanceof AuthenticationTokenSecretManager) { secretManager = (AuthenticationTokenSecretManager)mgr; } } } @Override public Token<AuthenticationTokenIdentifier> getAuthenticationToken() throws IOException { if (secretManager == null) { throw new IOException( "No secret manager configured for token authentication"); } User currentUser = RequestContext.getRequestUser(); UserGroupInformation ugi = null; if (currentUser != null) { ugi = currentUser.getUGI(); } if (currentUser == null) { throw new AccessDeniedException("No authenticated user for request!"); } else if (!isAllowedDelegationTokenOp(ugi)) { LOG.warn("Token generation denied for user="+currentUser.getName() +", authMethod="+ugi.getAuthenticationMethod()); throw new AccessDeniedException( "Token generation only allowed for Kerberos authenticated clients"); } return secretManager.generateToken(currentUser.getName()); } /** * @param ugi * @return true if delegation token operation is allowed */ private boolean isAllowedDelegationTokenOp(UserGroupInformation ugi) throws IOException { AuthenticationMethod authMethod = ugi.getAuthenticationMethod(); if (authMethod == AuthenticationMethod.PROXY) { authMethod = ugi.getRealUser().getAuthenticationMethod(); } if (authMethod != AuthenticationMethod.KERBEROS && authMethod != AuthenticationMethod.KERBEROS_SSL && authMethod != AuthenticationMethod.CERTIFICATE) { return false; } return true; } @Override public String whoami() { return RequestContext.getRequestUserName(); } @Override public long getProtocolVersion(String protocol, long clientVersion) throws IOException { if (AuthenticationProtocol.class.getName().equals(protocol)) { return TokenProvider.VERSION; } LOG.warn("Unknown protocol requested: "+protocol); return -1; } }