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.generated.AuthenticationProtos;
27  import org.apache.hadoop.io.Text;
28  import org.apache.hadoop.security.UserGroupInformation;
29  import org.apache.hadoop.security.token.TokenIdentifier;
30  
31  import com.google.protobuf.ByteString;
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 identifier =
141         AuthenticationProtos.TokenIdentifier.newBuilder().mergeFrom(inBytes).build();
142     // sanity check on type
143     if (!identifier.hasKind() ||
144         identifier.getKind() != AuthenticationProtos.TokenIdentifier.Kind.HBASE_AUTH_TOKEN) {
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()
174           && keyId == ident.getKeyId()
175           && issueDate == ident.getIssueDate()
176           && expirationDate == ident.getExpirationDate()
177           && (username == null ? ident.getUsername() == null :
178               username.equals(ident.getUsername()));
179     }
180     return false;
181   }
182 
183   @Override
184   public int hashCode() {
185     return (int)sequenceNumber;
186   }
187 }