问题描述
该项目是由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的状态为started
。 conf/context.xml
,conf/web.xml
,webapps/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
。