org.ietf.jgss

接口
异常
java.lang.Object
  继承者 org.ietf.jgss.GSSManager

public abstract class GSSManager
     
extends Object

此类作为其他重要 GSS-API 类的工厂,并且还提供有关受支持的机制的信息。它可以创建实现以下三个 GSS-API 接口的类的实例:GSSNameGSSCredentialGSSContext。它还具有一些查询可用的机制列表和每个机制支持的名称类型的方法。

默认的 GSSManager 子类的实例可以通过静态方法 getInstance 获取,但应用程序可以随意实例化 GSSManager 的其他字类。除其他机制外,默认的 GSSManager 实例还支持 Kerberos v5 GSS-API 机制。此机制由 Oid "1.2.840.113554.1.2.2" 标识,并在 RFC 1964 中定义。

扩展 GSSManager 抽象类的子类可以实现为基于模块化的提供者层,该层可利用一些人们熟知的服务提供者规范。GSSManager API 允许应用程序设置此类实现的首选的提供者。这些方法还允许实现抛出经过定义明确的异常,以防基于提供者的配置不受支持。那些希望移植的应用程序必须意识到这一点,并能够通过捕获异常进行彻底恢复。

预计将有三种使用提供者的最常见方法:

  1. 应用程序并不关心使用什么提供者(默认情况下)。
  2. 应用程序希望优先使用特定的提供者,或者针对特定的机制,或者始终如此,与机制无关。
  3. 应用程序希望尽可能使用本地配置的提供者,但是,如果失去了对一个或多个机制的支持,则应用程序就会回调它自己的提供者。

GSSManager 类有两种支持这些使用模式的方法:addProviderAtFrontaddProviderAtEnd。这两种方法可以创建 <provider, oid> 对的有序列表,其中的每个对都指示指定 oid 的一个首选提供者。

需要注意的一点是,在由 GSSManager 创建的不同的 GSS-API 对象之间存在着一定的交互,其中,用于特定机制的提供者可能需要对所有的对象保持一致。例如,如果 GSSCredential 包含来自机制 m 的提供者 p 中的元素,则通常要将它传递给一个将使用机制 m 的提供者 p 的 GSSContext。实现最大可移植性的简单经验就是,不要混合从不同的 GSSManager 中创建的对象,如果应用程序想在已经创建了对象的 GSSManager 上调用 addProviderAtFront 方法,在可能的情况下,则必须创建不同的 GSSManager 实例。

下面是一些示例代码,它显示了如何使用 GSSManager:

     GSSManager manager = GSSManager.getInstance();

     Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
     Oid krb5PrincipalNameType = new Oid("1.2.840.113554.1.2.2.1");

     // Identify who the client wishes to be
     GSSName userName = manager.createName("duke", GSSName.NT_USER_NAME);

     // Identify the name of the server. This uses a Kerberos specific
     // name format.
     GSSName serverName = manager.createName("nfs/foo.sun.com", 
                                             krb5PrincipalNameType);

     // Acquire credentials for the user
     GSSCredential userCreds = manager.createCredential(userName,
                                             GSSCredential.DEFAULT_LIFETIME,
                                             krb5Mechanism,
                                             GSSCredential.INITIATE_ONLY);

     // Instantiate and initialize a security context that will be
     // established with the server
     GSSContext context = manager.createContext(serverName,
                                                krb5Mechanism,
                                                userCreds,
                                                GSSContext.DEFAULT_LIFETIME);
 

服务器端可能会使用此源的以下变量:

     // Acquire credentials for the server
     GSSCredential serverCreds = manager.createCredential(serverName, 
                                             GSSCredential.DEFAULT_LIFETIME, 
                                             krb5Mechanism, 
                                             GSSCredential.ACCEPT_ONLY); 
 
     // Instantiate and initialize a security context that will
     // wait for an establishment request token from the client
     GSSContext context = manager.createContext(serverCreds);
 

从以下版本开始:
1.4
另请参见:
GSSName, GSSCredential, GSSContext

构造方法摘要
GSSManager()
           
 
方法摘要
abstract  void addProviderAtEnd(Provider p, Oid mech)
          此方法用于向 GSSManager 指示,如果没有其他的提供者支持指定的机制,则应用程序将使用特定的提供者。
