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.ProtobufUtil;
24  import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos;
25  import org.apache.hadoop.io.Text;
26  import org.apache.hadoop.security.UserGroupInformation;
27  import org.apache.hadoop.security.token.TokenIdentifier;
28  
29  import java.io.DataInput;
30  import java.io.DataOutput;
31  import java.io.IOException;
32  
33  /**
34   * Represents the identity information stored in an HBase authentication token.
35   */
36  @InterfaceAudience.Private
37  public class AuthenticationTokenIdentifier extends TokenIdentifier {
38    public static final Text AUTH_TOKEN_TYPE = new Text("HBASE_AUTH_TOKEN");
39  
40    protected String username;
41    protected int keyId;
42    protected long issueDate;
43    protected long expirationDate;
44    protected long sequenceNumber;
45  
46    public AuthenticationTokenIdentifier() {
47    }
48  
49    public AuthenticationTokenIdentifier(String username) {
50      this.username = username;
51    }
52  
53    public AuthenticationTokenIdentifier(String username, int keyId,
54        long issueDate, long expirationDate) {
55      this.username = username;
56      this.keyId = keyId;
57      this.issueDate = issueDate;
58      this.expirationDate = expirationDate;
59    }
60  
61    @Override
62    public Text getKind() {
63      return AUTH_TOKEN_TYPE;
64    }
65  
66    @Override
67    public UserGroupInformation getUser() {
68      if (username == null || "".equals(username)) {
69        return null;
70      }
71      return UserGroupInformation.createRemoteUser(username);
72    }
73  
74    public String getUsername() {
75      return username;
76    }
77  
78    void setUsername(String name) {
79      this.username = name;
80    }
81  
82    public int getKeyId() {
83      return keyId;
84    }
85  
86    void setKeyId(int id) {
87      this.keyId = id;
88    }
89  
90    public long getIssueDate() {
91      return issueDate;
92    }
93  
94    void setIssueDate(long timestamp) {
95      this.issueDate = timestamp;
96    }
97  
98    public long getExpirationDate() {
99      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)
122         .setExpirationDate(expirationDate)
123         .setKeyId(keyId)
124         .setSequenceNumber(sequenceNumber);
125     return builder.build().toByteArray();
126   }
127 
128   @Override
129   public void write(DataOutput out) throws IOException {
130     byte[] pbBytes = toBytes();
131     out.writeInt(pbBytes.length);
132     out.write(pbBytes);
133   }
134 
135   @Override
136   public void readFields(DataInput in) throws IOException {
137     int len = in.readInt();
138     byte[] inBytes = new byte[len];
139     in.readFully(inBytes);
140     AuthenticationProtos.TokenIdentifier.Builder builder =
141       AuthenticationProtos.TokenIdentifier.newBuilder();
142     ProtobufUtil.mergeFrom(builder, inBytes);
143     AuthenticationProtos.TokenIdentifier identifier = builder.build();
144     // sanity check on type
145     if (!identifier.hasKind() ||
146         identifier.getKind() != AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN) {
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()
176           && keyId == ident.getKeyId()
177           && issueDate == ident.getIssueDate()
178           && expirationDate == ident.getExpirationDate()
179           && (username == null ? ident.getUsername() == null :
180               username.equals(ident.getUsername()));
181     }
182     return false;
183   }
184 
185   @Override
186   public int hashCode() {
187     return (int)sequenceNumber;
188   }
189 }