[英]Tomcat: Multiple authentication schemes for a single web application?
我的Web应用程序使用内部Web API(作为主要客户端,从浏览器发出的简单AJAX请求),最终应该在外部为第三方公开。 由于该API已且必须受到web.xml
的安全性约束的保护,因此必须对用户或客户端进行身份验证。 当前,实现了一个自定义表单身份验证器,它执行一些其他检查和操作,然后将进一步的身份验证处理委托给派生自定义身份验证器的FormAuthenticator
类。 这样做确实非常不错,因为用户只是被迫登录并通过身份验证,而唯一的客户端是Web浏览器。
但是FORM身份验证不适用于其他类型的客户端:例如Android客户端,各种第三方客户端等。太过了表单身份验证,它们都必须模拟我在此问题中寻找的行为: 如何模拟JMeter在Tomcat中进行表单身份验证? 。 在对Tomcat源代码进行了一些研究之后,我想到了应该可以扩展AuthenticatorBase
类以实现自己的身份验证方式(例如FormAuthenticator
或BasicAuthenticator.java
这样做)。 我试图做的是:
public final class SimpleAuthenticator extends AuthenticatorBase {
private static final String USERNAME_PARAMETER = "username";
private static final String PASSWORD_PARAMETER = "password";
@Override
protected boolean authenticate(Request request, Response response, LoginConfig config) throws IOException {
final Principal principal = request.getUserPrincipal();
final String ssoId = (String) request.getNote(REQ_SSOID_NOTE);
if ( principal != null ) {
if ( ssoId != null ) {
associate(ssoId, request.getSessionInternal(true));
}
return true;
}
if ( ssoId != null && reauthenticateFromSSO(ssoId, request) ) {
return true;
}
final String contextPath = request.getContextPath();
final String requestURI = request.getDecodedRequestURI();
final boolean login = requestURI.equals(contextPath + "/authenticate");
if ( !login ) {
response.sendError(SC_FORBIDDEN);
return false;
}
final String username = request.getParameter(USERNAME_PARAMETER);
final String password = request.getParameter(PASSWORD_PARAMETER);
final Realm realm = context.getRealm();
final Principal authenticatedUserPrincipal = realm.authenticate(username, password);
if ( authenticatedUserPrincipal == null ) {
response.sendError(SC_UNAUTHORIZED);
return false;
}
register(request, response, authenticatedUserPrincipal, "SIMPLE", username, password);
return true;
}
}
简而言之,我想使用/%CONTEXT_PATH%/authenticate?username=%USERNAME%&password=%PASSWORD%
来通过我的自定义非格式SimpleAuthenticator
验证用户。 不太确定BasicAuthentication
是否适合这种情况,但是上面的示例出现了以下问题:
context.xml
指定多个Valve
。 如果将另一个验证者添加到context.xml
文件,则每个验证者都将处理每个安全资源。 (原则上,我理解为什么会发生这种情况,但是可以将它们分开以使用不同的资源吗?) /%CONTEXT_PATH%/authenticate
无法访问(HTTP 404)。 (尚不清楚/j_security_check
是通过某种方式模拟的。) FormAuthenticator
(就像今天一样),但是“轻量级”的客户端可以使用我尝试实现的简化身份验证与SimpleAuthenticator
。 (甚至不知道是否有可能-这就是核心) login-config
。 (嗯,我应该使用另一个Web应用程序来提供API吗?) Filter
实现自定义身份验证的内容,但是,如果可能的话,我想将身份验证器模块放在一个单独的位置(就像已经存在并通过Tomcat确认一样) :Web应用程序中的自定义表单身份验证器,而不是作为独立的JAR模块。可能吗? )。 但是,我可以从头开始回顾一下我使用的一般概念。 我怀疑我做错了一件事情并且已经完全了解了,但是我不相信无法在Tomcat中实现多种身份验证方案。
有什么方法可以提供多种身份验证方案,以从FormAuthetication
提取身份验证(对于轻量级客户端)? 非常感谢您的帮助。 提前致谢。
最重要的是:您不能为Tomcat中的同一Web应用程序配置多个身份验证方案。 您可以在web.xml
配置一种用于身份验证的身份验证方法:
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
Tomcat映射到用于Web应用程序身份验证的身份验证器。 例如,对于CLIENT-CERT
,它将使用org.apache.catalina.authenticator.SSLAuthenticator
映射位于文件org/apache/catalina/startup/Authenticators.properties
为此,您可以在问题中描述您可以使用常规的Tomcat Form Authenticator( <auth-method>FORM</auth-method>
)
以下代码将对用户进行身份验证:
String url = "j_security_check?j_username=" + username + "&j_password=" + password;
String redirectUrl = response.encodeRedirectURL(url);
response.sendRedirect(redirectUrl);
首次访问应用程序时,请通过上面的执行URL对用户进行身份验证。 另外,您可以将Form Authenticator用于“旧”代码:)请注意,以上代码使用GET
方法。 我建议在POST
方法中向j_security_check
提交相同的参数(可以在AJAX中完成)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.