abstract  void addProviderAtFront(Provider p, Oid mech)
          此方法用来向 GSSManager 表示,当支持是指定的机制所需要的支持时,应用程序希望优先于其他所有提供者使用特定的提供者。
abstract  GSSContext createContext(byte[] interProcessToken)
          创建以前导出的上下文的 Factory 方法。
abstract  GSSContext createContext(GSSCredential myCred)
          为接受端一方创建上下文的 Factory 方法。
abstract  GSSContext createContext(GSSName peer, Oid mech, GSSCredential myCred, int lifetime)
          在初始端一方创建上下文的 Factory 方法。
abstract  GSSCredential createCredential(GSSName name, int lifetime, Oid[] mechs, int usage)
          通过一套机制获取凭据的 Factory 方法。
abstract  GSSCredential createCredential(GSSName name, int lifetime, Oid mech, int usage)
          获取单个机制凭据的 Factory 方法。
abstract  GSSCredential createCredential(int usage)
          获取默认凭据的 Factory 方法。
abstract  GSSName createName(byte[] name, Oid nameType)
          将包含名称的字节数组从指定的名称空间转换到 GSSName 对象的 Factory 方法。
abstract  GSSName createName(byte[] name, Oid nameType, Oid mech)
          将包含名称的字符串数组从指定的名称空间转换到 GSSName 对象并同时针对机制对其进行规范化的 Factory 方法。
abstract  GSSName createName(String nameStr, Oid nameType)
          将字符串名称从指定的名称空间转换到 GSSName 对象的 Factory 方法。
abstract  GSSName createName(String nameStr, Oid nameType, Oid mech)
          将字符串名称从指定的名称空间转换到 GSSName 对象并同时针对机制对其进行规范化的 Factory 方法。
static GSSManager getInstance()
          返回默认的 GSSManager 实现。
abstract  Oid[] getMechs()
          返回一个可通过此 GSSManager 提供给 GSS-API 调用者的机制列表。
abstract  Oid[] getMechsForName(Oid nameType)
          返回支持指定的名称类型的机制的列表。
abstract  Oid[] getNamesForMech(Oid mech)
          然后返回由指定的机制所支持的名称类型。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

构造方法详细信息

GSSManager

public GSSManager()
方法详细信息

getInstance

public static GSSManager getInstance()
返回默认的 GSSManager 实现。

返回:
GSSManager 实现

getMechs

public abstract Oid[] getMechs()
返回一个可通过此 GSSManager 提供给 GSS-API 调用者的机制列表。从 getInstance() 方法中获取的默认 GSSManager 将 Oid "1.2.840.113554.1.2.2" 放在了其列表中。此 Oid 可确定已在 RFC 1964 中定义的 Kerberos v5 GSS-API 机制。

返回:
一些与可用的机制对应的 Oid 对象。当没有机制可用时(例如正在动态配置机制,并且当前未设置任何机制),将返回 null

getNamesForMech

public abstract Oid[] getNamesForMech(Oid mech)
                               throws GSSException
然后返回由指定的机制所支持的名称类型。

默认的 GSSManager 实例包括对 Kerberos v5 机制的支持。当指定此机制 ("1.2.840.113554.1.2.2") 时,返回的列表至少将包括以下名称类型:GSSName.NT_HOSTBASED_SERVICEGSSName.NT_EXPORT_NAME 和特定于 Kerberos v5 的 Oid "1.2.840.113554.1.2.2.1"。Oid "1.2.840.113554.1.2.2.1" 的名称空间在 RFC 1964 中进行了定义。

参数:
mech - 将查询的机制 Oid
返回:
一些与该机制支持的名称类型对应的 Oid 对象。
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#UNAVAILABLE GSSException.UNAVAILABLE}、 GSSException.FAILURE
GSSException
另请参见:
getMechsForName(Oid)

getMechsForName

public abstract Oid[] getMechsForName(Oid nameType)
返回支持指定的名称类型的机制的列表。

当指定的名称类型是 GSSName.NT_HOSTBASED_SERVICEGSSName.NT_EXPORT_NAME 或 "1.2.840.113554.1.2.2.1" 这三者之一时,在此列表中将始终返回 Kerberos v5 机制 ("1.2.840.113554.1.2.2")。

