Module java.base

Class LoginContext

java.lang.Object
javax.security.auth.login.LoginContext

public class LoginContext extends Object

LoginContext类描述了用于认证主体的基本方法,并提供了一种开发应用程序而不依赖底层认证技术的方式。一个Configuration指定了要与特定应用程序一起使用的认证技术或LoginModule。不同的LoginModules可以在不需要对应用程序本身进行任何修改的情况下插入到应用程序中。

除了支持可插拔认证,这个类还支持“堆叠”认证的概念。应用程序可以配置使用多个LoginModule。例如,可以在一个应用程序下配置Kerberos LoginModule和智能卡LoginModule。

典型的调用者使用一个名称和一个CallbackHandler实例化一个LoginContext。LoginContext使用名称作为索引进入Configuration,以确定应该使用哪些LoginModules,以及哪些必须成功才能使整体认证成功。将CallbackHandler传递给底层LoginModules,以便它们可以与用户进行通信和交互(例如通过图形用户界面提示输入用户名和密码)。

一旦调用者实例化了一个LoginContext,它调用login方法来认证一个Subjectlogin方法调用配置的模块执行各自类型的认证(用户名/密码,智能卡PIN验证等)。请注意,如果认证失败,LoginModules将不会尝试认证重试或引入延迟。这些任务属于LoginContext调用者。

如果login方法返回而不抛出异常,则整体认证成功。调用者可以通过调用getSubject方法检索新认证的Subject。可以通过调用Subject的相应getPrincipalsgetPublicCredentialsgetPrivateCredentials方法检索与Subject关联的Principal和Credentials。

要注销Subject,调用者调用logout方法。与login方法一样,这个logout方法调用配置的模块的logout方法。

一个LoginContext不应该用于认证多个Subject。应该使用单独的LoginContext来认证每个不同的Subject。

以下文档适用于所有LoginContext构造函数:

  1. Subject
    • 如果构造函数有一个Subject输入参数,则LoginContext使用调用者指定的Subject对象。
    • 如果调用者指定了一个null Subject并且允许一个null值,则LoginContext实例化一个新的Subject。
    • 如果构造函数没有Subject输入参数,则LoginContext实例化一个新的Subject。
  2. Configuration
    • 如果构造函数有一个Configuration输入参数并且调用者指定了一个非空的Configuration,则LoginContext使用调用者指定的Configuration。

      如果构造函数没有Configuration输入参数,或者如果调用者指定了一个null Configuration对象,则构造函数使用以下调用获取已安装的Configuration:

            config = Configuration.getConfiguration();
       
      对于这两种情况,给定给构造函数的名称参数被传递给Configuration.getAppConfigurationEntry方法。如果Configuration对指定的名称没有条目,那么LoginContext将调用getAppConfigurationEntry使用名称"other"(默认条目名称)。如果没有"other"的条目,则会抛出LoginException
    • 当LoginContext使用已安装的Configuration时,调用者需要createLoginContext.name和可能需要createLoginContext.other AuthPermissions。此外,LoginContext将从AccessController.doPrivileged调用中调用配置的模块,以便执行执行安全敏感任务的模块(例如连接到远程主机和更新Subject)将需要相应的权限,但LoginContext的调用者不需要这些权限。
    • 当LoginContext使用调用者指定的Configuration时,调用者不需要任何createLoginContext AuthPermission。LoginContext保存了调用者的AccessControlContext,并在受该上下文约束的AccessController.doPrivileged调用中调用配置的模块。这意味着调用者上下文(在创建LoginContext时存储)必须具有足够的权限来执行模块可能执行的任何安全敏感任务。
  3. CallbackHandler
    • 如果构造函数有一个CallbackHandler输入参数,则LoginContext使用调用者指定的CallbackHandler对象。
    • 如果构造函数没有CallbackHandler输入参数,或者如果调用者指定了一个null CallbackHandler对象(并且允许一个null值),则LoginContext查询auth.login.defaultCallbackHandler安全属性以获取默认处理程序实现的完全限定类名。如果未设置安全属性,则底层模块将没有用于与用户通信的CallbackHandler。因此,调用者假定配置的模块有其他认证用户的方式。
    • 当LoginContext使用已安装的Configuration(而不是调用者指定的Configuration,请参见上文)时,那么这个LoginContext必须将任何调用者指定的或默认CallbackHandler实现包装在一个新的CallbackHandler实现中,该实现的handle方法调用指定的CallbackHandler的handle方法,并在调用者当前AccessControlContextjava.security.AccessController.doPrivileged调用中受到约束。
