JavaEE5编程身份验证

JavaEE5编程身份验证,java,security,jsf,jakarta-ee,java-ee-5,Java,Security,Jsf,Jakarta Ee,Java Ee 5,如何从JSF操作(或在servletdoGet/doPost方法中)对用户进行身份验证? 我的意思是: Authenticator auth = ...; if (!auth.authenticate("user","password")) { FacesContext.getInstance().addMessage("Incorrect username or password", null); } 限制: 此方法必须与容器管理的安全性兼容。(即`HttpServletReque

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

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

  • 此方法必须与容器管理的安全性兼容。(即`HttpServletRequest.getRemoteUser()`必须返回经过身份验证的用户)
  • 此方法必须在任何地方都适用(即在每个应用程序服务器上)
未使用
j_security\u check
或其他J2EE身份验证类型(基本、摘要等)

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

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


编辑1
我是说SerlvetAPI至少2.3。 是的,我在ServletAPI3.0中读到了关于
登录的内容,但是只有新版本的应用服务器才支持它

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

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;
}
私有类tryClass(字符串名称)
{
尝试
{
返回Class.forName(name);
}
catch(classnotfounde异常)
{
返回null;
}
}
公共布尔身份验证(字符串用户名、字符串密码)引发AuthenticationException
{
尝试
{
ExternalContext=FacesContext.getCurrentInstance().getExternalContext();
对象请求=context.getRequest();
对象响应=context.getResponse();
类authClass=tryClass(“com.sun.appserv.security.programmaticologin”);
if(authClass!=null)
{
返回(布尔值)authClass.getMethod(“登录”).invoke(
authClass.newInstance(),“用户”,“密码”,请求,响应);
}
authClass=tryClass(“org.jboss.web.tomcat.security.login.WebAuthentication”);
if(authClass!=null)
{
返回(布尔值)authClass.getMethod(“登录”).invoke(
authClass.newInstance(),“用户”,“密码”);
}
//…其他黑客…应用服务器
}
捕获(例外e)
{
抛出新的AuthenticationException(“用户身份验证期间发生错误”,e);
}
返回false;
}

编程登录非常棘手,而且似乎因应用服务器而异。我相信使用j_安全检查是最成功的,它将允许您的应用程序跨各种应用程序服务器工作

困难的部分是让应用服务器接受身份验证。在Tomcat上,我已经能够执行myLoginModule.login()并成功登录模块,但是用户没有通过容器的身份验证。JBoss有一些代码可以在JBoss和Tomcat之间进行编程身份验证(因为Tomcat生活在JBoss中)。对于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) Servlet 3受到Glassfish 3的支持,但其他功能还不多(将成为Tomcat 7的一部分,可能是JBoss 6)。

啊,它是J2EE1.3JavaEE5。太糟糕了,每当您想继续使用容器管理的安全性时,您都会运气不佳。您必须从幕后获取特定于容器的实现。顺便说一下,“没有
j_security\u check
或BASIC/DIGEST的容器管理安全性”是自相矛盾的。我个人会忘记这一切和homegrow安全性,或者选择一个更易于配置的第三方实现,比如。

你真的在使用老式的J2EE吗?你是说JavaEE吗?如果是的话,5个还是6个?JavaEE5完全没有提供编程身份验证的功能,JavaEE6也没有,正如您在上一个链接的问题中所看到的那样。我很抱歉。当然是JavaEE5。总是混淆它们。您提到了Servlet2.3。Servlet2.3是J2EE1.3的一部分。JavaEE5有Servlet2.5。我目前正在使用JavaEE5。但它必须在WebSphere6.1上工作,WebSphere6.1只实现J2EE1.4。对不起,这是我的沉默。法利
j_security_check
是JavaEEAPI的一部分,由所有JavaEEWeb容器实现。API提供的编程使用仅在JavaEE6.0之后可用。我的意思是,成功编程登录(不使用j_安全检查)所需的编程代码在应用程序服务器之间似乎有所不同。@BalusC EE 6是否提供了一些标准的、可移植的编程登录方法?如果是这样,那就太酷了。
HttpServletRequest#login()