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 com.google.protobuf.ByteString;
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos;
24  import org.apache.hadoop.io.Text;
25  import org.apache.hadoop.security.UserGroupInformation;
26  import org.apache.hadoop.security.token.TokenIdentifier;
27  
28  import java.io.DataInput;
29  import java.io.DataOutput;
30  import java.io.IOException;
31  
32  /**
33   * Represents the identity information stored in an HBase authentication token.
34   */
35  @InterfaceAudience.Private
36  public class AuthenticationTokenIdentifier extends TokenIdentifier {
37    public static final Text AUTH_TOKEN_TYPE = new Text("HBASE_AUTH_TOKEN");
38  
39    protected String username;
40    protected int keyId;
41    protected long issueDate;
42    protected long expirationDate;
43    protected long sequenceNumber;
44    
45    public AuthenticationTokenIdentifier() {
46    }
47  
48    public AuthenticationTokenIdentifier(String username) {
49      this.username = username;
50    }
51  
52    public AuthenticationTokenIdentifier(String username, int keyId,
53        long issueDate, long expirationDate) {
54      this.username = username;
55      this.keyId = keyId;
56      this.issueDate = issueDate;
57      this.expirationDate = expirationDate;
58    }
59  
60    @Override
61    public Text getKind() {
62      return AUTH_TOKEN_TYPE;
63    }
64  
65    @Override
66    public UserGroupInformation getUser() {
67      if (username == null || "".equals(username)) {
68        return null;
69      }
70      return UserGroupInformation.createRemoteUser(username);
71    }
72  
73    public String getUsername() {
74      return username;
75    }
76  
77    void setUsername(String name) {
78      this.username = name;
79    }
80  
81    public int getKeyId() {
82      return keyId;
83    }
84  
85    void setKeyId(int id) {
86      this.keyId = id;
87    }
88  
89    public long getIssueDate() {
90      return issueDate;
91    }
92  
93    void setIssueDate(long timestamp) {
94      this.issueDate = timestamp;
95    }
96  
97    public long getExpirationDate() {
98      return expirationDate;
99    }
100 
101   void setExpirationDate(long timestamp) {
102     this.expirationDate = timestamp;
103   }
104 
105   public long getSequenceNumber() {
106     return sequenceNumber;
107   }
108 
109   void setSequenceNumber(long seq) {
110     this.sequenceNumber = seq;
111   }
112 
113   public byte[] toBytes() {
114     AuthenticationProtos.TokenIdentifier.Builder builder =
115         AuthenticationProtos.TokenIdentifier.newBuilder();
116     builder.setKind(AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN);
117     if (username != null) {
118       builder.setUsername(ByteString.copyFromUtf8(username));
119     }
120     builder.setIssueDate(issueDate)
121         .setExpirationDate(expirationDate)
122         .setKeyId(keyId)
123         .setSequenceNumber(sequenceNumber);
124     return builder.build().toByteArray();
125   }
126 
127   @Override
128   public void write(DataOutput out) throws IOException {
129     byte[] pbBytes = toBytes();
130     out.writeInt(pbBytes.length);
131     out.write(pbBytes);
132   }
133 
134   @Override
135   public void readFields(DataInput in) throws IOException {
136     int len = in.readInt();
137     byte[] inBytes = new byte[len];
138     in.readFully(inBytes);
139     AuthenticationProtos.TokenIdentifier identifier =
140         AuthenticationProtos.TokenIdentifier.newBuilder().mergeFrom(inBytes).build();
141     // sanity check on type
142     if (!identifier.hasKind() ||
143         identifier.getKind() != AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN) {
144       throw new IOException("Invalid TokenIdentifier kind from input "+identifier.getKind());
145     }
146 
147     // copy the field values
148     if (identifier.hasUsername()) {
149       username = identifier.getUsername().toStringUtf8();
150     }
151     if (identifier.hasKeyId()) {
152       keyId = identifier.getKeyId();
153     }
154     if (identifier.hasIssueDate()) {
155       issueDate = identifier.getIssueDate();
156     }
157     if (identifier.hasExpirationDate()) {
158       expirationDate = identifier.getExpirationDate();
159     }
160     if (identifier.hasSequenceNumber()) {
161       sequenceNumber = identifier.getSequenceNumber();
162     }
163   }
164 
165   @Override
166   public boolean equals(Object other) {
167     if (other == null) {
168       return false;
169     }
170     if (other instanceof AuthenticationTokenIdentifier) {
171       AuthenticationTokenIdentifier ident = (AuthenticationTokenIdentifier)other;
172       return sequenceNumber == ident.getSequenceNumber()
173           && keyId == ident.getKeyId()
174           && issueDate == ident.getIssueDate()
175           && expirationDate == ident.getExpirationDate()
176           && (username == null ? ident.getUsername() == null :
177               username.equals(ident.getUsername()));
178     }
179     return false;
180   }
181 
182   @Override
183   public int hashCode() {
184     return (int)sequenceNumber;
185   }
186 }