このファイルを使用して、伝搬トークン・インプリメンテーションの例を 示します。 以下のサンプル・コードは、 抽象クラスの拡張は行いませんが、com.ibm.wsspi.security.token.PropagationToken インターフェースを 直接実装します。 この インターフェースは直接インプリメントすることが可能ですが、重複するコードが書き込まれる可能性があります。 ただし、各種のトークン・インプリメンテーションによって処理方法が大きく異なる 場合は、インターフェースを直接インプリメントするとよいでしょう。
カスタム伝搬トークンのインプリメント方法について詳しくは、 カスタム伝搬トークンのインプリメント を参照してください。
package com.ibm.websphere.security.token; import com.ibm.websphere.security.WSSecurityException; import com.ibm.websphere.security.auth.WSLoginFailedException; import com.ibm.wsspi.security.token.*; import com.ibm.websphere.security.WebSphereRuntimePermission; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.DataOutputStream; import java.io.DataInputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.io.InputStream; import java.util.ArrayList; public class CustomPropagationTokenImpl implements com.ibm.wsspi.security.token.PropagationToken { private java.util.Hashtable hashtable = new java.util.Hashtable(); private byte[] tokenBytes = null; // 2 hours in millis, by default private static long expire_period_in_millis = 2*60*60*1000; private long counter = 0; /** * The constructor that is used to create initial PropagationToken instance */ public CustomAbstractTokenImpl () { // set the token version addAttribute("version", "1"); // set the token expiration addAttribute("expiration", new Long(System.currentTimeMillis() + expire_period_in_millis).toString()); } /** * The constructor that is used to deserialize the token bytes received * during a propagation login. */ public CustomAbstractTokenImpl (byte[] token_bytes) { try { hashtable = (java.util.Hashtable) com.ibm.wsspi.security.token. WSOpaqueTokenHelper.deserialize(token_bytes); } catch (Exception e) { e.printStackTrace(); } } /** * Validates the token including expiration, signature, and so on. * @return boolean */ public boolean isValid () { long expiration = getExpiration(); // if you set the expiration to 0, it does not expire if (expiration != 0) { // return if this token is still valid long current_time = System.currentTimeMillis(); boolean valid = ((current_time < expiration) ? true : false); System.out.println("isValid: returning " + valid); return valid; } else { System.out.println("isValid: returning true by default"); return true; } } /** * Gets the expiration as a long type. * @return long */ public long getExpiration() { // get the expiration value from the hashtable String[] expiration = getAttributes("expiration"); if (expiration != null && expiration[0] != null) { // expiration is the first element (should only be one) System.out.println("getExpiration: returning " + expiration[0]); return new Long(expiration[0]).longValue(); } System.out.println("getExpiration: returning 0"); return 0; } /** * Returns if this token should be forwarded/propagated downstream. * @return boolean */ public boolean isForwardable() { // You can choose whether your token gets propagated. In some cases // you might want the token to be local only. return true; } /** * Gets the principal that this token belongs to. If this token is an * authorization token, this principal string must match the authentication * token principal string or the message is rejected. * @return String */ public String getPrincipal() { // It is not necessary for the PropagationToken to return a principal, // because it is not user-centric. return ""; } /** * Returns the unique identifier of the token based upon information that * the provider considers makes it a unique token. This identifier is used * for caching purposes and might be used in combination with other token * unique IDs that are part of the same Subject. * * This method should return null if you want the accessID of the user to * represent its uniqueness. This is the typical scenario. * * @return String */ public String getUniqueID() { // If you want to propagate the changes to this token, change the // value that this unique ID returns whenever the token is changed. // Otherwise, CSIv2 uses an existing session when everything else is // the same. This getUniqueID is checked by CSIv2 to determine the // session lookup. return counter; } /** * Gets the bytes to be sent across the wire. The information in the byte[] * needs to be enough to recreate the Token object at the target server. * @return byte[] */ public byte[] getBytes () { if (hashtable != null) { try { // Do this if the object is set to read-only during login commit // because this guarantees that no new data is set. if (isReadOnly() && tokenBytes == null) tokenBytes = com.ibm.wsspi.security.token.WSOpaqueTokenHelper. serialize(hashtable); // You can deserialize this in the downstream login module using // WSOpaqueTokenHelper.deserialize() return tokenBytes; } catch (Exception e) { e.printStackTrace(); return null; } } System.out.println("getBytes: returning null"); return null; } /** * Gets the name of the token, which is used to identify the byte[] in the * protocol message. * @return String */ public String getName() { return this.getClass().getName(); } /** * Gets the version of the token as a short type. This code also is used * to identify the byte[] in the protocol message. * @return short */ public short getVersion() { String[] version = getAttributes("version"); if (version != null && version[0] != null) return new Short(version[0]).shortValue(); System.out.println("getVersion: returning default of 1"); return 1; } /** * When called, the token becomes irreversibly read-only. The implementation * needs to ensure that any setter methods check that this read-only flag has * been set. */ public void setReadOnly() { addAttribute("readonly", "true"); } /** * Called internally to see if the token is readonly */ private boolean isReadOnly() { String[] readonly = getAttributes("readonly"); if (readonly != null && readonly[0] != null) return new Boolean(readonly[0]).booleanValue(); System.out.println("isReadOnly: returning default of false"); return false; } /** * Gets the attribute value based on the named value. * @param String key * @return String[] */ public String[] getAttributes(String key) { ArrayList array = (ArrayList) hashtable.get(key); if (array != null && array.size() > 0) { return (String[]) array.toArray(new String[0]); } return null; } /** * Sets the attribute name and value pair. Returns the previous values set * for the key, or returns null if the value is not previously set. * @param String key * @param String value * @returns String[]; */ public String[] addAttribute(String key, String value) { // Gets the current value for the key ArrayList array = (ArrayList) hashtable.get(key); if (!isReadOnly()) { // Increments the counter to change the uniqueID counter++; // Copies the ArrayList to a String[] as it currently exists String[] old_array = null; if (array != null && array.size() > 0) old_array = (String[]) array.toArray(new String[0]); // Allocates a new ArrayList if one was not found if (array == null) array = new ArrayList(); // Adds the String to the current array list array.add(value); // Adds the current ArrayList to the Hashtable hashtable.put(key, array); // Returns the old array return old_array; } return (String[]) array.toArray(new String[0]); } /** * Gets the list of all of the attribute names present in the token. * @return java.util.Enumeration */ public java.util.Enumeration getAttributeNames() { return hashtable.keys(); } /** * Returns a deep clone of this token. This is typically used by the session * logic of the CSIv2 server to create a copy of the token as it exists in the * session. * @return Object */ public Object clone() { com.ibm.websphere.security.token.CustomPropagationTokenImpl deep_clone = new com.ibm.websphere.security.token.CustomPropagationTokenImpl(); java.util.Enumeration keys = getAttributeNames(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String[] list = (String[]) getAttributes(key); for (int i=0; i<list.length; i++) deep_clone.addAttribute(key, list[i]); } return deep_clone; } }