KerberosTicketpublic class KerberosTicket extends Object implements Destroyable, Refreshable, SerializableThis class encapsulates a Kerberos ticket and associated
information as viewed from the client's point of view. It captures all
information that the Key Distribution Center (KDC) sends to the client
in the reply message KDC-REP defined in the Kerberos Protocol
Specification (RFC 1510).
All Kerberos JAAS login modules that authenticate a user to a KDC should
use this class. Where available, the login module might even read this
information from a ticket cache in the operating system instead of
directly communicating with the KDC. During the commit phase of the JAAS
authentication process, the JAAS login module should instantiate this
class and store the instance in the private credential set of a
{@link javax.security.auth.Subject Subject}.
It might be necessary for the application to be granted a
{@link javax.security.auth.PrivateCredentialPermission
PrivateCredentialPermission} if it needs to access a KerberosTicket
instance from a Subject. This permission is not needed when the
application depends on the default JGSS Kerberos mechanism to access the
KerberosTicket. In that case, however, the application will need an
appropriate
{@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
Note that this class is applicable to both ticket granting tickets and
other regular service tickets. A ticket granting ticket is just a
special case of a more generalized service ticket. |
Fields Summary |
---|
private static final long | serialVersionUID | private static final int | FORWARDABLE_TICKET_FLAG | private static final int | FORWARDED_TICKET_FLAG | private static final int | PROXIABLE_TICKET_FLAG | private static final int | PROXY_TICKET_FLAG | private static final int | POSTDATED_TICKET_FLAG | private static final int | RENEWABLE_TICKET_FLAG | private static final int | INITIAL_TICKET_FLAG | private static final int | NUM_FLAGS | private byte[] | asn1EncodingASN.1 DER Encoding of the Ticket as defined in the
Kerberos Protocol Specification RFC1510. | private KeyImpl | sessionKeyKeyImpl is serialized by writing out the ASN1 Encoded bytes
of the encryption key. The ASN1 encoding is defined in RFC1510 and as
follows:
EncryptionKey ::= SEQUENCE {
keytype[0] INTEGER,
keyvalue[1] OCTET STRING
}
| private boolean[] | flagsTicket Flags as defined in the Kerberos Protocol Specification RFC1510. | private Date | authTimeTime of initial authentication | private Date | startTimeTime after which the ticket is valid. | private Date | endTimeTime after which the ticket will not be honored. (its expiration time). | private Date | renewTillFor renewable Tickets it indicates the maximum endtime that may be
included in a renewal. It can be thought of as the absolute expiration
time for the ticket, including all renewals. This field may be null
for tickets that are not renewable. | private KerberosPrincipal | clientClient that owns the service ticket | private KerberosPrincipal | serverThe service for which the ticket was issued. | private InetAddress[] | clientAddressesThe addresses from where the ticket may be used by the client.
This field may be null when the ticket is usable from any address. | private transient boolean | destroyed |
Constructors Summary |
---|
public KerberosTicket(byte[] asn1Encoding, KerberosPrincipal client, KerberosPrincipal server, byte[] sessionKey, int keyType, boolean[] flags, Date authTime, Date startTime, Date endTime, Date renewTill, InetAddress[] clientAddresses)Constructs a KerberosTicket using credentials information that a
client either receives from a KDC or reads from a cache.
init(asn1Encoding, client, server, sessionKey, keyType, flags,
authTime, startTime, endTime, renewTill, clientAddresses);
|
Methods Summary |
---|
public void | destroy()Destroys the ticket and destroys any sensitive information stored in
it.
if (!destroyed) {
Arrays.fill(asn1Encoding, (byte) 0);
client = null;
server = null;
sessionKey.destroy();
flags = null;
authTime = null;
startTime = null;
endTime = null;
renewTill = null;
clientAddresses = null;
destroyed = true;
}
| public final java.util.Date | getAuthTime()Returns the time that the client was authenticated.
return (authTime == null) ? null : new Date(authTime.getTime());
| public final javax.security.auth.kerberos.KerberosPrincipal | getClient()Returns the client principal associated with this ticket.
return client;
| public final java.net.InetAddress[] | getClientAddresses()Returns a list of addresses from where the ticket can be used.
return (clientAddresses == null?
null: (InetAddress[]) clientAddresses.clone());
| public final byte[] | getEncoded()Returns an ASN.1 encoding of the entire ticket.
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return (byte[]) asn1Encoding.clone();
| public final java.util.Date | getEndTime()Returns the expiration time for this ticket's validity period.
return (endTime == null) ? null : new Date(endTime.getTime());
| public final boolean[] | getFlags()Returns the flags associated with this ticket. Each element in the
returned array indicates the value for the corresponding bit in the
ASN.1 BitString that represents the ticket flags.
return (flags == null? null: (boolean[]) flags.clone());
| public final java.util.Date | getRenewTill()Returns the latest expiration time for this ticket, including all
renewals. This will return a null value for non-renewable tickets.
return (renewTill == null) ? null: new Date(renewTill.getTime());
| public final javax.security.auth.kerberos.KerberosPrincipal | getServer()Returns the service principal associated with this ticket.
return server;
| public final javax.crypto.SecretKey | getSessionKey()Returns the session key associated with this ticket.
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return sessionKey;
| public final int | getSessionKeyType()Returns the key type of the session key associated with this
ticket as defined by the Kerberos Protocol Specification.
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return sessionKey.getKeyType();
| public final java.util.Date | getStartTime()Returns the start time for this ticket's validity period.
return (startTime == null) ? null : new Date(startTime.getTime());
| private void | init(byte[] asn1Encoding, javax.security.auth.kerberos.KerberosPrincipal client, javax.security.auth.kerberos.KerberosPrincipal server, byte[] sessionKey, int keyType, boolean[] flags, java.util.Date authTime, java.util.Date startTime, java.util.Date endTime, java.util.Date renewTill, java.net.InetAddress[] clientAddresses)
if (asn1Encoding == null)
throw new IllegalArgumentException("ASN.1 encoding of ticket"
+ " cannot be null");
this.asn1Encoding = asn1Encoding.clone();
if (client == null)
throw new IllegalArgumentException("Client name in ticket"
+ " cannot be null");
this.client = client;
if (server == null)
throw new IllegalArgumentException("Server name in ticket"
+ " cannot be null");
this.server = server;
if (sessionKey == null)
throw new IllegalArgumentException("Session key for ticket"
+ " cannot be null");
this.sessionKey = new KeyImpl(sessionKey, keyType);
if (flags != null) {
if (flags.length >= NUM_FLAGS)
this.flags = (boolean[]) flags.clone();
else {
this.flags = new boolean[NUM_FLAGS];
// Fill in whatever we have
for (int i = 0; i < flags.length; i++)
this.flags[i] = flags[i];
}
} else
this.flags = new boolean[NUM_FLAGS];
if (this.flags[RENEWABLE_TICKET_FLAG]) {
if (renewTill == null)
throw new IllegalArgumentException("The renewable period "
+ "end time cannot be null for renewable tickets.");
this.renewTill = renewTill;
}
if (authTime == null)
throw new IllegalArgumentException("Authentication time of ticket"
+ " cannot be null");
this.authTime = authTime;
this.startTime = (startTime != null? startTime: authTime);
if (endTime == null)
throw new IllegalArgumentException("End time for ticket validity"
+ " cannot be null");
this.endTime = endTime;
if (clientAddresses != null)
this.clientAddresses = (InetAddress[]) clientAddresses.clone();
| public boolean | isCurrent()Determines if this ticket is still current.
return (System.currentTimeMillis() <= getEndTime().getTime());
| public boolean | isDestroyed()Determines if this ticket has been destroyed.
return destroyed;
| public final boolean | isForwardable()Determines if this ticket is forwardable.
return flags[FORWARDABLE_TICKET_FLAG];
| public final boolean | isForwarded()Determines if this ticket had been forwarded or was issued based on
authentication involving a forwarded ticket-granting ticket.
return flags[FORWARDED_TICKET_FLAG];
| public final boolean | isInitial()Determines if this ticket was issued using the Kerberos AS-Exchange
protocol, and not issued based on some ticket-granting ticket.
return flags[INITIAL_TICKET_FLAG];
| public final boolean | isPostdated()Determines is this ticket is post-dated.
return flags[POSTDATED_TICKET_FLAG];
| public final boolean | isProxiable()Determines if this ticket is proxiable.
return flags[PROXIABLE_TICKET_FLAG];
| public final boolean | isProxy()Determines is this ticket is a proxy-ticket.
return flags[PROXY_TICKET_FLAG];
| public final boolean | isRenewable()Determines is this ticket is renewable. If so, the {@link #refresh()
refresh} method can be called, assuming the validity period for
renewing is not already over.
return flags[RENEWABLE_TICKET_FLAG];
| public void | refresh()Extends the validity period of this ticket. The ticket will contain
a new session key if the refresh operation succeeds. The refresh
operation will fail if the ticket is not renewable or the latest
allowable renew time has passed. Any other error returned by the
KDC will also cause this method to fail.
Note: This method is not synchronized with the the accessor
methods of this object. Hence callers need to be aware of multiple
threads that might access this and try to renew it at the same
time.
if (destroyed)
throw new RefreshFailedException("A destroyed ticket "
+ "cannot be renewd.");
if (!isRenewable())
throw new RefreshFailedException("This ticket is not renewable");
if (System.currentTimeMillis() > getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
Throwable e = null;
sun.security.krb5.Credentials krb5Creds = null;
try {
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
client.toString(),
server.toString(),
sessionKey.getEncoded(),
sessionKey.getKeyType(),
flags,
authTime,
startTime,
endTime,
renewTill,
clientAddresses);
krb5Creds = krb5Creds.renew();
} catch (sun.security.krb5.KrbException krbException) {
e = krbException;
} catch (java.io.IOException ioException) {
e = ioException;
}
if (e != null) {
RefreshFailedException rfException
= new RefreshFailedException("Failed to renew Kerberos Ticket "
+ "for client " + client
+ " and server " + server
+ " - " + e.getMessage());
rfException.initCause(e);
throw rfException;
}
/*
* In case multiple threads try to refresh it at the same time.
*/
synchronized (this) {
try {
this.destroy();
} catch (DestroyFailedException dfException) {
// Squelch it since we don't care about the old ticket.
}
init(krb5Creds.getEncoded(),
new KerberosPrincipal(krb5Creds.getClient().getName()),
new KerberosPrincipal(krb5Creds.getServer().getName()),
krb5Creds.getSessionKey().getBytes(),
krb5Creds.getSessionKey().getEType(),
krb5Creds.getFlags(),
krb5Creds.getAuthTime(),
krb5Creds.getStartTime(),
krb5Creds.getEndTime(),
krb5Creds.getRenewTill(),
krb5Creds.getClientAddresses());
destroyed = false;
}
| public java.lang.String | toString()
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
StringBuffer caddrBuf = new StringBuffer();
if (clientAddresses != null) {
for (int i = 0; i < clientAddresses.length; i++) {
caddrBuf.append("clientAddresses[" + i + "] = " +
clientAddresses[i].toString());
}
}
return ("Ticket (hex) = " + "\n" +
(new HexDumpEncoder()).encode(asn1Encoding) + "\n" +
"Client Principal = " + client.toString() + "\n" +
"Server Principal = " + server.toString() + "\n" +
"Session Key = " + sessionKey.toString() + "\n" +
"Forwardable Ticket " + flags[FORWARDABLE_TICKET_FLAG] + "\n" +
"Forwarded Ticket " + flags[FORWARDED_TICKET_FLAG] + "\n" +
"Proxiable Ticket " + flags[PROXIABLE_TICKET_FLAG] + "\n" +
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
"Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
"Auth Time = " + authTime.toString() + "\n" +
"Start Time = " + startTime.toString() + "\n" +
"End Time = " + endTime.toString() + "\n" +
"Renew Till = " +
(renewTill == null ? "Null " : renewTill.toString()) + "\n" +
"Client Addresses " +
(clientAddresses == null ? " Null " : caddrBuf.toString() +
"\n"));
|
|