参数:
nameType - 要查找的名称类型的 Oid
返回:
一些与支持指定的名称类型的机制对应的 Oid 对象。当没有机制支持指定的名称类型时,将返回 null
另请参见:
getNamesForMech(Oid)

createName

public abstract GSSName createName(String nameStr,
                                   Oid nameType)
                            throws GSSException
将字符串名称从指定的名称空间转换到 GSSName 对象的 Factory 方法。通常,创建的 GSSName 对象包括该名称的多种表示形式,每个受支持的机制都有一种表示形式;此种情况的两个例外示例是:名称空间类型参数指示为 NT_EXPORT_NAME 或 GSS-API 实现不是多机制。建议不要将此方法用于 NT_EXPORT_NAME 类型,因为将以前导出的名称(由任意字节构成)表示为 String 可能会导致字符编码方案问题。在此情形下,建议将字节直接传入 createName 这一方法的重载形式。

参数:
nameStr - 表示要创建的名称的可打印形式的字符串。
nameType - 指定所提供的可打印名称的名称空间的 Oid。 null 可以用来指定,特定于机制的默认可打印语法应该根据每个检查 nameStr 的机制进行假定。建议不要将名称类型 NT_EXPORT_NAME 用于此方法。
返回:
一个表示所指定主体的 GSSName
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}、 GSSException.BAD_NAMEGSSException.BAD_MECHGSSException.FAILURE
GSSException
另请参见:
GSSName, GSSName.NT_EXPORT_NAME

createName

public abstract GSSName createName(byte[] name,
                                   Oid nameType)
                            throws GSSException
将包含名称的字节数组从指定的名称空间转换到 GSSName 对象的 Factory 方法。通常,创建的 GSSName 对象包括该名称的多种表示形式,每个受支持的机制都有一种表示形式;此种情况的两个例外示例是:名称空间类型参数指示为 NT_EXPORT_NAME 或 GSS-API 实现不是多机制。传入的字节将由每种基础机制根据它所选择的编码方案针对指定的命名类型进行解释。

参数:
name - 包含要创建的名称的字节数组
nameType - 指定在字节数组中提供的名称的名称空间的 Oid。 null可用来指定,特定于机制的默认可打印语法应该根据每个检查字节数组的机制进行假定。
返回:
一个表示所指定主体的 GSSName
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}、 GSSException.BAD_NAMEGSSException.BAD_MECHGSSException.FAILURE
GSSException
另请参见:
GSSName, GSSName.NT_EXPORT_NAME

createName

public abstract GSSName createName(String nameStr,
                                   Oid nameType,
                                   Oid mech)
                            throws GSSException
将字符串名称从指定的名称空间转换到 GSSName 对象并同时针对机制对其进行规范化的 Factory 方法。换句话说,此方法是一种实用程序,它执行以下两个步骤的等效步骤:首先是 createName,然后是 GSSName.canonicalize

参数:
nameStr - 表示要创建的名称的可打印形式的字符串。
nameType - 指定所提供的可打印名称的名称空间的 Oid。 null 可以用来指定,特定于机制的默认可打印语法应该根据每个检查 nameStr 的机制进行假定。建议不要将名称类型 NT_EXPORT_NAME 用于此方法。
mech - 指定应该为其规范化名称的机制的 Oid
返回:
一个表示指定的主体的 GSSName
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}、 GSSException.BAD_NAMEGSSException.BAD_MECHGSSException.FAILURE
GSSException
另请参见:
GSSName.canonicalize(Oid), GSSName.NT_EXPORT_NAME

createName

public abstract GSSName createName(byte[] name,
                                   Oid nameType,
                                   Oid mech)
                            throws GSSException
将包含名称的字符串数组从指定的名称空间转换到 GSSName 对象并同时针对机制对其进行规范化的 Factory 方法。换句话说,此方法是一种实用程序,它执行以下两个步骤的等效步骤:首先是 createName,然后是 GSSName.canonicalize

