blob: 59a48298a4bd6b2c120550ce805a124fbb991037 [file] [log] [blame]
/*
* 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.accumulo.core.client.impl;
import static java.util.Objects.requireNonNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import org.apache.accumulo.core.client.security.tokens.DelegationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DelegationTokenImpl extends PasswordToken implements DelegationToken {
private static final Logger log = LoggerFactory.getLogger(DelegationTokenImpl.class);
public static final String SERVICE_NAME = "AccumuloDelegationToken";
private AuthenticationTokenIdentifier identifier;
public DelegationTokenImpl() {
super();
}
public DelegationTokenImpl(byte[] delegationTokenPassword,
AuthenticationTokenIdentifier identifier) {
requireNonNull(delegationTokenPassword);
requireNonNull(identifier);
setPassword(delegationTokenPassword);
this.identifier = identifier;
}
public DelegationTokenImpl(String instanceID, UserGroupInformation user,
AuthenticationTokenIdentifier identifier) {
requireNonNull(instanceID);
requireNonNull(user);
requireNonNull(identifier);
Credentials creds = user.getCredentials();
Token<? extends TokenIdentifier> token = creds
.getToken(new Text(SERVICE_NAME + "-" + instanceID));
if (null == token) {
throw new IllegalArgumentException(
"Did not find Accumulo delegation token in provided UserGroupInformation");
}
setPasswordFromToken(token, identifier);
}
public DelegationTokenImpl(Token<? extends TokenIdentifier> token,
AuthenticationTokenIdentifier identifier) {
requireNonNull(token);
requireNonNull(identifier);
setPasswordFromToken(token, identifier);
}
private void setPasswordFromToken(Token<? extends TokenIdentifier> token,
AuthenticationTokenIdentifier identifier) {
if (!AuthenticationTokenIdentifier.TOKEN_KIND.equals(token.getKind())) {
String msg = "Expected an AuthenticationTokenIdentifier but got a " + token.getKind();
log.error(msg);
throw new IllegalArgumentException(msg);
}
setPassword(token.getPassword());
this.identifier = identifier;
}
/**
* The identifier for this token, may be null.
*/
public AuthenticationTokenIdentifier getIdentifier() {
return identifier;
}
/**
* The service name used to identify the {@link Token}
*/
public Text getServiceName() {
requireNonNull(identifier);
return new Text(SERVICE_NAME + "-" + identifier.getInstanceId());
}
@Override
public void init(Properties properties) {
// Encourage use of UserGroupInformation as entry point
}
@Override
public Set<TokenProperty> getProperties() {
// Encourage use of UserGroupInformation as entry point
return Collections.emptySet();
}
@Override
public void write(DataOutput out) throws IOException {
super.write(out);
identifier.write(out);
}
@Override
public void readFields(DataInput in) throws IOException {
super.readFields(in);
identifier = new AuthenticationTokenIdentifier();
identifier.readFields(in);
}
@Override
public DelegationTokenImpl clone() {
DelegationTokenImpl copy = (DelegationTokenImpl) super.clone();
copy.setPassword(getPassword());
copy.identifier = new AuthenticationTokenIdentifier(identifier);
return copy;
}
@Override
public int hashCode() {
return super.hashCode() ^ identifier.hashCode();
}
@Override
public boolean equals(Object obj) {
// We assume we can cast obj to DelegationToken because the super.equals(obj) check ensures obj
// is of the same type as this
return super.equals(obj) && identifier.equals(((DelegationTokenImpl) obj).identifier);
}
}