View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.security.token;
20  
21  import java.io.DataInput;
22  import java.io.DataOutput;
23  import java.io.IOException;
24  
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
27  import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos;
28  import org.apache.hadoop.io.Text;
29  import org.apache.hadoop.security.UserGroupInformation;
30  import org.apache.hadoop.security.token.TokenIdentifier;
31  
32  import com.google.protobuf.ByteString;
33  
34  /**
35   * Represents the identity information stored in an HBase authentication token.
36   */
37  @InterfaceAudience.Private
38  public class AuthenticationTokenIdentifier extends TokenIdentifier {
39    public static final Text AUTH_TOKEN_TYPE = new Text("HBASE_AUTH_TOKEN");
40  
41    protected String username;
42    protected int keyId;
43    protected long issueDate;
44    protected long expirationDate;
45    protected long sequenceNumber;
46  
47    public AuthenticationTokenIdentifier() {
48    }
49  
50    public AuthenticationTokenIdentifier(String username) {
51      this.username = username;
52    }
53  
54    public AuthenticationTokenIdentifier(String username, int keyId,
55        long issueDate, long expirationDate) {
56      this.username = username;
57      this.keyId = keyId;
58      this.issueDate = issueDate;
59      this.expirationDate = expirationDate;
60    }
61  
62    @Override
63    public Text getKind() {
64      return AUTH_TOKEN_TYPE;
65    }
66  
67    @Override
68    public UserGroupInformation getUser() {
69      if (username == null || "".equals(username)) {
70        return null;
71      }
72      return UserGroupInformation.createRemoteUser(username);
73    }
74  
75    public String getUsername() {
76      return username;
77    }
78  
79    void setUsername(String name) {
80      this.username = name;
81    }
82  
83    public int getKeyId() {
84      return keyId;
85    }
86  
87    void setKeyId(int id) {
88      this.keyId = id;
89    }
90  
91    public long getIssueDate() {
92      return issueDate;
93    }
94  
95    void setIssueDate(long timestamp) {
96      this.issueDate = timestamp;
97    }
98  
99    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 }