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