需求:把所有未登陆的请求重定向到登陆页面
用Handler Interceptor验证登陆
JEECMS的FrontContextInterceptor已经实现了判断用户是否登陆的逻辑,只要在这基础上加上重定向就可以了。
修改FrontContextInterceptor.java:
if (user != null) {
CmsUtils.setUser(request, user);
} else if (!isAllowed(request)) {
response.sendRedirect(request.getContextPath() + site.getLoginUrl());
return false;
}
isAllowed
方法用于判断是否允于未登录时直接访问:
private boolean isAllowed(HttpServletRequest request)
throws ServletException {
String[] allowedUrl = {"login.jspx"};
String requestURI = request.getRequestURI();
if (!request.getMethod().equals("GET")) {
return true;
}
for (int i = 0; i < allowedUrl.length; i++) {
if (requestURI.indexOf(allowedUrl[i]) != -1) {
return true;
}
}
return false;
}
用Filter验证登陆
对静态页面,FrontContextInterceptor是不会处理的,所以再实现一个filter来处理。
web.xml:
<filter>
<filter-name>authFilter</filter-name>
<filter-class>com.jeecms.common.web.AuthFilter</filter-class>
</filter>
要过滤*.jhtml, *.html, *.htm的请求,加上AuthFilter,例如
<filter-mapping>
<filter-name>authFilter</filter-name>
<url-pattern>*.jhtml</url-pattern>
</filter-mapping>
AuthFilter.java:
public void doFilter(ServletRequest req,
ServletResponse rep, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) rep;
ServletContext sc = config.getServletContext();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(sc);
CmsUserMng cmsUserMng = (CmsUserMng)context.getBean("cmsUserMng");
AuthenticationMng authMng = (AuthenticationMng)context.getBean("authenticationMng");
CmsUser user = null;
Integer userId = authMng.retrieveUserIdFromSession(session, request);
if (userId != null) {
user = cmsUserMng.findById(userId);
}
if (user == null && (!isAllowed(request))) {
response.sendRedirect(request.getContextPath() + "/login.jspx");
} else {
chain.doFilter(req, rep);
}
}
主体参考FrontContextInterceptor
, 因为在web.xml
配置filter, 所以在AuthFilter
直接用WebApplicationContextUtil
拿到ApplicationContex
, 再拿到判断登用用的AuthenticationMng
,CmsUserMng
。
简化
像上面这样分开处理动态和静态页面略麻烦,而且验证也做多了,其实我们不需要在AuthFilter
里拿到用户的。所以我们简化一下逻辑,把全部页面都用一个AuthFilter
过滤。
public class AuthFilter implements Filter {
public void doFilter(ServletRequest req,
ServletResponse rep, FilterChain chain)
throws ServletException, IOException {
// We need HttpServlet* to get access to work with HTTP
// .....
// Obtain beans from Spring
// ....
if (!isLogined(session, authMng) && !isAllowed(request, response)) {
response.sendRedirect(request.getContextPath() + "/login.jspx");
} else {
chain.doFilter(req, rep);
}
}
// Check if an user is logined
private isLogined(SessionProvider session, AuthenticationMng authMng) {
String authId = (String) session.getAttribute(request, AUTH_KEY);
if (authId == null || authMng.retrieve(authId) == null) {
return false;
}
return true;
}
// Check if a request is allowed even if no user are logined
private boolean isAllowed( //...
}