如何从JSF操作(或在servlet doGet
/ doPost
方法中)对用户进行身份验证?
我的意思是:
Authenticator auth = ...;
if (!auth.authenticate("user","password"))
{
FacesContext.getInstance().addMessage("Incorrect username or password", null);
}
限制:
不使用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;
}
答案 0 :(得分:1)
程序化登录非常棘手,似乎因应用程序服务器而异。我相信使用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)说:
程序化登录特定于Enterprise Server,不能移植到其他应用程序服务器。
修改强>
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)Servfish 3由Glassfish 3提供支持,但还不是很多(将成为Tomcat 7的一部分,可能是JBoss 6)。
答案 1 :(得分:1)
啊,它是 J2EE 1.3 Java EE 5.太糟糕了,每当你想要继续使用容器管理安全时,你都会失去运气。您必须从封底获取特定于容器的实现。顺便说一下,“没有j_security_check
或BASIC / DIGEST”的容器管理安全性是自相矛盾的。我个人会忘记这一切,并且可以放弃安全性或者获取更易于配置的第三方实现,例如Spring Security。