简体   繁体   English

Java EE身份验证错误处理

[英]Java EE Authentication Error Handling

We are currently trying to implement a web application which is using the Java EE authentication mechanism with a FORM-based login, inside the Websphere 6.1 web container. 我们目前正在尝试在Websphere 6.1 Web容器内实现一个Web应用程序,该Web应用程序使用Java EE身份验证机制和基于FORM的登录名。 If the authentication is successful, we have everything working; 如果验证成功,则说明一切正常。 the LDAP membership groups are being retrieved, the group to role mapping is being performed, and the roles are being returned to and correctly interpreted by the web application. 将检索LDAP成员资格组,执行组到角色的映射,并将角色返回给Web应用程序并由Web应用程序正确解释。

If the authentication is not successful, the form-login-error page is being returned. 如果认证不成功,则返回表单登录错误页面。 However, this is a static page that simply says something like "there was an error". 但是,这是一个静态页面,仅显示诸如“存在错误”之类的信息。 How do we trap the specific error that prevented the successful login (username/password incorrect, LDAP repository unavailable, account locked, password expired, etc.)? 我们如何捕获阻止成功登录的特定错误(用户名/密码错误,LDAP存储库不可用,帐户锁定,密码过期等)? It seems like there should be some easy way to do this, as you would want to treat some "security" exceptions differently than others. 似乎应该有一些简单的方法来执行此操作,因为您希望将某些“安全”异常与其他异常区别对待。

I use Struts so it will do forwarding for you. 我使用Struts,所以它将为您做转发。 If you don't have a framework (why not?) you'll will have to do it manually. 如果您没有框架(为什么没有?),则必须手动进行。

The Java EE spec covers the j_security_check servlet. Java EE规范涵盖了j_security_check servlet。

The login page POSTs j_username and j_password to the j_security_check servlet. 登录页面将j_username和j_password张贴到j_security_check servlet。 Your app will be configured to error to an unauthorized page (see web.xml) but will (initially) call a servlet. 您的应用将配置为错误进入未经授权的页面(请参阅web.xml),但会(最初)调用servlet。 401 or 403 will go to a forbidden page (again web.xml) 401或403将转到禁止页面(再次是web.xml)

Inside that servlet (which extends the HttpServlet) - you will check for all that good stuff. 在该servlet(扩展HttpServlet)内部-您将检查所有这些好东西。

