【问题标题】:Java EE 5 programmatic authenticationJava EE 5 编程身份验证
【发布时间】:2011-05-11 14:16:42
【问题描述】:

如何通过 JSF 操作(或 servlet doGet/doPost 方法)对用户进行身份验证? 我的意思是:

Authenticator auth = ...;
if (!auth.authenticate("user","password"))
{
    FacesContext.getInstance().addMessage("Incorrect username or password", null);
}

限制:

  • 此方法必须与容器管理的安全性兼容。 (即 `HttpServletRequest.getRemoteUser()` 必须返回经过身份验证的用户)
  • 此方法必须适用于任何地方(即在每个应用程序服务器上)。

不使用j_security_check 或其他J2EE 身份验证类型(BASIC、DIGEST 等...)

有可能吗?
或者如何以这种方式创建验证码?
验证登录名和密码不为空?
在单页上,当然没有 JavaScript...

类似的问题......但没有回答这个问题:

JSF authentication and authorization
Performing user authentication in Java EE / JSF using j_security_check

编辑 1
我的意思是 serlvet API 至少 2.3。 是的,我在 Servlet API 3.0 中读到了 login,但它仅受新版本的应用服务器支持。

我认为这里可以提供一些解决方案,为每个应用程序服务器实现此身份验证。 有时通过一些技巧,有时通过为此目的设计的特殊类。 像这样:

private Class<?> tryClass(String name)
{
    try
    {
        return Class.forName(name);
    }
    catch (ClassNotFoundException e)
    {
        return null;
    }
}

public boolean authenticate(String username, String password) throws AuthenticationException
{
    try
    {

        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        Object request = context.getRequest();
        Object response = context.getResponse();

        Class<?> authClass = tryClass("com.sun.appserv.security.ProgrammaticLogin");
        if (authClass != null)
        {
            return (Boolean)authClass.getMethod("login").invoke(
                authClass.newInstance(), "user", "password", request, response);
        }

        authClass = tryClass("org.jboss.web.tomcat.security.login.WebAuthentication");
        if (authClass != null)
        {
            return (Boolean)authClass.getMethod("login").invoke(
                authClass.newInstance(), "user", "password");
        }

        // ... other hacks ...application servers 

    }
    catch (Exception e)
    {
        throw new AuthenticationException("an error occured during user authentication", e);
    }

    return false;
}

【问题讨论】:

  • 您真的在使用老式 J2EE 吗?你不是说Java EE吗?如果是这样,是 5 还是 6? Java EE 5 完全不提供编程身份验证功能,Java EE 6 提供,您可以在最后一个链接问题中阅读。
  • 对不起。当然是 Java EE 5。总是把他们弄糊涂。
  • 您提到了 Servlet 2.3。 Servlet 2.3 是 J2EE 1.3 的一部分。 Java EE 5 有 Servlet 2.5。
  • 我目前正在使用 Java EE 5。但它必须在仅实现 J2EE 1.4 的 WebSphere 6.1 上工作。对不起,这是我的沉默。

标签: java security jsf jakarta-ee java-ee-5


【解决方案1】:

啊,它是 J2EE 1.3 Java EE 5。太糟糕了,每当你想继续使用容器管理的安全性时,你就很不走运。您必须从幕后获取特定于容器的实现。顺便说一句,“没有j_security_check 或BASIC/DIGEST 的容器管理安全”是自相矛盾的。我个人会忘记这一切并自行开发安全性或获取更可配置的第 3 方实现,例如 Spring Security

【讨论】:

    【解决方案2】:

    程序化登录非常棘手,而且似乎因应用服务器而异。我相信使用 j_security_check 是最成功的,并且可以让您的应用程序跨各种应用程序服务器工作。

    困难的部分是让应用服务器接受身份验证。在 Tomcat 上,我已经能够执行 myLoginModule.login() 并让登录模块成功,但用户未通过容器进行身份验证。 JBoss 有一些代码可以让编程身份验证在 JBoss 和 Tomcat 之间工作(因为 Tomcat 位于 JBoss 中)。对 Glassfish 进行研究后,我的印象是程序化登录非常困难,应该留给专业人士。

    Glassfish 文档 (http://docs.sun.com/app/docs/doc/820-4496/beacm?a=view) 说:

    程序化登录特定于企业服务器,不能移植到其他应用程序服务器。

    编辑

    j_security_check 方法需要一点时间来适应,但是一旦你学会了解决它,就会非常成功。基本上,您可以有一个欢迎页面,将用户重定向到您的应用程序;如果用户尚未登录,他们将被发送到您的登录页面。您的登录页面可以是您网站的主页。进入主页后,用户可以导航到您网站的其他“不安全”页面。如果您愿意,您也可以在这些页面上包含登录表单。您不会被一个登录页面卡住。

    编辑 2

    我一直在使用 AJAX(通过 Richfaces)检查用户的用户名/密码,并在需要时显示错误消息。如果凭据正确,则提交指向 j_security_check 的表单以进行实际身份验证。

    编辑 3

    BalusC 在第二个链接问题上建议的编程登录方法(http://stackoverflow.com/questions/2206911/best-way-for-user-authentication-on-javaee-6-using-jsf-2- 0) 做request.login(...) 看起来很棒。我很快就会尝试;o) Glassfish 3 支持 Servlet 3,但还没有其他支持(将成为 Tomcat 7 的一部分,可能是 JBoss 6)。

    【讨论】:

    • 变化? j_security_check 是 Java EE API 的一部分,由所有 Java EE Web 容器实现。 API 提供的编程使用仅在 Java EE 6 之后可用。
    • 好的。我的意思是成功编程登录所需的编程代码(不使用 j_security_check)似乎在应用服务器之间有所不同。
    • @BalusC EE 6 是否提供了一些标准的、可移植的编程登录方法?如果是这样,那就太酷了。
    • HttpServletRequest#login(),另请参阅问题中第二个链接问题中的答案。由于不清楚 OP 实际使用的是什么,因此无法可靠地回答这个问题。
    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2013-11-27
    相关资源
    最近更新 更多