Class LdapLoginModule

  • All Implemented Interfaces:
    LoginModule


    public class LdapLoginModule
    extends Object
    implements LoginModule
    LoginModule执行基于LDAP的身份验证。 根据存储在LDAP目录中的相应用户凭据验证用户名和密码。 本模块需要提供的CallbackHandler支持NameCallbackPasswordCallback 如果认证成功,则新LdapPrincipal使用用户的专有名称创建一个新UserPrincipal使用用户的用户名创建并且两者都与当前相关Subject

    该模块以以下三种模式之一运行: 首先搜索,首先 验证仅认证 通过指定一组特定的选项来选择一种模式。

    在搜索优先模式下,搜索LDAP目录以确定用户的可分辨名称,然后尝试进行身份验证。 使用提供的用户名与指定的搜索过滤器一起执行(匿名)搜索。 如果成功,则尝试使用用户的可分辨名称和提供的密码进行身份验证。 要启用此模式,请设置userFilter选项,并省略authIdentity选项。 当用户的可分辨名称未提前知道时,请使用搜索优先模式。

    在认证第一模式下,尝试使用提供的用户名和密码进行认证,然后搜索LDAP目录。 如果认证成功,则使用提供的用户名与指定的搜索过滤器进行搜索。 要启用此模式,请设置authIdentityuserFilter选项。 访问已配置为禁止匿名搜索的LDAP目录时,请使用验证优先模式。

    在仅认证模式下,尝试使用提供的用户名和密码进行身份验证。 由于用户的可分辨名称已知,因此不会搜索LDAP目录。 要启用此模式,请将authIdentity选项设置为有效的可分辨名称,并省略userFilter选项。 当用户的专有名称提前知道时,使用仅认证模式。

    以下选项是必需的,必须在此模块的登录中指定Configuration

    userProvider=ldap_urls
    此选项标识存储用户条目的LDAP目录。 ldap_urls是标识要使用的LDAP服务器的空格分隔的LDAP URL( RFC 2255 )的列表,以及用户条目所在目录树中的位置。 当指定了几个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 properties"也可以在Configuration指定。 它们被添加到环境中并传递给LDAP提供者。 请注意,以下四个JNDI属性由此模块直接设置,如果配置中也存在,则将被忽略:

    • java.naming.provider.url
    • java.naming.security.principal
    • java.naming.security.credentials
    • java.naming.security.protocol

    三个样品Configurations如下所示。 第一个激活搜索优先模式。 它标识LDAP服务器,并指定用户的条目由其uidobjectClass属性定位。 它还指定应创建基于用户的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的应用程序必须被授予某些权限。

    如果应用程序使用安装的 Configuration创建登录上下文,那么应用程序必须被授予AuthPermission以创建登录上下文。 例如,以下安全策略允许用户当前目录中的应用程序实例化任何登录上下文:

      grant codebase "file:${user.dir}/" {
             permission javax.security.auth.AuthPermission "createLoginContext.*";
         }; 
    或者,如果应用程序使用调用者指定的 Configuration创建登录上下文,那么应用程序必须被授予LoginModule所需的权限。 模块需要以下两个权限:

    例如,以下安全策略在用户当前目录中授予应用程序该模块所需的所有权限:

      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​()
    • 方法详细信息

      • initialize

        public void initialize​(Subject subject,
                               CallbackHandler callbackHandler,
                               Map<String,?> sharedState,
                               Map<String,?> options)
        初始化 LoginModule
        Specified by:
        initialize在接口 LoginModule
        参数
        subject - 要验证的 Subject
        callbackHandler - 一个 CallbackHandler获取用户名和密码。
        sharedState - 共享 LoginModule状态。
        options - 在特定 LoginModule的登录 Configuration指定的选项。
      • login

        public boolean login​()
                      throws LoginException
        开始用户认证。

        获取用户的凭据并根据指定的LDAP目录进行验证。

        Specified by:
        login在接口 LoginModule
        结果
        真的永远,因为这个 LoginModule不应该被忽视。
        异常
        FailedLoginException - 如果身份验证失败。
        LoginException - 如果这个 LoginModule无法执行认证。
      • commit

        public boolean commit​()
                       throws LoginException
        完成用户认证。

        如果LoginContext的整体身份验证成功(相关的请求,REQUISITE,SUPPICIENT和可选LoginModules成功),则调用此方法。

        如果此LoginModule自己的身份验证尝试成功(通过检索通过login方法保存的私有状态进行检查),则此方法将LdapPrincipal和一个或多个UserPrincipalSubject中的LoginModule 如果此LoginModule自身的身份验证尝试失败,则此方法将删除原始保存的任何状态。

        Specified by:
        commit在接口 LoginModule
        结果
        如果此LoginModule自己的登录和提交尝试成功,则为true,否则为false。
        异常
        LoginException - 如果提交失败
      • abort

        public boolean abort​()
                      throws LoginException
        中止用户身份验证。

        如果整体认证失败,则调用此方法。 (相关要求,必要,有效和可选的LoginModules没有成功)。

        如果此LoginModule自己的身份验证尝试成功(通过检索由logincommit方法保存的私有状态进行检查),则此方法将清除最初保存的任何状态。

        Specified by:
        abort在接口 LoginModule
        结果
        如果此LoginModule自己的登录和/或提交尝试失败,则为false,否则为true。
        异常
        LoginException - 如果中止失败。
      • logout

        public boolean logout​()
                       throws LoginException
        注销用户。

        此方法将删除由commit方法添加的commit

        Specified by:
        logout在接口 LoginModule
        结果
        在所有情况下都是真实的,因为这个 LoginModule不应该被忽略。
        异常
        LoginException - 如果注销失败。