/** * The function will verify the token with NameNode if available and will create a * UserGroupInformation. * * <p>Code in this function is copied from JspHelper.getTokenUGI * * @param identifier Delegation token identifier * @param password Delegation token password * @param kind the kind of token * @param service the service for this token * @param servletContext Jetty servlet context which contains the NN address * @throws SecurityException Thrown when authentication fails */ private static void verifyToken( byte[] identifier, byte[] password, Text kind, Text service, ServletContext servletContext) { try { Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(identifier, password, kind, service); ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier()); DataInputStream in = new DataInputStream(buf); DelegationTokenIdentifier id = new DelegationTokenIdentifier(); id.readFields(in); final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(servletContext); if (nn != null) { nn.getNamesystem().verifyToken(id, token.getPassword()); } UserGroupInformation userGroupInformation = id.getUser(); userGroupInformation.addToken(token); LOG.debug( "user " + userGroupInformation.getUserName() + " (" + userGroupInformation.getShortUserName() + ") authenticated"); // re-login if necessary userGroupInformation.checkTGTAndReloginFromKeytab(); } catch (IOException e) { throw new SecurityException("Failed to verify delegation token " + e, e); } }
public static HdfsProtos.BlockTokenIdentifierProto toProto(Token<?> blockToken) { return HdfsProtos.BlockTokenIdentifierProto.newBuilder() .setIdentifier(ByteString.copyFrom(blockToken.getIdentifier())) .setPassword(ByteString.copyFrom(blockToken.getPassword())) .setKind(blockToken.getKind().toString()) .setService(blockToken.getService().toString()) .build(); }
/** * Renew a delegation token. * * @param token the token to renew * @param renewer the full principal name of the user doing the renewal * @return the new expiration time * @throws InvalidToken if the token is invalid * @throws AccessControlException if the user can't renew token */ public synchronized long renewToken(Token<TokenIdent> token, String renewer) throws InvalidToken, IOException { long now = System.currentTimeMillis(); ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier()); DataInputStream in = new DataInputStream(buf); TokenIdent id = createIdentifier(); id.readFields(in); LOG.info("Token renewal requested for identifier: " + id); if (id.getMaxDate() < now) { throw new InvalidToken("User " + renewer + " tried to renew an expired token"); } if ((id.getRenewer() == null) || ("".equals(id.getRenewer().toString()))) { throw new AccessControlException( "User " + renewer + " tried to renew a token without " + "a renewer"); } if (!id.getRenewer().toString().equals(renewer)) { throw new AccessControlException( "Client " + renewer + " tries to renew a token with " + "renewer specified as " + id.getRenewer()); } DelegationKey key = allKeys.get(id.getMasterKeyId()); if (key == null) { throw new InvalidToken( "Unable to find master key for keyId=" + id.getMasterKeyId() + " from cache. Failed to renew an unexpired token" + " with sequenceNumber=" + id.getSequenceNumber()); } byte[] password = createPassword(token.getIdentifier(), key.getKey()); if (!Arrays.equals(password, token.getPassword())) { throw new AccessControlException( "Client " + renewer + " is trying to renew a token with " + "wrong password"); } long renewTime = Math.min(id.getMaxDate(), now + tokenRenewInterval); DelegationTokenInformation info = new DelegationTokenInformation(renewTime, password); if (currentTokens.get(id) == null) { throw new InvalidToken("Renewal request for unknown token"); } currentTokens.put(id, info); return renewTime; }
/** * The function will get the token information from parameters and call SecuredHDFS to verify the * token. * * <p>All token properties will be deserialized from string to a Token object * * @param protData input parameters * @param context servlet context which contains the NN address * @throws SecurityException Thrown when authentication fails */ public static void verifyToken(ProtocolData protData, ServletContext context) { try { if (UserGroupInformation.isSecurityEnabled()) { Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(); String tokenString = protData.getToken(); token.decodeFromUrlString(tokenString); verifyToken( token.getIdentifier(), token.getPassword(), token.getKind(), token.getService(), context); } } catch (IOException e) { throw new SecurityException("Failed to verify delegation token " + e, e); } }
/** * Get {@link UserGroupInformation} and possibly the delegation token out of the request. * * @param context the Servlet context * @param request the http request * @param conf configuration * @param secureAuthMethod the AuthenticationMethod used in secure mode. * @param tryUgiParameter Should it try the ugi parameter? * @return a new user from the request * @throws AccessControlException if the request has no token */ public static UserGroupInformation getUGI( ServletContext context, HttpServletRequest request, Configuration conf, final AuthenticationMethod secureAuthMethod, final boolean tryUgiParameter) throws IOException { final UserGroupInformation ugi; final String usernameFromQuery = getUsernameFromQuery(request, tryUgiParameter); final String doAsUserFromQuery = request.getParameter(DoAsParam.NAME); if (UserGroupInformation.isSecurityEnabled()) { final String remoteUser = request.getRemoteUser(); String tokenString = request.getParameter(DELEGATION_PARAMETER_NAME); if (tokenString != null) { Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(); token.decodeFromUrlString(tokenString); SecurityUtil.setTokenService(token, NameNode.getAddress(conf)); token.setKind(DelegationTokenIdentifier.HDFS_DELEGATION_KIND); ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier()); DataInputStream in = new DataInputStream(buf); DelegationTokenIdentifier id = new DelegationTokenIdentifier(); id.readFields(in); if (context != null) { NameNode nn = (NameNode) context.getAttribute("name.node"); if (nn != null) { // Verify the token. nn.getNamesystem() .getDelegationTokenSecretManager() .verifyToken(id, token.getPassword()); } } ugi = id.getUser(); if (ugi.getRealUser() == null) { // non-proxy case checkUsername(ugi.getShortUserName(), usernameFromQuery); checkUsername(null, doAsUserFromQuery); } else { // proxy case checkUsername(ugi.getRealUser().getShortUserName(), usernameFromQuery); checkUsername(ugi.getShortUserName(), doAsUserFromQuery); ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf); } ugi.addToken(token); ugi.setAuthenticationMethod(AuthenticationMethod.TOKEN); } else { if (remoteUser == null) { throw new IOException("Security enabled but user not " + "authenticated by filter"); } final UserGroupInformation realUgi = UserGroupInformation.createRemoteUser(remoteUser); checkUsername(realUgi.getShortUserName(), usernameFromQuery); // This is not necessarily true, could have been auth'ed by user-facing // filter realUgi.setAuthenticationMethod(secureAuthMethod); ugi = initUGI(realUgi, doAsUserFromQuery, request, true, conf); } } else { // Security's not on, pull from url final UserGroupInformation realUgi = usernameFromQuery == null ? getDefaultWebUser(conf) // not specified in request : UserGroupInformation.createRemoteUser(usernameFromQuery); realUgi.setAuthenticationMethod(AuthenticationMethod.SIMPLE); ugi = initUGI(realUgi, doAsUserFromQuery, request, false, conf); } if (LOG.isDebugEnabled()) LOG.debug("getUGI is returning: " + ugi.getShortUserName()); return ugi; }