参数:
name - 包含要创建的名称的字节数组
nameType - 指定在字节数组中提供的名称的名称空间的 Oid。 null可用来指定,特定于机制的默认可打印语法应该根据每个检查字节数组的机制进行假定。
mech - 指定应该为其规范化名称的机制的 Oid
返回:
一个表示指定的主体的 GSSName
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}、 GSSException.BAD_NAMEGSSException.BAD_MECHGSSException.FAILURE
GSSException
另请参见:
GSSName.canonicalize(Oid), GSSName.NT_EXPORT_NAME

createCredential

public abstract GSSCredential createCredential(int usage)
                                        throws GSSException
获取默认凭据的 Factory 方法。这会导致 GSS-API 将特定于系统的默认实现用于机制、名称和生存期的 set。

GSS-API 机制提供商必须对调用者实施本地访问控制策略施,以防止未经授权的调用者获取他们无权获取的凭据。不同机制提供商需要的权限种类将以机制为单位记录在文档中。失败的权限检查可能会导致从此方法中抛出 SecurityException

参数:
usage - 此凭据对象的预期用途。此参数的值必须是下列值之一: GSSCredential.INITIATE_AND_ACCEPTGSSCredential.ACCEPT_ONLYGSSCredential.INITIATE_ONLY
返回:
所请求类型的 GSSCredential。
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_MECH GSSException.BAD_MECH}、 GSSException.BAD_NAMETYPEGSSException.BAD_NAMEGSSException.CREDENTIALS_EXPIREDGSSException.NO_CREDGSSException.FAILURE
GSSException
另请参见:
GSSCredential

createCredential

public abstract GSSCredential createCredential(GSSName name,
                                               int lifetime,
                                               Oid mech,
                                               int usage)
                                        throws GSSException
获取单个机制凭据的 Factory 方法。

GSS-API 机制提供商必须对调用者实施本地访问控制策略施,以防止未经授权的调用者获取他们无权获取的凭据。不同机制提供商需要的权限种类将以机制为单位记录在文档中。失败的权限检查可能会导致从此方法中抛出 SecurityException

生存期的非默认值并不总能得到基础机制的认可,因此,应用程序必须随时准备根据返回的凭据调用 getRemainingLifetime

参数:
name - 将为其获取此凭据的主体的名称。使用 null 来指定默认的主体。
lifetime - 凭据应该保持有效的秒数。使用 GSSCredential.INDEFINITE_LIFETIME 请求证书具有最大允许生存期。使用 GSSCredential.DEFAULT_LIFETIME 请求默认的凭据生存期。
mech - 所需机制的 Oid。使用 (Oid) null 来请求默认的机制。
usage - 此凭据对象的预期用途。此参数的值必须是下列值之一: GSSCredential.INITIATE_AND_ACCEPTGSSCredential.ACCEPT_ONLYGSSCredential.INITIATE_ONLY
返回:
所请求类型的 GSSCredential。
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_MECH GSSException.BAD_MECH}、 GSSException.BAD_NAMETYPEGSSException.BAD_NAMEGSSException.CREDENTIALS_EXPIREDGSSException.NO_CREDGSSException.FAILURE
GSSException
另请参见:
GSSCredential

createCredential

public abstract GSSCredential createCredential(GSSName name,
                                               int lifetime,
                                               Oid[] mechs,
                                               int usage)
                                        throws GSSException
通过一套机制获取凭据的 Factory 方法。此方法尝试为在称为 mechs 的数组中指定的每个机制获取凭据。若要确定成功为其获取凭据的机制列表,调用者应该使用 GSSCredential.getMechs 方法。

GSS-API 机制提供商必须对调用者实施本地访问控制策略施,以防止未经授权的调用者获取他们无权获取的凭据。不同机制提供商需要的权限种类将以机制为单位记录在文档中。失败的权限检查可能会导致从此方法中抛出 SecurityException

生存期的非默认值并不总能得到基础机制的认可,因此,应用程序必须随时准备根据返回的凭据调用 getRemainingLifetime

