英文:
Custom SpnegoAuthenticator worked with Tomcat 8 but gives 404 with Tomcat 9
问题
项目使用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 {
// 处理用户名和密码
// 返回结果
}
}
这在Tomcat 8中运行良好,在localhost/application/j_security_check
进行身份验证。但是在部署到Tomcat 9.0.20后,访问localhost/application/j_security_check
会返回404错误,尽管在CustomeSpnegoAuthenticator.java
中,formAuthenticator的状态为started
。conf/context.xml
、conf/web.xml
、webapps/application/WEB-INF/web.xml
保持不变,唯一不同的是Tomcat版本。
是否有人知道可能的原因,或者如何进一步调试?
英文:
Project was developed with Jetty using Form Authentication. File 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>
In production, it was published in Tomcat 8.0.53 and using a custom SpnegoAuthenticator
. File conf/context.xml
<Context>
<Valve className="com.CustomeSpnegoAuthenticator" />
</Context>
File tomcat/application/WEB-INF/web.xml
includes these:
<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>
in file CustomeSpnegoAuthenticator.java
, a FormAuthenticator is initialised and set up as below
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
}
}
This worked well in Tomcat 8, authentication happens at localhost/application/j_security_check
. But after deploying it in Tomcat 9.0.20, it starts giving 404 to localhost/application/j_security_check
, although in CustomeSpnegoAuthenticator.java
formAuthenticator's state is started
. conf/context.xml
, conf/web.xml
,webapps/application/WEB-INF/web.xml
are the same. Only Tomcat version is different.
Does anyone has any idea what might be the reason, or how can I debug further?
答案1
得分: 1
所以在阅读源代码后,我发现Tomcat 9中的认证器实现与Tomcat 8有些不同。他们用doAuthenticate
替代了authenticate
。
所以解决方案在文件CustomeSpnegoAuthenticator.java
中,将覆盖函数从authenticate
更改为doAuthenticate
。并且由于这一行:formAuthenticator.setLandingPage("/home");
。在文件login.jsp
中,操作应该是home/j_security_check
。
英文:
So after reading the source code, I found the implementation of authenticators in Tomcat 9 is a bit different from Tomcat 8. They replaced authenticate
with doAuthenticate
.
So the solution is in file CustomeSpnegoAuthenticator.java
, change override function from authenticate
to doAuthenticate
. And because of this line: formAuthenticator.setLandingPage("/home");
. In file login.jsp
, action should be home/j_security_check
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论