自版本:
1.4
参见:
  • Constructor Details

    • LoginContext

      public LoginContext(String name) throws LoginException
      用名称实例化一个新的LoginContext对象。
      参数:
      name - 用作Configuration索引的名称。
      抛出:
      LoginException - 如果调用者指定的nameConfiguration中不存在,并且没有"other"的Configuration条目,或者如果设置了auth.login.defaultCallbackHandler安全属性,但无法加载实现类。
      SecurityException - 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")
    • LoginContext

      public LoginContext(String name, Subject subject) throws LoginException
      用名称和一个Subject对象实例化一个新的LoginContext对象。
      参数:
      name - 用作Configuration索引的名称。
      subject - 要认证的Subject
      抛出:
      LoginException - 如果调用者指定的nameConfiguration中不存在,并且没有"other"的Configuration条目,如果调用者指定的subjectnull,或者如果设置了auth.login.defaultCallbackHandler安全属性,但无法加载实现类。
      SecurityException - 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")
    • LoginContext

      public LoginContext(String name, CallbackHandler callbackHandler) throws LoginException
      用名称和一个CallbackHandler对象实例化一个新的LoginContext对象。
      参数:
      name - 用作Configuration索引的名称。
      callbackHandler - LoginModules用于与用户通信的CallbackHandler对象。
      抛出:
      LoginException - 如果调用者指定的nameConfiguration中不存在,并且没有Configuration条目为"other",或者如果调用者指定的callbackHandlernull
      SecurityException - 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")
    • LoginContext

      public LoginContext(String name, Subject subject, CallbackHandler callbackHandler) throws LoginException
      实例化一个新的LoginContext对象,其中包括一个名称,一个要进行身份验证的Subject,以及一个CallbackHandler对象。
      参数:
      name - 用作索引进入Configuration的名称。
      subject - 要进行身份验证的Subject
      callbackHandler - 由LoginModules用于与用户通信的CallbackHandler对象。
      抛出:
      LoginException - 如果调用者指定的nameConfiguration中不存在,并且没有"other"的Configuration条目,或者如果调用者指定的subjectnull,或者如果调用者指定的callbackHandlernull
      SecurityException - 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")。
    • LoginContext

      public LoginContext(String name, Subject subject, CallbackHandler callbackHandler, Configuration config) throws LoginException
      实例化一个新的LoginContext对象,其中包括一个名称,一个要进行身份验证的Subject,一个CallbackHandler对象,以及一个登录Configuration
      参数:
      name - 用作索引进入调用者指定的Configuration的名称。
      subject - 要进行身份验证的Subject,或者为null
      callbackHandler - 由LoginModules用于与用户通信的CallbackHandler对象,或者为null
      config - 列出要调用以执行身份验证的登录模块的Configuration,或者为null
      抛出:
      LoginException - 如果调用者指定的nameConfiguration中不存在,并且没有"other"的Configuration条目。
      SecurityException - 如果设置了SecurityManager,confignull,并且调用者没有AuthPermission("createLoginContext.name"),或者name的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")。
      自JDK版本:
      1.5
  • Method Details

    • login

      public void login() throws LoginException
      执行身份验证。

      此方法为LoginContext构造函数指定的name配置的每个LoginModule调用login方法,由登录Configuration确定。然后,每个LoginModule执行其各自类型的身份验证(用户名/密码,智能卡PIN验证等)。

      此方法通过调用每个配置的LoginModule的commit方法完成2阶段身份验证过程,如果整体身份验证成功(相关的REQUIRED、REQUISITE、SUFFICIENT和OPTIONAL LoginModules成功),或者通过调用每个配置的LoginModule的abort方法完成2阶段身份验证过程,如果整体身份验证失败。如果身份验证成功,每个成功的LoginModule的commit方法将相关的Principal和Credentials与Subject关联。如果身份验证失败,每个LoginModule的abort方法将删除/销毁任何先前存储的状态。

      如果身份验证过程的commit阶段失败,则整体身份验证失败,此方法为每个配置的LoginModule调用abort方法。

      如果abort阶段由于任何原因失败,则此方法传播在login阶段或commit阶段抛出的原始异常。在任何情况下,整体身份验证失败。

      在多个LoginModules失败的情况下,此方法传播第一个失败的LoginModule引发的异常。

      请注意,如果此方法进入abort阶段(logincommit阶段失败),则此方法调用为应用程序配置的所有LoginModules,而不考虑它们各自的Configuration标志参数。基本上,这意味着在abort阶段忽略了RequisiteSufficient语义。这确保了适当的清理和状态恢复可以发生。

      抛出:
      LoginException - 如果身份验证失败。
    • logout

      public void logout() throws LoginException
      注销Subject

      此方法为此LoginContext配置的每个LoginModule调用logout方法。每个LoginModule执行其各自的注销过程,其中可能包括从Subject和状态清理中删除/销毁PrincipalCredential信息。

      请注意,此方法调用为应用程序配置的所有LoginModules,而不考虑它们各自的Configuration标志参数。基本上,这意味着对于此方法,RequisiteSufficient语义被忽略。这确保了适当的清理和状态恢复可以发生。

      抛出:
      LoginException - 如果注销失败。
    • getSubject

      public Subject getSubject()
      返回经过身份验证的Subject
      返回:
      经过身份验证的Subject。如果调用者为此LoginContext的构造函数指定了一个Subject,则此方法返回调用者指定的Subject。如果未指定Subject并且身份验证成功,则此方法返回由此LoginContext实例化和用于身份验证的Subject。如果未指定Subject,并且身份验证失败或尚未尝试身份验证,则此方法返回null。