[英]Remember me auto login with JSF + JAAS
我试图在我的应用程序中添加记住我的功能,但是由于某种原因HttpServletRequest.login()抛出ServletException
:
javax.servlet.ServletException: Login failed
at com.cleanup.filter.AutoLoginFilter.doFilter(AutoLoginFilter.java:71)
第71行:
req.login(adminUser.getEmail(), adminUser.getPwd());
我知道根据文档:
抛出 :ServletException-如果配置的登录机制不支持用户名密码身份验证,或者已经建立了非空的调用者身份(在登录之前),或者对提供的用户名和密码的验证失败。
这又意味着凭据是“无效的”,这是不正确的,因为登录机制可以正常工作。
但是,为什么会引发此异常呢?
我的理论是,由于password
已加密,因此,如果是这种情况,则request.login(..,..)
也可以使用已散列的密码?
这是我的过滤器:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String remoteUser = (String) req.getRemoteUser();
if (remoteUser == null) {
String uuid = CookieRememberUtil.getCookieValue(req);
System.out.println("Found cookie" + uuid);
if (uuid != null) {
AdminUsers adminUser = cookiesFacade.getAdminUserFromUUID(uuid);
if (adminUser != null) {
req.login(adminUser.getEmail(), adminUser.getPwd());
CookieRememberUtil.addCookie(resp, uuid);
} else {
CookieRememberUtil.removeCookie(resp);
}
}
}
chain.doFilter(request, response);
}
问题是备份登录过程的基础领域实现。
登录方法不可避免地要遵循配置的Realm进行实际身份验证。 例如,如果您使用的是数据库领域,则领域将在数据库中查找用户,比较密码,然后提取角色信息。
因此,您需要做的是使Realm具有“ cookie意识”。
也就是说,当您点击过滤器时,您可以检查“记住我” cookie,并将该信息基本上传递给登录方法,以便最终到达您的自定义领域,然后做正确的事情。
String uuid = CookieRememberUtil.getCookieValue(req);
if (uuid != null) {
req.login("***REMEMBER_ME***", uuid);
} else {
... run your normal login logic
}
然后,领域将查找魔术用户,其名称为“ REMEMBER_ME ”,并使用UUID提取凭据,并建立主体。
然后,通常,您不允许用户名中带有“ *”之类的内容,这样一来,某人登录并向您发送带有UUID的垃圾邮件就很难获得访问权限。 您可以在登录时进行检查,并使用无效的用户名,找不到的用户等直接终止。
因此,TLDR,您需要为容器定义一个自定义领域。
编辑:
为了使容器执行授权,它使用一种称为领域的概念。 领域是用于验证用户,检查其密码并通过创建主体来加载其角色的一段代码。 所有的容器都带有内置的Realms,它们执行基本的工作:处理平面文件,处理数据库,也许处理LDAP服务器。
您可以编写一个自定义的Realm实现并将其安装在您的容器中,它通常是您实现的非常简单的接口。
领域的整个目的是获取凭据,并返回一个主体。 使用Servlet 3.x的程序化登录功能,您不仅可以选择何时进行登录调用,还可以选择要传递到Realm的凭据。
通常,您输入用户名和密码。 Realm查找用户名,对密码进行哈希处理,将其与存储的内容进行比较,然后瞧瞧,创建一个简单的Principal并将其返回。
在您的情况下,当您设置了REMEMBER_ME cookie时,您将返回cookie或可从中提取的数据,而不是返回用户名和密码(因为您没有提示输入用户名和密码,而没有用户名和密码)。曲奇饼。 但是,您唯一的登录界面(通过登录方法)接受用户名和密码。 实际上,它接受两个字符串,可以将其用作用户名和密码。 实际上,它们可以是任意值-例如一个标志,指示Realm通过cookie值以及相关的cookie值登录。
领域使用cookie值来查找标识,并创建适当的主体。 您返回的主体不必具有与登录函数的第一个参数相同的“用户名”,它可以返回所需的任何主体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.