public final void doGet(javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
    throws javax.servlet.ServletException, java.io.IOException
{
    // initialize the app
    AppInit initializer = new AppInit();

    // get the logger
    log = new Log4jWrapper(this.getClass());

    // initialize the application session
    HttpSession sess = request.getSession(true);
    sess.setAttribute(CommonConstants.SESSION_CURR_USER_ID, request.getRemoteUser());

    // initialize the JSP to forward to based on the user role
    String fwdJSP = "SetupMainPage.jsp";
    if (request.isUserInRole(CommonConstants.ROLE_MANAGER)) {
        log.debug("User is a Manager");
    }
    //else other role checks - (these are users in groups in the LDAP)
    // initialize the application session and set a variable to indicate that
    // we are coming from a first time login (not a timeout login)
    sess.setAttribute(CommonConstants.SESSION_COMING_FROM_INITIAL_LOGIN,"TRUE");
    disp = getServletContext().getRequestDispatcher("SetupMainPage.jsp");
    disp.forward(request, response);
}
//else failure

Unknown user 未知用户

[11/22/08 8:54:47:993 EST] 7f6ac69c FormLoginServ E SECJ0118E: Authentication error during authentication for user s [11/22/08 8:54:47:993 EST] 7f6ac69c FormLoginServ E SECJ0118E:用户s身份验证期间的身份验证错误

right user - wrong password, but the request.getRemoteUser() will have a value 正确的用户-错误的密码,但是request.getRemoteUser()将具有一个值

[11/22/08 8:56:45:082 EST] 7f51469c FormLoginServ E SECJ0118E: Authentication error during authentication for user jbsymolo [11/22/08 8:56:45:082 EST] 7f51469c FormLoginServ E SECJ0118E:对用户jbsymolo进行身份验证期间出现身份验证错误

Unfortunately - i don't have any examples of someone locked out but I going to assume that the main security directory (LDAP) you will have an entry for the user for that. 不幸的是-我没有任何人被锁定的示例,但我将假设主安全目录(LDAP)会为用户提供一个条目。

This is from someone else (so I can't take credit) 这是从别人那里来的(所以我不能相信)

I think this page describes how to do what you want to do. 我认为此页面描述了如何做您想做的事。

Specifically how to retrieve the authentication exception from an arbitrary underlying authentication source (looks like Websphere calls them user registries). 特别是如何从任意基础身份验证源检索身份验证异常(看起来像Websphere称它们为用户注册表)。

Throwable t = com.ibm.websphere.security.auth.WSSubject.getRootLoginException(); 可抛出t = com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
if (t != null) 如果(t!= null)
t = determineCause(t); t =确定原因(t);

Where determineCause() is defined on the same page. 在同一页面上定义了defineCause()的位置。 This way, even if your server is configured to authenticate against a John Deer tractor, you will have access to the "OutOfGasLoginException" if there is one. 这样,即使您的服务器配置为针对John Deer拖拉机进行身份验证,也可以访问“ OutOfGasLoginException”(如果存在)。 The above code can go into the Servlet, Servlet Filter, or JSP that is redirect to by the container (as described above by jsymolon). 上面的代码可以进入容器重定向到的Servlet,Servlet过滤器或JSP(如jsymolon所述)。 It simply examines the exceptions and then places a corresponding friendly error message on the resulting page. 它仅检查异常,然后在结果页面上放置相应的友好错误消息。

This is ancient knowledge - I believe to have done such a thing with tomcat. 这是古老的知识-我相信与tomcat一起做过这样的事情。 There was, as far as I can remember, no standard way, as the implementation was completely decoupled from the request and frontend web stuff, so that it was difficult to establish any means of communication between the authenticating component and the frontend (eg error page). 据我所知,这是没有标准的方法,因为实现是完全与请求和前端Web东西分离的,因此很难在身份验证组件和前端之间建立任何通信方式(例如错误页面) )。

We ended up with a tomcat specific way, relying heavily on the current implementation. 我们最终采用了tomcat特定的方式,很大程度上依赖于当前的实现。 I'm no longer with that company, so I can't tell about the current state of the code or the solution we chose back then. 我不再在那家公司工作,所以我无法告知代码的当前状态或我们当时选择的解决方案。 I believe you'll also have to have some Websphere specific solution - be it the use of thread local variables, keying messages with the username that attempted to log in, somehow getting hold of the session identifier or similar. 我相信您还必须具有一些特定于Websphere的解决方案-使用线程局部变量,使用尝试登录的用户名键入消息,以某种方式获取会话标识符或类似内容。

Check this article Securing J2EE Applications with a Servlet Filter . 检查本文,了解如何使用Servlet筛选器保护J2EE应用程序 I believe it covers your requirement to be able to pass the reason for the authentication error. 我相信它满足了您能够通过身份验证错误原因的要求。

The JavaEE specification does not provide a standard mean to get an authentication feedback like error codes. JavaEE规范没有提供获取错误信息之类的身份验证反馈的标准方法。

According to the following IBM Redpaper about z/OS security integration in gray note on page 57: IBM specific extension is available so that the error page JSP can report a specific message (like password expired) based on an error status code. 根据以下有关z / OS安全集成的IBM Redpaper在第57页上的灰色注释:提供了IBM特定的扩展名,以便错误页面JSP可以基于错误状态代码报告特定的消息(例如密码已过期)。

According to the WebSphere InfoCenter the FormLoginWeb sample from the TechSamp package in your WebSphere installation ( samples/src/TechSamp/FormLoginWeb ) is supposed to demonstrate such IBM specific extension but... The only thing interesting is the LoginFilter that intercepts calls on /j_security_check and is able to do pre-login validation and post-login action as explained in details in that paper . 根据WebSphere InfoCenter ,WebSphere安装中TechSamp包中的FormLoginWeb示例( samples/src/TechSamp/FormLoginWeb )应演示此类特定于IBM的扩展,但是...唯一有趣的是LoginFilter可以拦截/j_security_check调用并能够执行登录前验证和登录后操作,如该文件详细说明的那样。

With such a mechanism it is possible to get login exception from JAAS Subject and set an login error code in HttpSession so that the error page can generate a specific message. 通过这种机制,可以从JAAS主题获取登录异常并在HttpSession中设置登录错误代码,以便错误页面可以生成特定消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM