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 */ 018package org.apache.hadoop.hbase.security.token; 019 020import java.io.DataInput; 021import java.io.DataOutput; 022import java.io.IOException; 023import org.apache.hadoop.io.Text; 024import org.apache.hadoop.security.UserGroupInformation; 025import org.apache.hadoop.security.token.TokenIdentifier; 026import org.apache.yetus.audience.InterfaceAudience; 027 028import org.apache.hbase.thirdparty.com.google.protobuf.ByteString; 029 030import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 031import org.apache.hadoop.hbase.shaded.protobuf.generated.AuthenticationProtos; 032 033/** 034 * Represents the identity information stored in an HBase authentication token. 035 */ 036@InterfaceAudience.Private 037public class AuthenticationTokenIdentifier extends TokenIdentifier { 038 public static final Text AUTH_TOKEN_TYPE = new Text("HBASE_AUTH_TOKEN"); 039 040 protected String username; 041 protected int keyId; 042 protected long issueDate; 043 protected long expirationDate; 044 protected long sequenceNumber; 045 046 public AuthenticationTokenIdentifier() { 047 } 048 049 public AuthenticationTokenIdentifier(String username) { 050 this.username = username; 051 } 052 053 public AuthenticationTokenIdentifier(String username, int keyId, long issueDate, 054 long expirationDate) { 055 this.username = username; 056 this.keyId = keyId; 057 this.issueDate = issueDate; 058 this.expirationDate = expirationDate; 059 } 060 061 @Override 062 public Text getKind() { 063 return AUTH_TOKEN_TYPE; 064 } 065 066 @Override 067 public UserGroupInformation getUser() { 068 if (username == null || "".equals(username)) { 069 return null; 070 } 071 return UserGroupInformation.createRemoteUser(username); 072 } 073 074 public String getUsername() { 075 return username; 076 } 077 078 void setUsername(String name) { 079 this.username = name; 080 } 081 082 public int getKeyId() { 083 return keyId; 084 } 085 086 void setKeyId(int id) { 087 this.keyId = id; 088 } 089 090 public long getIssueDate() { 091 return issueDate; 092 } 093 094 void setIssueDate(long timestamp) { 095 this.issueDate = timestamp; 096 } 097 098 public long getExpirationDate() { 099 return expirationDate; 100 } 101 102 void setExpirationDate(long timestamp) { 103 this.expirationDate = timestamp; 104 } 105 106 public long getSequenceNumber() { 107 return sequenceNumber; 108 } 109 110 void setSequenceNumber(long seq) { 111 this.sequenceNumber = seq; 112 } 113 114 public byte[] toBytes() { 115 AuthenticationProtos.TokenIdentifier.Builder builder = 116 AuthenticationProtos.TokenIdentifier.newBuilder(); 117 builder.setKind(AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN); 118 if (username != null) { 119 builder.setUsername(ByteString.copyFromUtf8(username)); 120 } 121 builder.setIssueDate(issueDate).setExpirationDate(expirationDate).setKeyId(keyId) 122 .setSequenceNumber(sequenceNumber); 123 return builder.build().toByteArray(); 124 } 125 126 @Override 127 public void write(DataOutput out) throws IOException { 128 byte[] pbBytes = toBytes(); 129 out.writeInt(pbBytes.length); 130 out.write(pbBytes); 131 } 132 133 @Override 134 public void readFields(DataInput in) throws IOException { 135 int len = in.readInt(); 136 byte[] inBytes = new byte[len]; 137 in.readFully(inBytes); 138 AuthenticationProtos.TokenIdentifier.Builder builder = 139 AuthenticationProtos.TokenIdentifier.newBuilder(); 140 ProtobufUtil.mergeFrom(builder, inBytes); 141 AuthenticationProtos.TokenIdentifier identifier = builder.build(); 142 // sanity check on type 143 if ( 144 !identifier.hasKind() 145 || identifier.getKind() != AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN 146 ) { 147 throw new IOException("Invalid TokenIdentifier kind from input " + identifier.getKind()); 148 } 149 150 // copy the field values 151 if (identifier.hasUsername()) { 152 username = identifier.getUsername().toStringUtf8(); 153 } 154 if (identifier.hasKeyId()) { 155 keyId = identifier.getKeyId(); 156 } 157 if (identifier.hasIssueDate()) { 158 issueDate = identifier.getIssueDate(); 159 } 160 if (identifier.hasExpirationDate()) { 161 expirationDate = identifier.getExpirationDate(); 162 } 163 if (identifier.hasSequenceNumber()) { 164 sequenceNumber = identifier.getSequenceNumber(); 165 } 166 } 167 168 @Override 169 public boolean equals(Object other) { 170 if (other == null) { 171 return false; 172 } 173 if (other instanceof AuthenticationTokenIdentifier) { 174 AuthenticationTokenIdentifier ident = (AuthenticationTokenIdentifier) other; 175 return sequenceNumber == ident.getSequenceNumber() && keyId == ident.getKeyId() 176 && issueDate == ident.getIssueDate() && expirationDate == ident.getExpirationDate() 177 && (username == null ? ident.getUsername() == null : username.equals(ident.getUsername())); 178 } 179 return false; 180 } 181 182 @Override 183 public int hashCode() { 184 return (int) sequenceNumber; 185 } 186 187 @Override 188 public String toString() { 189 return "(username=" + username + ", keyId=" + keyId + ", issueDate=" + issueDate 190 + ", expirationDate=" + expirationDate + ", sequenceNumber=" + sequenceNumber + ")"; 191 } 192}