Tomcat 7 java.lang.NullPointerException 当使用 Active Directory 身份验证输入错误的凭据时

Tomcat 7 java.lang.NullPointerException when wrong credential entered using Active Directory authentification

我正在尝试使用 Active Directory 对我网站上的用户进行身份验证 应用。如果我使用正确的,这现在可以正常工作 凭据,但如果我没有输入正确的凭据,我会得到 在错误 [1] 之后,不允许进一步尝试。我没有 当我只使用 UserDatabaseRealm 时出现这个问题。

编辑: 按照@kotacc 的建议升级到 Tomcat 8.0.15 后,进入错误的凭据。 编辑结束

我的 server.xml 在 [2] 而我的 web.xml 在 [3] 我的配置详情在 [4].

知道哪里出了问题吗?谁能指出我向右 这个的文档?

问候

[2] 这是我 server.xml:

的相关部分
<Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.CombinedRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm. -->
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
        <Realm className="org.apache.catalina.realm.JNDIRealm"
        connectionURL="ldap://someServer.mycompany.com:389"
        connectionName="OneUser@mycompany.CORP"
        connectionPassword="aPassword"
        referrals="follow"
        userBase="ou=Users,OU=somServer,DC=mycompany,DC=CORP"
        userSearch="(sAMAccountName={0})"
        userSubtree="true"
      />
     </Realm>
     </Realm>

[3] 这是我 web.xml:

的相关部分
 <security-constraint>
        <web-resource-collection>
            <web-resource-name>Wildcard means whole app requires
authentication</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>

        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <security-constraint>
    <web-resource-collection>
        <web-resource-name>Public</web-resource-name>
        <description>Matches a few special pages.</description>
        <url-pattern>/index.html</url-pattern>
    </web-resource-collection>
        <!-- No auth-constraint means everybody has access! -->
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>

  <security-role>
   <description>this is the standard user</description>
   <role-name>*</role-name>
 </security-role>

[4] 这是在 Tomcat 7.0.57 运行 上 Windows 7 64 位

> java -version java version "1.7.0_71" Java(TM) SE Runtime Environment
> (build 1.7.0_71-b14) Java HotSpot(TM) 64-Bit Server VM (build
> 24.71-b01, mixed mode)

[1] 这里是错误:

java.lang.NullPointerException
org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1303)
org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1253)
org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:1194)
org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:1069)
org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:146)
org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:146)
org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:180)
org.apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.java:164)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:575)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2466)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2455)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)

[5] 这是 Tomcat 8.0.15:

的错误
java.lang.NullPointerException
    org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1286)
    org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1236)
    org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:1177)
    org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:1052)
    org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:157)
    org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:157)
    org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:180)
    org.apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.java:111)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:576)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

它似乎是 Tomcat 7.0.57 中的一个缺陷。如果您在第 1300 行看到 source code,则没有空值检查。我已将这段代码粘贴到此处并给出我的评论:

protected User getUser(DirContext context, String username,
                       String credentials, int curUserPattern)
    throws NamingException {
    ...
    if (userPatternFormatArray != null && curUserPattern >= 0) {
        user = getUserByPattern(context, username, credentials, attrIds, curUserPattern);
    } else {
        user = getUserBySearch(context, username, attrIds);
    }
    if (userPassword == null && credentials != null) { //Line 1300;No null check for 'user' object.
        return new User(user.getUserName(), user.getDN(), credentials,
                user.getRoles(), user.getUserRoleId());
    }
    return user;
}

似乎在 Tomcat 7.0.57 版本中添加了来自 1300 的行。我还可以看到它在 trunk 中得到解决,但尚未发布。我建议您使用以前的版本 (7.0.56) 或 Tomcat 8.

[编辑]:似乎所有版本的 Tomcat 都没有修复此缺陷 8. 截至目前,Tomcat 的最新版本即 7.0.57 和 8.0.15 有这个缺陷。