All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.security.authentication.util.AuthToken Maven / Gradle / Ivy

The newest version!
/**
 * Licensed 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. See accompanying LICENSE file.
 */
package org.apache.hadoop.security.authentication.util;

import org.apache.hadoop.security.authentication.client.AuthenticationException;

import java.security.Principal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

/**
 */
public class AuthToken implements Principal {

  /**
   * Constant that identifies an anonymous request.
   */

  private static final String ATTR_SEPARATOR = "&";
  private static final String USER_NAME = "u";
  private static final String PRINCIPAL = "p";
  private static final String MAX_INACTIVES = "i";
  private static final String EXPIRES = "e";
  private static final String TYPE = "t";

  private final static Set ATTRIBUTES =
      new HashSet<>(Arrays.asList(USER_NAME, PRINCIPAL, EXPIRES, TYPE));

  private String userName;
  private String principal;
  private String type;
  private long maxInactives;
  private long expires;
  private String tokenStr;

  protected AuthToken() {
    userName = null;
    principal = null;
    type = null;
    maxInactives = -1;
    expires = -1;
    tokenStr = "ANONYMOUS";
    generateToken();
  }

  private static final String ILLEGAL_ARG_MSG = " is NULL, empty or contains a '" + ATTR_SEPARATOR + "'";

  /**
   * Creates an authentication token.
   *
   * @param userName user name.
   * @param principal principal (commonly matches the user name, with Kerberos is the full/long principal
   * name while the userName is the short name).
   * @param type the authentication mechanism name.
   * (System.currentTimeMillis() + validityPeriod).
   */
  public AuthToken(String userName, String principal, String type) {
    checkForIllegalArgument(userName, "userName");
    checkForIllegalArgument(principal, "principal");
    checkForIllegalArgument(type, "type");
    this.userName = userName;
    this.principal = principal;
    this.type = type;
    this.maxInactives = -1;
    this.expires = -1;
  }
  
  /**
   * Check if the provided value is invalid. Throw an error if it is invalid, NOP otherwise.
   * 
   * @param value the value to check.
   * @param name the parameter name to use in an error message if the value is invalid.
   */
  protected static void checkForIllegalArgument(String value, String name) {
    if (value == null || value.length() == 0 || value.contains(ATTR_SEPARATOR)) {
      throw new IllegalArgumentException(name + ILLEGAL_ARG_MSG);
    }
  }

  /**
   * Sets the max inactive interval of the token.
   *
   * @param interval max inactive interval of the token in milliseconds since
   *                 the epoch.
   */
  public void setMaxInactives(long interval) {
    this.maxInactives = interval;
  }

  /**
   * Sets the expiration of the token.
   *
   * @param expires expiration time of the token in milliseconds since the epoch.
   */
  public void setExpires(long expires) {
    this.expires = expires;
      generateToken();
  }

  /**
   * Returns true if the token has expired.
   *
   * @return true if the token has expired.
   */
  public boolean isExpired() {
    return (getMaxInactives() != -1 &&
        System.currentTimeMillis() > getMaxInactives())
        || (getExpires() != -1 &&
        System.currentTimeMillis() > getExpires());
  }

  /**
   * Generates the token.
   */
  private void generateToken() {
    StringBuffer sb = new StringBuffer();
    sb.append(USER_NAME).append("=").append(getUserName()).append(ATTR_SEPARATOR);
    sb.append(PRINCIPAL).append("=").append(getName()).append(ATTR_SEPARATOR);
    sb.append(TYPE).append("=").append(getType()).append(ATTR_SEPARATOR);
    if (getMaxInactives() != -1) {
      sb.append(MAX_INACTIVES).append("=")
      .append(getMaxInactives()).append(ATTR_SEPARATOR);
    }
    sb.append(EXPIRES).append("=").append(getExpires());
    tokenStr = sb.toString();
  }

  /**
   * Returns the user name.
   *
   * @return the user name.
   */
  public String getUserName() {
    return userName;
  }

  /**
   * Returns the principal name (this method name comes from the JDK {@link Principal} interface).
   *
   * @return the principal name.
   */
  @Override
  public String getName() {
    return principal;
  }

  /**
   * Returns the authentication mechanism of the token.
   *
   * @return the authentication mechanism of the token.
   */
  public String getType() {
    return type;
  }

  /**
   * Returns the max inactive time of the token.
   *
   * @return the max inactive time of the token, in milliseconds since Epoc.
   */
  public long getMaxInactives() {
    return maxInactives;
  }

  /**
   * Returns the expiration time of the token.
   *
   * @return the expiration time of the token, in milliseconds since Epoc.
   */
  public long getExpires() {
    return expires;
  }

  /**
   * Returns the string representation of the token.
   * 

* This string representation is parseable by the {@link #parse} method. * * @return the string representation of the token. */ @Override public String toString() { return tokenStr; } public static AuthToken parse(String tokenStr) throws AuthenticationException { if (tokenStr.length() >= 2) { // strip the \" at the two ends of the tokenStr if (tokenStr.charAt(0) == '\"' && tokenStr.charAt(tokenStr.length()-1) == '\"') { tokenStr = tokenStr.substring(1, tokenStr.length()-1); } } Map map = split(tokenStr); // remove the signature part, since client doesn't care about it map.remove("s"); if (!map.keySet().containsAll(ATTRIBUTES)) { throw new AuthenticationException("Invalid token string, missing attributes"); } long expires = Long.parseLong(map.get(EXPIRES)); AuthToken token = new AuthToken(map.get(USER_NAME), map.get(PRINCIPAL), map.get(TYPE)); //process optional attributes if (map.containsKey(MAX_INACTIVES)) { long maxInactives = Long.parseLong(map.get(MAX_INACTIVES)); token.setMaxInactives(maxInactives); } token.setExpires(expires); return token; } /** * Splits the string representation of a token into attributes pairs. * * @param tokenStr string representation of a token. * * @return a map with the attribute pairs of the token. * * @throws AuthenticationException thrown if the string representation of the token could not be broken into * attribute pairs. */ private static Map split(String tokenStr) throws AuthenticationException { Map map = new HashMap(); StringTokenizer st = new StringTokenizer(tokenStr, ATTR_SEPARATOR); while (st.hasMoreTokens()) { String part = st.nextToken(); int separator = part.indexOf('='); if (separator == -1) { throw new AuthenticationException("Invalid authentication token"); } String key = part.substring(0, separator); String value = part.substring(separator + 1); map.put(key, value); } return map; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy