Tomcat LockOutRealm错误/用户锁定后显示错误消息

时间:2018-08-24 09:29:55

标签: tomcat login tomcat8 jdbcrealm

我正在Tomcat中使用JDBCRealm + LockOutRealm(但可以切换到9)。一切正常,但是如果用户锁定自己,则只能在日志中看到它,而面对登录错误页面的用户则看不到。

想象一下,用户几次使用大写锁定输入密码,因此锁定了帐户,然后注意到大写锁定,将其删除了,但仍然无法登录。

是否可以显示出LockOutRealm而不是错误的密码是登录失败的原因?

我只在catalina.out中看到这一点:

Aug 24, 2018 10:59:15 AM org.apache.catalina.realm.LockOutRealm authenticate
WARNING: An attempt was made to authenticate the locked user "abcd"
Aug 24, 2018 10:59:15 AM org.apache.catalina.authenticator.AuthenticatorBase invoke
FINE:  Failed authenticate() test ??/test/j_security_check

我确实找到了this answer,这是恕我直言,是该地区唯一相关的答案。但这是从2011年开始的,现在可能会有更好,更轻松的方法。

(同样不那么重要),还有一种方法可以从应用程序帐户中解锁用户/重置LockOutRealm,例如通过使用管理员帐户访问一些受保护的servlet,可以做到这一点吗?有一个 unlock()方法,但它似乎并非旨在在应用程序内部使用,请参见here

1 个答案:

答案 0 :(得分:0)

刚遇到同样的问题。似乎什么都没有改变。为了添加另一种解决方法,我最终通过反射获得了 LockOutRealm,如 here 所述。 当然,这违反了应用不应该知道哪些领域正在使用的设计原则。

相关代码:

 ApplicationContextFacade acf = (ApplicationContextFacade) request.getSession().getServletContext();

 Field privateField = ApplicationContextFacade.class.getDeclaredField("context");  
 privateField.setAccessible(true);  
 ApplicationContext appContext = (ApplicationContext) privateField.get(acf);
  
 Field privateField2 = ApplicationContext.class.getDeclaredField("context");  
 privateField2.setAccessible(true);  
 StandardContext stdContext = (StandardContext) privateField2.get(appContext);
  
 LockOutRealm realm = (LockOutRealm) stdContext.getRealm();  

然后使用 realm.isLocked(username) 来决定显示哪个错误消息。 (LockOutRealm 可能不是根领域,这取决于 context.xml 中的配置)