如何实现JSF登录过滤器? [英] How implement a login filter in JSF?
问题描述
我想即使用户知道一些页面的URL,以阻止某些网页的访问。
例如, /localhost:8080/user/home.xhtml
(需先做登录),如果没有登录然后重定向到 /index.xhtml
。
I would like to block the access of some page even if the user knows the url of some pages.
For example, /localhost:8080/user/home.xhtml
(need to do the login first) if not logged then redirect to /index.xhtml
.
如何在JSF?我在这是需要一个过滤器的谷歌阅读,但我不知道该怎么做。
How do that in JSF ? I read in the Google that's needed a filter, but I don't know how to do that.
推荐答案
您需要实施<一个href=\"http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html\"><$c$c>javax.servlet.Filter$c$c>类,请在的doFilter()
方法所需的作业并将其映射在一个URL模式涵盖了受限制的页面, /用户/ *
也许?在的doFilter()
您应检查登录用户的presence在盘中莫名其妙。此外,您还需要采取JSF Ajax和资源请求考虑在内。 JSF Ajax请求需要一个特殊的XML响应,让JavaScript的执行重定向。 JSF资源请求需要被跳过,否则您的登录页面将不会有任何的CSS / JS /图像了。
You need to implement the javax.servlet.Filter
class, do the desired job in doFilter()
method and map it on an URL pattern covering the restricted pages, /user/*
maybe? Inside the doFilter()
you should check the presence of the logged-in user in the session somehow. Further you also need to take JSF ajax and resource requests into account. JSF ajax requests require a special XML response to let JavaScript perform a redirect. JSF resource requests need to be skipped otherwise your login page won't have any CSS/JS/images anymore.
假设你已经登录的用户在JSF通过 externalContext.getSessionMap管理的bean(A
,那么你可以通过 /login.xhtml
页存储)。把(用户,用户)得到它session.getAttribute(用户)
通常像下面的方法
Assuming that you've a /login.xhtml
page which stores the logged-in user in a JSF managed bean via externalContext.getSessionMap().put("user", user)
, then you could get it via session.getAttribute("user")
the usual way like below:
@WebFilter("/user/*")
public class AuthorizationFilter implements Filter {
private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<partial-response><redirect url=\"%s\"></redirect></partial-response>";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURL = request.getContextPath() + "/login.xhtml";
boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
boolean loginRequest = request.getRequestURI().equals(loginURL);
boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));
if (loggedIn || loginRequest || resourceRequest) {
if (!resourceRequest) { // Prevent browser from caching restricted resources. See also http://stackoverflow.com/q/4194207/157882
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(request, response); // So, just continue request.
}
else if (ajaxRequest) {
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
response.getWriter().printf(AJAX_REDIRECT_XML, loginURL); // So, return special XML response instructing JSF ajax to send a redirect.
}
else {
response.sendRedirect(loginURL); // So, just perform standard synchronous redirect.
}
}
// You need to override init() and destroy() as well, but they can be kept empty.
}
此外,过滤器也获得页面上禁用浏览器缓存,所以浏览器后退按钮不会显示它们了。
Additionally, the filter also disabled browser cache on secured page, so the browser back button won't show up them anymore.
如果你碰巧使用JSF工具库 OmniFaces ,高于code可以减少如下:
In case you happen to use JSF utility library OmniFaces, above code could be reduced as below:
@WebFilter("/user/*")
public class AuthorizationFilter extends HttpFilter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws ServletException, IOException {
String loginURL = request.getContextPath() + "/login.xhtml";
boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
boolean loginRequest = request.getRequestURI().equals(loginURL);
boolean resourceRequest = Servlets.isFacesResourceRequest(request);
if (loggedIn || loginRequest || resourceRequest) {
if (!resourceRequest) { // Prevent browser from caching restricted resources. See also http://stackoverflow.com/q/4194207/157882
Servlets.setNoCacheHeaders(response);
}
chain.doFilter(request, response); // So, just continue request.
}
else {
Servlets.facesRedirect(request, response, loginURL);
}
}
}
参见:
- 我们的Servlet过滤器维基页面
- How办理认证/授权与用户数据库中的?
- Using JSF 2.0 / Facelets的,是有办法的全球监听器连接到所有的AJAX调用?
- 避免背部按钮JSF Web应用程序
- Our Servlet Filters wiki page
- How to handle authentication/authorization with users in a database?
- Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?
- Avoid back button on JSF web application
See also:
这篇关于如何实现JSF登录过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!