我想在JSF/Primefaces应用程序中实现一个简单的身份验证。我尝试了很多不同的东西,例如Dialog-Login Demo对对话框进行了简单的测试,但它没有登录用户或?
我还研究了Java Security,比如:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/protected/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>REGISTERED_USER</role-name>
</auth-constraint>
</security-constraint>
有了这个,所有受保护的东西都受到了保护,但据我所知,我需要在服务器中定义一个用于身份验证的领域。我不想在服务器中指定这一点,只是在数据库中进行简单的查找
有没有一种方法可以在不在应用程序服务器中定义内容的情况下对用户进行身份验证?还是其他简单的解决方案来验证和保护不同的页面?
有没有一种方法可以在不在应用程序服务器中定义内容的情况下对用户进行身份验证?
这是一个漫长而棘手的故事。它经常成为对Java EE的主要批评点之一
故事的核心是,传统的JavaEE应用程序应该部署有"未解决的依赖关系"。这些依赖关系必须在应用程序服务器上得到满足,通常由非开发人员通过使用某种GUI或控制台来满足。
安全配置是未解析的依赖项之一。
如果安全配置是在应用程序服务器上完成的,那么根据定义,这始终是不可移植的,例如,必须以应用程序服务器特定的方式完成。它完全排除了使用应用程序域模型(例如JPA实体User
(进行此身份验证的可能性。
一些服务器(例如JBoss AS(允许在应用程序中配置其专有的安全机制,此外还允许从应用程序加载"自定义登录模块"(几乎每个服务器的术语都不同(。通过一些小技巧,这将允许使用应用程序域模型和应用程序本身用于身份验证的相同数据源。
最后,还有一种相对未知的可移植方法可以在应用程序中进行身份验证。这是通过JASPICSPI完成的,也称为JASPI或JSR196。基本上,这个JASPIC似乎就是你想要的。
不幸的是,JASPIC并不完美,尽管它是Java EE 6中的一项技术,而且我们几乎已经达到了Java EE 7,但目前在各种应用程序服务器中对JASPIC的支持仍然很粗略。除此之外,即使JASPIC是标准化的,应用程序服务器供应商仍然以某种方式需要专有配置才能使其真正工作。
我写了一篇关于JASPIC的文章,更详细地解释了当前的问题:用JASPIC 在Java EE中实现容器身份验证
我只需使用Web过滤器就找到了一个适合自己的简单解决方案。我在web.xml中添加了一个类似的过滤器
<!-- Authentication Filter -->
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>org.example.filters.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/protected/*</url-pattern>
</filter-mapping>
过滤器看起来像这个
@WebFilter(filterName="AuthenticationFilter")
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Cookie[] cookies = ((HttpServletRequest)request).getCookies();
// Try to find a valid session cookie
if (cookies != null) {
String sessionId = null;
for (Cookie cookie : cookies) {
if ("sessionId".equals(cookie.getName())) {
sessionId = cookie.getValue();
}
}
// Check if we have a valid session
UserSession session = Backend.getInstance().getSessionGateway().getBySessionId(sessionId);
if (session != null) {
chain.doFilter(request, response);
return;
} else if (sessionId != null) {
// Remove the cookie
Cookie cookie = new Cookie("sessionId", null);
cookie.setMaxAge(-1);
((HttpServletResponse)response).addCookie(cookie);
}
}
// Problem due to relative path!!
// ((HttpServletResponse)response).sendRedirect("../login.xhtml");
RequestDispatcher rd = request.getRequestDispatcher("/login.xhtml");
rd.forward(request, response);
}
}
所以我只需要实现一个Bean来验证和设置会话cookie。我将添加用户代理以获得额外的安全性,但它基本上可以工作。
我唯一的问题是无法进行重定向,因为它不使用上下文路径,而只是重定向到/index.xhtml,而不是/my_app_context/index.xhtml