参数:
name - 将为其获取此凭据的主体的名称。使用 null 来指定默认的主体。
lifetime - 凭据应该保持有效的秒数。使用 GSSCredential.INDEFINITE_LIFETIME 请求证书具有最大允许生存期。使用 GSSCredential.DEFAULT_LIFETIME 请求默认的凭据生存期。
mechs - Oid 组成的数组,指示获取凭据的机制。使用 (Oid[]) null 请求机制特定于系统的默认 set。
usage - 此凭据对象的预期用途。此参数的值必须是下列值之一: GSSCredential.INITIATE_AND_ACCEPTGSSCredential.ACCEPT_ONLYGSSCredential.INITIATE_ONLY
返回:
所请求类型的 GSSCredential。
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#BAD_MECH GSSException.BAD_MECH}、 GSSException.BAD_NAMETYPEGSSException.BAD_NAMEGSSException.CREDENTIALS_EXPIREDGSSException.NO_CREDGSSException.FAILURE
GSSException
另请参见:
GSSCredential

createContext

public abstract GSSContext createContext(GSSName peer,
                                         Oid mech,
                                         GSSCredential myCred,
                                         int lifetime)
                                  throws GSSException
在初始端一方创建上下文的 Factory 方法。 有些机制提供商可能会要求调用者授予初始化安全上下文的权限。失败的权限检查可能会导致从此方法中抛出 SecurityException

生存期的非默认值并不总能得到基础机制的认可,因此,应用程序必须随时准备根据返回的上下文调用 getLifetime

参数:
peer - 目标同位体的名称。
mech - 所需机制的 Oid。使用 null 来请求默认的机制。
myCred - 初始端的凭据。将 null 用作默认的初始端主体。
lifetime - 为上下文请求的以秒为单位的生存期。使用 GSSContext.INDEFINITE_LIFETIME 请求上下文具有最大允许的生存期。使用 GSSContext.DEFAULT_LIFETIME 请求上下文的默认生存期。
返回:
未创建的 GSSContext
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN}、 GSSException.BAD_MICGSSException.CONTEXT_EXPIREDGSSException.FAILURE
GSSException
另请参见:
GSSContext

createContext

public abstract GSSContext createContext(GSSCredential myCred)
                                  throws GSSException
为接受端一方创建上下文的 Factory 方法。上下文的属性将通过提供给 accept 方法的输入标记来确定。 有些机制提供商可能会要求调用者授予接受安全上下文的权限。失败的权限检查可能会导致从此方法中抛出 SecurityException

参数:
myCred - 接受端的凭据。将 null 用作默认的接受端主体。
返回:
未创建的 GSSContext
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN}、 GSSException.BAD_MICGSSException.CONTEXT_EXPIREDGSSException.FAILURE
GSSException
另请参见:
GSSContext

createContext

public abstract GSSContext createContext(byte[] interProcessToken)
                                  throws GSSException
创建以前导出的上下文的 Factory 方法。上下文属性将通过输入标记来确定,并且不能通过 set 方法进行修改。

不要求实现支持安全上下文的进程间的传输。在导出文本前,调用 GSSContext.isTransferable 将表示上下文是否可传输。在不支持它的实现中调用此方法会导致 GSSException,并带有错误代码 GSSException.UNAVAILABLE。 有些机制提供商可能会要求调用者授予初始化或接受安全上下文的权限。失败的权限检查可能会导致从此方法中抛出 SecurityException

参数:
interProcessToken - 以前从导出方法中发出的标记。
返回:
以前创建的 GSSContext
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#NO_CONTEXT GSSException.NO_CONTEXT}、 GSSException.DEFECTIVE_TOKENGSSException.UNAVAILABLEGSSException.UNAUTHORIZEDGSSException.FAILURE
GSSException
另请参见:
GSSContext

addProviderAtFront

public abstract void addProviderAtFront(Provider p,
                                        Oid mech)
                                 throws GSSException
此方法用来向 GSSManager 表示,当支持是指定的机制所需要的支持时,应用程序希望优先于其他所有提供者使用特定的提供者。当将 null (而不是 Oid)一值用于机制时,GSSManager 必须优先于其他提供者而使用指示的提供者,而不管机制是什么。仅当指示的提供者不支持所需的机制时,才应将 GSSManager 移动到另外的提供者上。

重复调用此方法可以保存较旧的设置,但这会降低它们的优先级,从而在顶端形成一个提供者和 Oid 对有序列表。

