- 所有已实现的接口:
LoginModule
LoginModule
执行基于 LDAP 的身份验证。根据存储在 LDAP 目录中的相应用户凭证验证用户名和密码。该模块需要提供的 CallbackHandler
来支持 NameCallback
和 PasswordCallback
。如果身份验证成功,则使用用户的可分辨名称创建一个新的LdapPrincipal
,并使用用户的用户名创建一个新的UserPrincipal
,并且两者都与当前的Subject
相关联。
该模块以三种模式之一运行:搜索优先, 认证优先或者仅认证.通过指定一组特定的选项来选择模式。
在搜索优先模式下,搜索 LDAP 目录以确定用户的专有名称,然后尝试进行身份验证。使用提供的用户名结合指定的搜索过滤器执行(匿名)搜索。如果成功,则尝试使用用户的专有名称和提供的密码进行身份验证。要启用此模式,请设置 userFilter
选项并省略 authIdentity
选项。当事先不知道用户的可分辨名称时,使用搜索优先模式。
在身份验证优先模式下,使用提供的用户名和密码尝试进行身份验证,然后搜索 LDAP 目录。如果身份验证成功,则使用提供的用户名结合指定的搜索过滤器执行搜索。要启用此模式,请设置 authIdentity
和 userFilter
选项。访问已配置为不允许匿名搜索的 LDAP 目录时,请使用身份验证优先模式。
在仅身份验证模式下,将尝试使用提供的用户名和密码进行身份验证。不搜索 LDAP 目录,因为用户的专有名称已知。要启用此模式,请将 authIdentity
选项设置为有效的可分辨名称并省略 userFilter
选项。当预先知道用户的可分辨名称时,使用仅身份验证模式。
以下选项是强制性的,必须在此模块的登录 Configuration
中指定:
-
userProvider=ldap_urls
-
此选项标识存储用户条目的 LDAP 目录。ldap_urls是以空格分隔的 LDAP URL (RFC 2255) 的列表,它标识要使用的 LDAP 服务以及用户条目在其目录树中的位置。当指定多个 LDAP URL 时,将依次尝试每个 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
,则调试消息显示在标准输出流上。
也可以在 Configuration
中指定任意的 “JNDI 属性”。它们被添加到环境中并传递给 LDAP 提供程序。请注意,以下四个 JNDI 属性由该模块直接设置,如果配置中也存在,则将被忽略:
java.naming.provider.url
java.naming.security.principal
java.naming.security.credentials
java.naming.security.protocol
三个样本 Configuration
如下所示。第一个激活搜索优先模式。它标识 LDAP 服务并指定用户条目由其 uid
和 objectClass
属性定位。它还指定应创建基于用户的 employeeNumber
属性的身份。第二个激活身份验证优先模式。它要求动态定位 LDAP 服务,直接使用提供的用户名执行身份验证但没有 SSL 的保护,并且用户的条目由三个命名属性之一及其 objectClass
属性定位。第三个激活仅身份验证模式。它标识备用 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
的应用程序必须被授予某些权限。如果应用程序使用 installed
Configuration
创建登录上下文,则必须授予应用程序AuthPermission
创建登录上下文。例如,以下安全策略允许用户当前目录中的应用程序实例化 any 登录上下文:grant codebase "file:${user.dir}/" { permission javax.security.auth.AuthPermission "createLoginContext.*"; };
或者,如果应用程序使用 caller-specifiedConfiguration
创建登录上下文,则必须向应用程序授予LoginModule
所需的权限。 This 模块需要以下两个权限:SocketPermission
连接到 LDAP 服务。AuthPermission
修改与Subject
关联的Principal
集合。
例如,以下安全策略授予用户当前目录中的应用程序该模块所需的所有权限:
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
-
构造方法总结
构造方法 -
方法总结
-
构造方法详细信息
-
LdapLoginModule
public LdapLoginModule()创建一个LdapLoginModule
。
-
-
方法详情
-
initialize
public void initialize(Subject subject, CallbackHandler callbackHandler, Map <String , ?> sharedState, Map <String , ?> options) 初始化这个LoginModule
。- 指定者:
initialize
在接口LoginModule
中- 参数:
subject
- 要验证的Subject
。callbackHandler
- aCallbackHandler
获取用户名和密码。sharedState
- 共享LoginModule
状态。options
- 在登录Configuration
中为此特定的LoginModule
指定的选项。
-
login
开始用户认证。获取用户的凭据并根据指定的 LDAP 目录验证它们。
- 指定者:
login
在接口LoginModule
中- 返回:
-
总是正确的,因为这个
LoginModule
不应该被忽略。 - 抛出:
FailedLoginException
- 如果身份验证失败。LoginException
- 如果此LoginModule
无法执行身份验证。
-
commit
完成用户认证。如果 LoginContext 的整体身份验证成功(相关的 REQUIRED、REQUISITE、SUFFICIENT 和 OPTIONAL LoginModules 成功),则调用此方法。
如果此 LoginModule 自己的身份验证尝试成功(通过检索
login
方法保存的私有状态进行检查),则此方法将一个LdapPrincipal
和一个或多个UserPrincipal
与位于LoginModule
中的Subject
相关联。如果此 LoginModule 自己的身份验证尝试失败,则此方法会删除最初保存的所有状态。- 指定者:
commit
在接口LoginModule
中- 返回:
- 如果此 LoginModule 自己的登录和提交尝试成功,则为 true,否则为 false。
- 抛出:
LoginException
- 如果提交失败
-
abort
中止用户身份验证。如果整体身份验证失败,则调用此方法。 (相关的 REQUIRED、REQUISITE、SUFFICIENT 和 OPTIONAL LoginModules 没有成功)。
如果此 LoginModule 自己的身份验证尝试成功(通过检索
login
和commit
方法保存的私有状态进行检查),则此方法会清除最初保存的任何状态。- 指定者:
abort
在接口LoginModule
中- 返回:
- 如果此 LoginModule 自己的登录和/或提交尝试失败,则为 false,否则为 true。
- 抛出:
LoginException
- 如果中止失败。
-
logout
注销用户。此方法删除由
commit
方法添加的主体。- 指定者:
logout
在接口LoginModule
中- 返回:
-
在所有情况下都为真,因为不应忽略此
LoginModule
。 - 抛出:
LoginException
- 如果注销失败。
-