自定义SpnegoAuthenticator使用Tomcat 8,但使用Tomcat 9提供404

问题描述

该项目是由Jetty使用表单身份验证开发的。文件login.jsp

<form method="post" action="j_security_check">
    <input type="text" name="j_username"/>
    <input type="password" name="j_password"/>
    <input type="submit" value="Login"/>
</form>

在生产中,它已在Tomcat 8.0.53中发布,并使用自定义SpnegoAuthenticator。文件conf/context.xml

<Context>
    <Valve className="com.CustomeSpnegoAuthenticator" />
</Context>

文件tomcat/application/WEB-INF/web.xml包括以下内容:

<login-config>
    <auth-method>SPNEGO</auth-method>
    <realm-name>REALMNAME</realm-name>
    <form-login-config>
        <form-login-page>/login.jsp</form-login-page>
        <form-error-page>/loginError.jsp</form-error-page>
    </form-login-config>
</login-config>

在文件CustomeSpnegoAuthenticator.java中,将初始化FormAuthenticator并将其设置如下

public class CustomeSpnegoAuthenticator extends org.apache.catalina.authenticator.SpnegoAuthenticator {
    private FormAuthenticator formAuthenticator = new FormAuthenticator();
    @Override
    public void setContainer(Container container) {
        try {
            super.setContainer(container);
            formAuthenticator.setContainer(container);
            formAuthenticator.setLandingPage("/home");
            formAuthenticator.start();
            log.info("formAuthenticator state: " + formAuthenticator.getState())
        } catch (LifecycleException ex) {
            log.error("Failed to start authenticators,reason: " + ex.getMessage(),ex);
        }
    }
    @Override
    protected String getAuthMethod() {
        return Constants.SPNEGO_METHOD;
    }
    @Override
    public boolean authenticate(Request request,HttpServletResponse response) throws IOException {
        // process username and password
        // return result
    }
}

这在Tomcat 8中效果很好,身份验证发生在localhost/application/j_security_check处。但是在将其部署到Tomcat 9.0.20中之后,它开始将404赋予localhost/application/j_security_check,尽管在CustomeSpnegoAuthenticator.java形式下,Authenticator的状态为startedconf/context.xmlconf/web.xmlwebapps/application/WEB-INF/web.xml相同。只是Tomcat版本不同。

有人知道这是什么原因吗,或者我该如何进一步调试?

解决方法

因此,在阅读源代码之后,我发现Tomcat 9中的身份验证器的实现与Tomcat 8有所不同。它们用authenticate代替了doAuthenticate

因此解决方案在文件CustomeSpnegoAuthenticator.java中,将覆盖功能从authenticate更改为doAuthenticate。由于这一行:formAuthenticator.setLandingPage("/home");。在文件login.jsp中,操作应为home/j_security_check

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...