LoginContext
类描述了用于认证主体的基本方法,并提供了一种开发应用程序而不依赖底层认证技术的方式。一个Configuration
指定了要与特定应用程序一起使用的认证技术或LoginModule
。不同的LoginModules可以在不需要对应用程序本身进行任何修改的情况下插入到应用程序中。
除了支持可插拔认证,这个类还支持“堆叠”认证的概念。应用程序可以配置使用多个LoginModule。例如,可以在一个应用程序下配置Kerberos LoginModule和智能卡LoginModule。
典型的调用者使用一个名称和一个CallbackHandler
实例化一个LoginContext。LoginContext使用名称作为索引进入Configuration,以确定应该使用哪些LoginModules,以及哪些必须成功才能使整体认证成功。将CallbackHandler
传递给底层LoginModules,以便它们可以与用户进行通信和交互(例如通过图形用户界面提示输入用户名和密码)。
一旦调用者实例化了一个LoginContext,它调用login
方法来认证一个Subject
。login
方法调用配置的模块执行各自类型的认证(用户名/密码,智能卡PIN验证等)。请注意,如果认证失败,LoginModules将不会尝试认证重试或引入延迟。这些任务属于LoginContext调用者。
如果login
方法返回而不抛出异常,则整体认证成功。调用者可以通过调用getSubject
方法检索新认证的Subject。可以通过调用Subject的相应getPrincipals
、getPublicCredentials
和getPrivateCredentials
方法检索与Subject关联的Principal和Credentials。
要注销Subject,调用者调用logout
方法。与login
方法一样,这个logout
方法调用配置的模块的logout
方法。
一个LoginContext不应该用于认证多个Subject。应该使用单独的LoginContext来认证每个不同的Subject。
以下文档适用于所有LoginContext构造函数:
Subject
- 如果构造函数有一个Subject输入参数,则LoginContext使用调用者指定的Subject对象。
- 如果调用者指定了一个
null
Subject并且允许一个null
值,则LoginContext实例化一个新的Subject。 - 如果构造函数没有Subject输入参数,则LoginContext实例化一个新的Subject。
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时存储)必须具有足够的权限来执行模块可能执行的任何安全敏感任务。
- 如果构造函数有一个Configuration输入参数并且调用者指定了一个非空的Configuration,则LoginContext使用调用者指定的Configuration。
CallbackHandler
- 如果构造函数有一个CallbackHandler输入参数,则LoginContext使用调用者指定的CallbackHandler对象。
- 如果构造函数没有CallbackHandler输入参数,或者如果调用者指定了一个
null
CallbackHandler对象(并且允许一个null
值),则LoginContext查询auth.login.defaultCallbackHandler
安全属性以获取默认处理程序实现的完全限定类名。如果未设置安全属性,则底层模块将没有用于与用户通信的CallbackHandler。因此,调用者假定配置的模块有其他认证用户的方式。 - 当LoginContext使用已安装的Configuration(而不是调用者指定的Configuration,请参见上文)时,那么这个LoginContext必须将任何调用者指定的或默认CallbackHandler实现包装在一个新的CallbackHandler实现中,该实现的
handle
方法调用指定的CallbackHandler的handle
方法,并在调用者当前AccessControlContext
的java.security.AccessController.doPrivileged
调用中受到约束。
- 自版本:
- 1.4
- 参见:
-
Constructor Summary
ConstructorDescriptionLoginContext
(String name) 用名称实例化一个新的LoginContext
对象。LoginContext
(String name, CallbackHandler callbackHandler) 用名称和一个CallbackHandler
对象实例化一个新的LoginContext
对象。LoginContext
(String name, Subject subject) 用名称和一个Subject
对象实例化一个新的LoginContext
对象。LoginContext
(String name, Subject subject, CallbackHandler callbackHandler) 用名称、要认证的Subject
和一个CallbackHandler
对象实例化一个新的LoginContext
对象。LoginContext
(String name, Subject subject, CallbackHandler callbackHandler, Configuration config) 用名称、要认证的Subject
、一个CallbackHandler
对象和一个登录Configuration
实例化一个新的LoginContext
对象。 -
Method Summary
-
Constructor Details
-
LoginContext
用名称实例化一个新的LoginContext
对象。- 参数:
-
name
- 用作Configuration
索引的名称。 - 抛出:
-
LoginException
- 如果调用者指定的name
在Configuration
中不存在,并且没有"other
"的Configuration
条目,或者如果设置了auth.login.defaultCallbackHandler
安全属性,但无法加载实现类。 -
SecurityException
- 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name
的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")
-
LoginContext
用名称和一个Subject
对象实例化一个新的LoginContext
对象。- 参数:
-
name
- 用作Configuration
索引的名称。 -
subject
- 要认证的Subject
。 - 抛出:
-
LoginException
- 如果调用者指定的name
在Configuration
中不存在,并且没有"other"的Configuration
条目,如果调用者指定的subject
是null
,或者如果设置了auth.login.defaultCallbackHandler安全属性,但无法加载实现类。 -
SecurityException
- 如果设置了SecurityManager并且调用者没有AuthPermission("createLoginContext.name"),或者如果name
的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")
-
LoginContext
用名称和一个CallbackHandler
对象实例化一个新的LoginContext
对象。- 参数:
-
name
- 用作Configuration
索引的名称。 -
callbackHandler
- LoginModules用于与用户通信的CallbackHandler
对象。 - 抛出:
-
LoginException
- 如果调用者指定的name
在Configuration
中不存在,并且没有Configuration
条目为"other
",或者如果调用者指定的callbackHandler
是null
。 -
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
- 如果调用者指定的name
在Configuration
中不存在,并且没有"other"的Configuration
条目,或者如果调用者指定的subject
为null
,或者如果调用者指定的callbackHandler
为null
。 -
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
- 如果调用者指定的name
在Configuration
中不存在,并且没有"other"的Configuration
条目。 -
SecurityException
- 如果设置了SecurityManager,config为null
,并且调用者没有AuthPermission("createLoginContext.name"),或者name
的配置条目不存在并且调用者没有额外具有AuthPermission("createLoginContext.other")。 - 自JDK版本:
- 1.5
-
-
Method Details
-
login
执行身份验证。此方法为
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
阶段(login
或commit
阶段失败),则此方法调用为应用程序配置的所有LoginModules,而不考虑它们各自的Configuration
标志参数。基本上,这意味着在abort
阶段忽略了Requisite
和Sufficient
语义。这确保了适当的清理和状态恢复可以发生。- 抛出:
-
LoginException
- 如果身份验证失败。
-
logout
注销Subject
。此方法为此
LoginContext
配置的每个LoginModule
调用logout
方法。每个LoginModule
执行其各自的注销过程,其中可能包括从Subject
和状态清理中删除/销毁Principal
和Credential
信息。请注意,此方法调用为应用程序配置的所有LoginModules,而不考虑它们各自的
Configuration
标志参数。基本上,这意味着对于此方法,Requisite
和Sufficient
语义被忽略。这确保了适当的清理和状态恢复可以发生。- 抛出:
-
LoginException
- 如果注销失败。
-
getSubject
返回经过身份验证的Subject
。- 返回:
-
经过身份验证的
Subject
。如果调用者为此LoginContext的构造函数指定了一个Subject,则此方法返回调用者指定的Subject。如果未指定Subject并且身份验证成功,则此方法返回由此LoginContext实例化和用于身份验证的Subject。如果未指定Subject,并且身份验证失败或尚未尝试身份验证,则此方法返回null。
-