- 所有已实现的接口:
-
LoginModule
LoginModule
执行基于LDAP的身份验证。用户名和密码将与存储在LDAP目录中的相应用户凭据进行验证。此模块需要提供的CallbackHandler
支持一个NameCallback
和一个PasswordCallback
。如果身份验证成功,则使用用户的专有名称创建一个新的LdapPrincipal
,并使用用户的用户名创建一个新的UserPrincipal
,并将它们与当前的Subject
关联。
此模块以三种模式之一运行:search-first、authentication-first或authentication-only。通过指定特定的选项来选择模式。
在search-first模式下,将搜索LDAP目录以确定用户的专有名称,然后尝试进行身份验证。使用提供的用户名与指定的搜索过滤器执行(匿名)搜索。如果成功,则尝试使用用户的专有名称和提供的密码进行身份验证。要启用此模式,请设置userFilter
选项并省略authIdentity
选项。当用户的专有名称事先不知道时,请使用search-first模式。
在authentication-first模式下,使用提供的用户名和密码尝试进行身份验证,然后搜索LDAP目录。如果身份验证成功,则使用提供的用户名与指定的搜索过滤器执行搜索。要启用此模式,请设置authIdentity
和userFilter
选项。当访问已配置为禁止匿名搜索的LDAP目录时,请使用authentication-first模式。
在authentication-only模式下,使用提供的用户名和密码尝试进行身份验证。不搜索LDAP目录,因为用户的专有名称已知。要启用此模式,请将authIdentity
选项设置为有效的专有名称,并省略userFilter
选项。当用户的专有名称事先已知时,请使用authentication-only模式。
以下选项是强制性的,并且必须在此模块的登录Configuration
中指定:
-
userProvider=ldap_urls
-
此选项标识存储用户条目的LDAP目录。ldap_urls是一个以空格分隔的LDAP URL列表(RFC 2255),用于标识要使用的LDAP服务器以及其目录树中用户条目的位置。如果指定了多个LDAP URL,则会依次尝试每个,直到建立第一个成功的连接。URL的专有名称组件中的空格必须使用百分比字符('
%
')后跟两个十六进制数字的标准机制进行转义(请参阅URI
)。还必须从URL中省略查询组件。通过DNS(RFC 2782)自动发现LDAP服务器受支持(一旦配置DNS以支持此类服务)。通过省略LDAP URL中的主机名和端口号组件来启用此功能。
此模块还识别以下可选的Configuration
选项:
-
userFilter=ldap_filter
-
此选项指定用于在LDAP目录中定位用户条目的搜索过滤器。用于确定用户的专有名称。
ldap_filter
是一个LDAP过滤器字符串(RFC 2254)。如果它包含特殊标记"{USERNAME}
",则该标记将在使用过滤器搜索目录之前替换为提供的用户名值。 -
authIdentity=auth_id
-
此选项指定在向LDAP目录验证用户时要使用的身份。
auth_id
可以是LDAP专有名称字符串(RFC 2253)或其他字符串名称。它必须包含特殊标记"{USERNAME}
",该标记将在用于身份验证之前用提供的用户名值替换。请注意,如果此选项不包含专有名称,则还必须指定userFilter
选项。 -
authzIdentity=authz_id
-
此选项为用户指定授权身份。
authz_id
是任何字符串名称。如果它包含带大括号的单个特殊标记,则该标记将被视为属性名称,并将从用户的LDAP条目中的该属性的单个值替换为该值。如果找不到属性,则将忽略该选项。当提供此选项并且用户已成功验证时,将使用授权身份创建一个额外的UserPrincipal
,并将其与当前的Subject
关联。 -
useSSL
-
如果为
false
,则此模块在尝试身份验证之前不会与LDAP服务器建立SSL连接。使用SSL用于保护用户密码的隐私,因为它在LDAP上以明文传输。默认情况下,此模块使用SSL。 -
useFirstPass
-
如果为
true
,则此模块从模块的共享状态中检索用户名和密码,使用"javax.security.auth.login.name"和"javax.security.auth.login.password"作为相应的键。检索的值用于身份验证。如果身份验证失败,则不会尝试重试,并将失败报告给调用应用程序。 -
tryFirstPass
-
如果为
true
,则此模块从模块的共享状态中检索用户名和密码,使用"javax.security.auth.login.name"和"javax.security.auth.login.password"作为相应的键。检索的值用于身份验证。如果身份验证失败,则模块使用CallbackHandler
检索新的用户名和密码,并尝试进行另一次身份验证。如果身份验证失败,则将失败报告给调用应用程序。 -
storePass
-
如果为
true
,则此模块将从CallbackHandler
获取的用户名和密码存储在模块的共享状态中,使用"javax.security.auth.login.name"和"javax.security.auth.login.password"作为相应的键。如果共享状态中已存在用户名和密码的现有值,或者身份验证失败,则不执行此操作。 -
clearPass
-
如果为
true
,则此模块在身份验证的两个阶段(登录和提交)完成后清除存储在模块的共享状态中的用户名和密码。 -
debug
-
如果为
true
,则在标准输出流上显示调试消息。
还可以在"JNDI属性"中指定任意的Configuration
。它们将添加到环境并传递给LDAP提供程序。请注意,此模块直接设置以下四个JNDI属性,并且如果这些属性也存在于配置中,则会被忽略:
java.naming.provider.url
java.naming.security.principal
java.naming.security.credentials
java.naming.security.protocol
下面显示了三个示例Configuration
。第一个激活search-first模式。它标识LDAP服务器,并指定用户条目通过其uid
和objectClass
属性进行定位。还指定应创建基于用户employeeNumber
属性的身份。第二个激活authentication-first模式。它请求动态定位LDAP服务器,使用提供的用户名直接执行身份验证,但不使用SSL保护,并且用户条目通过三个命名属性之一和它们的objectClass
属性进行定位。第三个激活authentication-only模式。它标识备用LDAP服务器,指定用于身份验证的专有名称和用于授权的固定身份。不执行目录搜索。
ExampleApplication { com.sun.security.auth.module.LdapLoginModule REQUIRED userProvider="ldap://ldap-svr/ou=people,dc=example,dc=com" userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" authzIdentity="{EMPLOYEENUMBER}" debug=true; }; ExampleApplication { com.sun.security.auth.module.LdapLoginModule REQUIRED userProvider="ldap:///cn=users,dc=example,dc=com" authIdentity="{USERNAME}" userFilter="(&(|(samAccountName={USERNAME})(userPrincipalName={USERNAME})(cn={USERNAME}))(objectClass=user))" useSSL=false debug=true; }; ExampleApplication { com.sun.security.auth.module.LdapLoginModule REQUIRED userProvider="ldap://ldap-svr1 ldap://ldap-svr2" authIdentity="cn={USERNAME},ou=people,dc=example,dc=com" authzIdentity="staff" debug=true; };
- 注意:
-
当一个活动的
SecurityManager
时,创建一个LoginContext
并使用LoginModule
的应用程序必须被授予某些权限。如果应用程序使用一个已安装的
Configuration
创建登录上下文,则该应用程序必须被授予创建登录上下文的AuthPermission
。例如,以下安全策略允许用户当前目录中的应用程序实例化任何登录上下文:grant codebase "file:${user.dir}/" { permission javax.security.auth.AuthPermission "createLoginContext.*"; };
或者,如果应用程序使用调用者指定的Configuration
创建登录上下文,则该应用程序必须被授予LoginModule
所需的权限。 此模块需要以下两个权限:SocketPermission
连接到LDAP服务器。AuthPermission
修改与Principal
相关联的Subject
的一组权限。
例如,以下安全策略授予用户当前目录中的应用程序此模块所需的所有权限:
grant codebase "file:${user.dir}/" { permission java.net.SocketPermission "*:389", "connect"; permission java.net.SocketPermission "*:636", "connect"; permission javax.security.auth.AuthPermission "modifyPrincipals"; };
- 自1.6版本起:
- 1.6
-
Constructor Summary
-
Method Summary
-
Constructor Details
-
LdapLoginModule
public LdapLoginModule()创建一个LdapLoginModule
。
-
-
Method Details
-
initialize
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) 初始化这个LoginModule
。- 指定者:
-
initialize
在接口LoginModule
- 参数:
-
subject
- 要进行身份验证的Subject
。 -
callbackHandler
- 一个CallbackHandler
用于获取用户名和密码。 -
sharedState
- 共享的LoginModule
状态。 -
options
- 在此特定LoginModule
的登录Configuration
中指定的选项。
-
login
开始用户认证。获取用户的凭据并根据指定的LDAP目录进行验证。
- 指定者:
-
login
在接口LoginModule
- 返回:
-
始终为true,因为这个
LoginModule
不应被忽略。 - 抛出:
-
FailedLoginException
- 如果认证失败。 -
LoginException
- 如果这个LoginModule
无法执行认证。
-
commit
完成用户认证。如果LoginContext的整体认证成功(相关的REQUIRED、REQUISITE、SUFFICIENT和OPTIONAL LoginModules成功),则调用此方法。
如果这个LoginModule自己的认证尝试成功(通过检索
login
方法保存的私有状态来检查),则此方法将在LoginModule
中的Subject
上关联一个LdapPrincipal
和一个或多个UserPrincipal
。如果这个LoginModule自己的认证尝试失败,则此方法将删除最初保存的任何状态。- 指定者:
-
commit
在接口LoginModule
- 返回:
- 如果这个LoginModule自己的登录和提交尝试成功,则为true,否则为false。
- 抛出:
-
LoginException
- 如果提交失败
-
abort
中止用户认证。如果整体认证失败,则调用此方法。(相关的REQUIRED、REQUISITE、SUFFICIENT和OPTIONAL LoginModules未成功)。
如果这个LoginModule自己的认证尝试成功(通过检索
login
和commit
方法保存的私有状态来检查),则此方法将清除最初保存的任何状态。- 指定者:
-
abort
在接口LoginModule
- 返回:
- 如果这个LoginModule自己的登录和/或提交尝试失败,则为false,否则为true。
- 抛出:
-
LoginException
- 如果中止失败。
-
logout
注销用户。此方法将删除由
commit
方法添加的Principal。- 指定者:
-
logout
在接口LoginModule
- 返回:
-
在所有情况下都为true,因为这个
LoginModule
不应被忽略。 - 抛出:
-
LoginException
- 如果注销失败。
-