如何处理/限制用户对 servlet 和 jsp 的访问?
Posted
技术标签:
【中文标题】如何处理/限制用户对 servlet 和 jsp 的访问?【英文标题】:How can I handle/restrict user-access to servlets & jsp's? 【发布时间】:2013-08-16 22:52:29 【问题描述】:我目前正在用 Java 编写一个小的动态 Web 应用程序。 该应用程序应该是一个事件平台,您可以在其中创建用户帐户,登录,然后您可以查看所有打开的事件(在以后的迭代中,用户可以创建/参与这些事件)。
现在,网络应用的结构可以(简化)如下描述:
Register-Servlet -> Register.jsp
|
V
Login-Servlet -> Login.jsp
|
V
Main-page-Servlet -> Main.jsp
所以现在,用户可以访问 Login.jsp,他的登录信息将被发送到 Login-Servlet,它会对其进行验证,然后将其发送到 Main-Page-Servlet。 Main-Page-Servlet 然后(在再次验证登录后)从数据库中获取所有当前事件,将其附加到请求中,并将其转发到 Main.jsp,后者将其显示给用户查看。
现在,如果用户想要直接访问 Main.jsp(而不是来自 Main-Page-Servlet),它显然无法显示可用的事件。我目前使用的解决方法是进行空检查以查看事件是否存在,如果不存在,则重定向到 Main-Page-Servlet。
这样解决我的问题让我很困扰,因为我认为这不是最佳做法,而且我认为随着我的应用程序变得越来越大,它只会产生很多其他问题。
我的第一个想法是,如果我可以简单地对用户“隐藏”所有 .jsp 文件,这可能会很有用,这样用户就只能登陆 servlet 并且不能以不同的方式访问 .jsp 文件。
有没有办法做到这一点?或者,如果不是,如果我要编写专业的企业级应用程序,最佳实践解决方案是什么?
【问题讨论】:
查看身份验证和授权。使用 servlet,这些通常使用HttpSession
及其周围实现。
【参考方案1】:
这可以在Filter
中处理,*** Servlet-Filter wiki 中有很好的解释和示例。
针对您的问题调整代码(注意needsAuthentication
方法的添加和使用):
@WebFilter("/*")
public class LoginFilter implements Filter
@Override
public void init(FilterConfig config)
throws ServletException
// If you have any <init-param> in web.xml, then you could get them
// here by config.getInitParameter("name") and assign it as field.
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String requestPath = httpServletRequest.getRequestURI();
if (needsAuthentication(requestPath) ||
session == null ||
session.getAttribute("user") == null) // change "user" for the session attribute you have defined
response.sendRedirect(request.getContextPath() + "/login"); // No logged-in user found, so redirect to login page.
else
chain.doFilter(req, res); // Logged-in user found, so just continue request.
@Override
public void destroy()
// If you have assigned any expensive resources as field of
// this Filter class, then you could clean/close them here.
//basic validation of pages that do not require authentication
private boolean needsAuthentication(String url)
String[] validNonAuthenticationUrls =
"Login.jsp", "Register.jsp" ;
for(String validUrl : validNonAuthenticationUrls)
if (url.endsWith(validUrl))
return false;
return true;
我建议将所有需要身份验证的页面移到 app
之类的文件夹中,然后将网络过滤器更改为
@WebFilter("/app/*")
这样,您可以删除过滤器中的needsAuthentication
方法。
【讨论】:
哇,谢谢。我想问题就这样解决了,尽管我需要一段时间才能完成所有这些工作:) @MrTrustworthy 不客气。补充一点,如果您没有使用像 Tomcat 5 这样的 Servlet 3.0 兼容应用程序服务器,那么您必须在 web.xml 中以旧方式配置过滤器。请注意,这已包含在我发布的 wiki 链接中。 +1, @MrTrustworthy 如果您想在 web.xml 中手动配置它,如果您使用的是 servlets @sureshatta 所有内容都包含在 *** 的 servlet-filter wiki 中。您也应该检查该链接:) @Luiggi:啊,我只看了你的代码 15 分钟,然后它就拍了下来,我明白了:D 我唯一不明白的是为什么 validNonAuthenticationUrls 包含这些字符串,因为它们是我只想通过 servlet 访问那些(尤其是 main.jsp)。我的想法有错误吗?【参考方案2】:有几种方法可以做到这一点,例如上面的 servlet 过滤器。我在一些项目中看到他们使用更简单的机制通过创建一个通用操作(servlet)来完成它。所以不是扩展 HttpServlet,而是所有 servlet 都将扩展通用动作。而且你可以实现很多常见的东西,比如身份验证、验证、权限......
以下是常见操作示例:
public class CommonServlet extends HttpServlet
................
................
protected boolean validate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
response.setContentType("text/html; charset=UTF-8");
request.setCharacterEncoding("UTF-8");
String email = (String) request.getSession().getAttribute("email");
Object salaryGroup = request.getSession().getAttribute("SALARY_GROUP");
if (email == null || email.equals(""))
request.setAttribute("err", "You have not logged in");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return false;
................
................
public void setRoleAndValidate(HttpServletRequest request, HttpServletResponse response, String role)
throws ServletException, IOException
if (!validate(request, response))
return;
setRoleCode(role);
................
................
您的操作 servlet 将如下所示:
@WebServlet("/employeeManager")
public class EmployeeManager extends CommonServlet
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException
request.setCharacterEncoding("UTF-8");
setRoleAndValidate(request, response, Permission.EMPLOYEE_LIST.toString());
String action = request.getParameter("action");
.....
Here's the simple implementation
【讨论】:
以上是关于如何处理/限制用户对 servlet 和 jsp 的访问?的主要内容,如果未能解决你的问题,请参考以下文章
如何处理从 servlet 中的 Angular 应用程序发送的预检请求?