调用带有 null Oid 的 addProviderAtFront 将移除在 GSSManager 实例中为此提供者设置的所有原来的优先级。调用带有非 null Oid 的 addProviderAtFront 将移除使用此机制和此提供者一起设置的任何原来的优先级。

如果 GSSManager 实现不支持带有可插入提供者体系结构的 SPI,则必须抛出 GSSException,并带有状态码 GSSException.UNAVAILABLE,以表示操作不可用。

假设应用程序希望提供者 A 在任何机制需要时都始终第一个接受检查,则它将调用:

         GSSManager mgr = GSSManager.getInstance();
         // mgr may at this point have its own pre-configured list
         // of provider preferences. The following will prepend to
         // any such list:

         mgr.addProviderAtFront(A, null);
 
现在,如果它还希望在对原来的 set A 进行检查之前始终能从提供者 B 中获取机制 Oid m1,则它将调用:

         mgr.addProviderAtFront(B, m1);
 
这时,如果需要 m1,GSSManager 将首先检查 B。万一 B 未提供对 m1 的支持,GSSManager 将继续检查 A。如果需要机制 m2(其中 m2 不同于 m1),则 GSSManager 将跳过 B 而直接检查 A。

假设后来对同一 GSSManager 实例又进行了以下调用:

         mgr.addProviderAtFront(B, null)
 
那么将包含原来具有 (B, m1) 对的设置,该设置应该移除。实际上,优先级列表现在变成了 {(B, null), (A, null), ...//后面是预配置的列表。

不过,请注意下面的调用:

         mgr.addProviderAtFront(A, m3)
 
并不包括原来的设置 (A, null),并且列表实际上将变为 {(A, m3), (B, null), (A, null), ...}

参数:
p - 当 mech 需要支持时应该使用的提供者实例。
mech - 将为之设置提供者的机制
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#UNAVAILABLE GSSException.UNAVAILABLE}、 GSSException.FAILURE
GSSException

addProviderAtEnd

public abstract void addProviderAtEnd(Provider p,
                                      Oid mech)
                               throws GSSException
此方法用于向 GSSManager 指示,如果没有其他的提供者支持指定的机制,则应用程序将使用特定的提供者。当将 null(而不是 Oid)一值用于机制时,GSSManager 必须将指示的提供者用于任何机制。

重复调用此方法可以保存较旧的设置,但这会使它们的优先级高于新的设置,从而在底端形成一个提供者和 Oid 对有序列表。因此,在利用此提供者设置之前将首先利用较旧的提供者设置。

如果存在与现有设置的优先级冲突的原有优先级,则 GSSManager 必须忽略此请求。

如果 GSSManager 实现不支持带有可插入提供者体系结构的 SPI,则必须抛出 GSSException,并带有状态码 GSSException.UNAVAILABLE,以表示操作不可用。

假设应用程序希望,在需要设置 Oid m1 时,始终第一个检查系统默认的提供者,并且仅在它们不支持 m1 时才检查提供者 A。则它将调用:

         GSSManager mgr = GSSManager.getInstance();
         mgr.addProviderAtEnd(A, m1);
 
现在,如果它还希望在检查完所有配置的提供者之后,针对所有的机制检查提供者 B,则它将调用:

         mgr.addProviderAtEnd(B, null);
 
实际上,优先级列表现在变成了 {..., (A, m1), (B, null)}。

假设后来对同一 GSSManager 实例又进行了以下调用:

         mgr.addProviderAtEnd(B, m2)
 
那么将包含原来具有 (B, null) 对的设置,因此应该忽略此请求。如果向已经存在的 (A, m1) 或 (B, null) 对 发出请求,也会出现同样的情况。

不过,请注意下面的调用:

         mgr.addProviderAtEnd(A, null)
 
并不包括原来的设置 (A, m1),并且该列表实际上将变为 {..., (A, m1), (B, null), (A, null)}

参数:
p - 当 mech 需要支持时应该使用的提供者实例。
mech - 将为之设置提供者的机制
抛出:
GSSException,包含以下主要错误代码:{@link - GSSException#UNAVAILABLE GSSException.UNAVAILABLE}、 GSSException.FAILURE
GSSException