001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.hbase.security.token; 020 021import java.io.DataInput; 022import java.io.DataOutput; 023import java.io.IOException; 024 025import org.apache.yetus.audience.InterfaceAudience; 026import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 027import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos; 028import org.apache.hadoop.io.Text; 029import org.apache.hadoop.security.UserGroupInformation; 030import org.apache.hadoop.security.token.TokenIdentifier; 031 032import com.google.protobuf.ByteString; 033 034/** 035 * Represents the identity information stored in an HBase authentication token. 036 */ 037@InterfaceAudience.Private 038public class AuthenticationTokenIdentifier extends TokenIdentifier { 039 public static final Text AUTH_TOKEN_TYPE = new Text("HBASE_AUTH_TOKEN"); 040 041 protected String username; 042 protected int keyId; 043 protected long issueDate; 044 protected long expirationDate; 045 protected long sequenceNumber; 046 047 public AuthenticationTokenIdentifier() { 048 } 049 050 public AuthenticationTokenIdentifier(String username) { 051 this.username = username; 052 } 053 054 public AuthenticationTokenIdentifier(String username, int keyId, 055 long issueDate, long expirationDate) { 056 this.username = username; 057 this.keyId = keyId; 058 this.issueDate = issueDate; 059 this.expirationDate = expirationDate; 060 } 061 062 @Override 063 public Text getKind() { 064 return AUTH_TOKEN_TYPE; 065 } 066 067 @Override 068 public UserGroupInformation getUser() { 069 if (username == null || "".equals(username)) { 070 return null; 071 } 072 return UserGroupInformation.createRemoteUser(username); 073 } 074 075 public String getUsername() { 076 return username; 077 } 078 079 void setUsername(String name) { 080 this.username = name; 081 } 082 083 public int getKeyId() { 084 return keyId; 085 } 086 087 void setKeyId(int id) { 088 this.keyId = id; 089 } 090 091 public long getIssueDate() { 092 return issueDate; 093 } 094 095 void setIssueDate(long timestamp) { 096 this.issueDate = timestamp; 097 } 098 099 public long getExpirationDate() { 100 return expirationDate; 101 } 102 103 void setExpirationDate(long timestamp) { 104 this.expirationDate = timestamp; 105 } 106 107 public long getSequenceNumber() { 108 return sequenceNumber; 109 } 110 111 void setSequenceNumber(long seq) { 112 this.sequenceNumber = seq; 113 } 114 115 public byte[] toBytes() { 116 AuthenticationProtos.TokenIdentifier.Builder builder = 117 AuthenticationProtos.TokenIdentifier.newBuilder(); 118 builder.setKind(AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN); 119 if (username != null) { 120 builder.setUsername(ByteString.copyFromUtf8(username)); 121 } 122 builder.setIssueDate(issueDate) 123 .setExpirationDate(expirationDate) 124 .setKeyId(keyId) 125 .setSequenceNumber(sequenceNumber); 126 return builder.build().toByteArray(); 127 } 128 129 @Override 130 public void write(DataOutput out) throws IOException { 131 byte[] pbBytes = toBytes(); 132 out.writeInt(pbBytes.length); 133 out.write(pbBytes); 134 } 135 136 @Override 137 public void readFields(DataInput in) throws IOException { 138 int len = in.readInt(); 139 byte[] inBytes = new byte[len]; 140 in.readFully(inBytes); 141 AuthenticationProtos.TokenIdentifier.Builder builder = 142 AuthenticationProtos.TokenIdentifier.newBuilder(); 143 ProtobufUtil.mergeFrom(builder, inBytes); 144 AuthenticationProtos.TokenIdentifier identifier = builder.build(); 145 // sanity check on type 146 if (!identifier.hasKind() || 147 identifier.getKind() != AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN) { 148 throw new IOException("Invalid TokenIdentifier kind from input "+identifier.getKind()); 149 } 150 151 // copy the field values 152 if (identifier.hasUsername()) { 153 username = identifier.getUsername().toStringUtf8(); 154 } 155 if (identifier.hasKeyId()) { 156 keyId = identifier.getKeyId(); 157 } 158 if (identifier.hasIssueDate()) { 159 issueDate = identifier.getIssueDate(); 160 } 161 if (identifier.hasExpirationDate()) { 162 expirationDate = identifier.getExpirationDate(); 163 } 164 if (identifier.hasSequenceNumber()) { 165 sequenceNumber = identifier.getSequenceNumber(); 166 } 167 } 168 169 @Override 170 public boolean equals(Object other) { 171 if (other == null) { 172 return false; 173 } 174 if (other instanceof AuthenticationTokenIdentifier) { 175 AuthenticationTokenIdentifier ident = (AuthenticationTokenIdentifier)other; 176 return sequenceNumber == ident.getSequenceNumber() 177 && keyId == ident.getKeyId() 178 && issueDate == ident.getIssueDate() 179 && expirationDate == ident.getExpirationDate() 180 && (username == null ? ident.getUsername() == null : 181 username.equals(ident.getUsername())); 182 } 183 return false; 184 } 185 186 @Override 187 public int hashCode() { 188 return (int)sequenceNumber; 189 } 190 191 @Override 192 public String toString() { 193 return "(username=" + username + ", keyId=" 194 + keyId + ", issueDate=" + issueDate 195 + ", expirationDate=" + expirationDate + ", sequenceNumber=" + sequenceNumber + ")"; 196 } 197}