Java EE 5 编程式身份验证

发布于 2024-10-03 04:24:59 字数 2352 浏览 3 评论 0原文

如何通过 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认证与授权
在 Java EE / JSF 中执行用户身份验证使用 j_security_check

编辑 1
我的意思是 servet 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;
}

How I can authenticate a user from JSF action (or in servlet doGet/doPost methods)?
I mean something like:

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

Restrictions:

  • This method must be compatible with container managed security. (i.e. `HttpServletRequest.getRemoteUser()` must return authenticated user)
  • This method must work everywhere (i.e. on each application server).

Not using j_security_check or another J2EE authentication type (BASIC, DIGEST, etc...)

It is possible?
Or how to create captcha in this way?
Validate that login and password is not empty?
On single page and without JavaScript, of course...

Similar questions... but without answer on this question:

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

Edit 1:
I mean serlvet API at least 2.3.
Yes, I read about login in Servlet API 3.0, but it is supported only by new versions of application servers.

I think that here can be some solution that implements this authentication for each application server.
Sometimes via some hacks, sometimes via special classes designed for this purpose.
Like this:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情话已封尘 2024-10-10 04:24:59

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

Ah, it's J2EE 1.3 Java EE 5. Too bad, you're out of luck whenever you want to go ahead with container managed security. You have to grab containerspecific implementations from under the covers. By the way, "container managed security without j_security_check or BASIC/DIGEST" is self-contradicting. I would personally just forget about it all and homegrow security or grab a 3rd party implementation which is more configureable, like Spring Security.

顾冷 2024-10-10 04:24:59

编程登录非常棘手,并且似乎因应用程序服务器而异。我相信使用 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)。

Programmatic login is pretty darn tricky and seems to vary by application server. I believe that going with the j_security_check is the most successful, and will allow your application to work across various application servers.

The hard part is getting the application server to accept the authentication. On Tomcat, I've been able to do myLoginModule.login() and have the login module succeed, but the user wasn't authenticated with the container. JBoss has some code to get programmatic authentication to work between JBoss and Tomcat (since Tomcat lives within JBoss). Looking into this for Glassfish, I got the impression that programmatic login is very difficult and should be left to the pro's.

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

Programmatic login is specific to the Enterprise Server and not portable to other application servers.

Edit

The j_security_check method takes a little getting used to, but once you learn to work around it, can be quite successful. Basically you can have a welcome page that redirects the user in to your application; if the user has not logged in yet, they'll get sent to your login page. Your login page can be your site's home page. Once on the home page, the user can navigate to other "unsecure" pages of your site. You can include login forms on those pages as well if you like. You're not stuck with a single login page.

Edit 2

I've been using AJAX (via Richfaces) to check the user's username/password and showing an error message if needed. If the credentials are correct, the form pointing to j_security_check is submitted to do the actual authentication.

Edit 3

The programmatic login method suggested by BalusC on the second linked question (http://stackoverflow.com/questions/2206911/best-way-for-user-authentication-on-javaee-6-using-jsf-2-0) doing request.login(...) looks great. I'll be trying it out soon ;o) Servlet 3 is supported by Glassfish 3 but not much else yet (will be part of Tomcat 7, probably JBoss 6).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文