如何使用过滤器限制来自地址栏的所有请求
How to restrict all the requests coming from address bar using filters
我正在使用 struts 2
和 hibernate
开发一个 java 网络应用程序。我想限制用户通过直接在地址栏上键入来调用任何 struts 操作。相反,用户应该使用 JSP 页面本身提供的链接,因为在我的应用程序中有很多访问级别,所以现在用户通过直接在地址栏上键入操作名称来进行未经授权的访问。在返回成功之前,我已经检查了登录用户对每个功能的访问级别。但这不是到处检查的好习惯。我搜索了有关使用 java Filters
来执行此操作的信息,但没有成功。
我用来实现过滤器的内容如下:-
web.xml(Security
是我的包名,SessionFilter
是 servlet
class )
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
Security.SessionFilter
</filter-class>
<init-param>
<param-name>avoid-urls</param-name>
<param-value>Index.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Index.jsp
是我的应用程序的入口点,所以我想只允许通过在地址栏上键入其他任何内容来直接访问此页面。如果用户在地址栏上键入任何其他操作名称 he/she 应该再次重定向到登录页面,这就是为什么我在下面的代码中写了这个 response.sendRedirect("Index.jsp");
SessionFilter.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
private ArrayList<String> urlList;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean allowedRequest = false;
if (urlList.contains(url)) {
allowedRequest = true;
}
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
response.sendRedirect("Index.jsp");
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
String urls = config.getInitParameter("avoid-urls");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
}
首先,访问级别检查不应该在 jsp 页面上。此页面应仅显示视图。用户是否有权访问特定资源应该在服务器端使用某种用户级别或角色级别的安全性来处理。为此,您可以实现自己的过滤器,也可以使用已经可用的安全库,例如 spring-security 或 shiro security.
但是如果您不想这样做并想坚持您当前的方法,那么您可以检查每个请求的 header X-Requested-With
。对于 ajax 个请求,它包含 XMLHttpRequest
。但它不是标准的header,所有browsers/user-agents可能不会发送这个header。为确保 ajax 请求,您可以向从您的页面发送的每个请求添加一些自定义 header。
但是再次使用这种方法,如果未经授权的用户想要访问某个操作,he/she 可以通过手动将 header 添加到他们的请求中来实现。所以在服务器端而不是在客户端检查授权是一个不错的选择。
您可以实施过滤器来检查授权访问并通过将他们重定向到登录或索引页面来拒绝任何未经授权的访问。
但是因为你使用了struts2;您可以利用 struts2 拦截器:
要定义一个 struts2 拦截器:
public class LogInInterceptor implements Interceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Map<String, Object> sessionMap = ActionContext.getContext().getSession();
if (sessionMap.get("urlList").contains(url)) {
return invocation.invoke();
} else {
return "index-jsp-alias";
}
}
// setters and getters.
}
在 struts.xml 文件中定义这个拦截器:
<interceptors>
<interceptor name="mylogging" class="LogInInterceptor" />
<interceptor-stack name="loggingStack">
<interceptor-ref name="mylogging" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="loggingStack" />
<global-results>
<result name="index-jsp-alias">Index.jsp</result>
</global-results>
我找到了我的问题的解决方案并在我的应用程序中成功实施。非常感谢所有有用的答案和建议。
我的实现如下:-
web.xml
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
Security.SessionFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SessionFilter.java
package Security;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
req.setCharacterEncoding("UTF-8");
HttpServletRequest request = (HttpServletRequest) req;
String referrer = request.getHeader("referer");
if (null == request.getSession(true).getAttribute("emp_id")) {
if (referrer == null) {
if (isSessionExcluded(req)) {
req.setAttribute("isSessionExpire", "true");
RequestDispatcher reqDisp = req.getRequestDispatcher("/Index.jsp");
reqDisp.forward(req, resp);
}
}
} else {
if (referrer == null) {
RequestDispatcher reqDisp = req.getRequestDispatcher("/Error.jsp");
reqDisp.forward(req, resp);
}
}
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
private boolean isSessionExcluded(ServletRequest req) {
if (req instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) req;
String contextPath = request.getContextPath();
String reqUri = request.getRequestURI();
if (!(contextPath + "/Index.jsp").equals(reqUri)) {
return true;
}
}
return false;
}
}
I have used String referrer = request.getHeader("referer");
in doFilter
method. This will distinguish the requests whether the request generated by typing on address bar or by clicking some link. In case when the request is generated by address bar typing, the value of referrer will be null.
我希望这个解决方案对其他人也有帮助。
我正在使用 struts 2
和 hibernate
开发一个 java 网络应用程序。我想限制用户通过直接在地址栏上键入来调用任何 struts 操作。相反,用户应该使用 JSP 页面本身提供的链接,因为在我的应用程序中有很多访问级别,所以现在用户通过直接在地址栏上键入操作名称来进行未经授权的访问。在返回成功之前,我已经检查了登录用户对每个功能的访问级别。但这不是到处检查的好习惯。我搜索了有关使用 java Filters
来执行此操作的信息,但没有成功。
我用来实现过滤器的内容如下:-
web.xml(Security
是我的包名,SessionFilter
是 servlet
class )
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
Security.SessionFilter
</filter-class>
<init-param>
<param-name>avoid-urls</param-name>
<param-value>Index.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Index.jsp
是我的应用程序的入口点,所以我想只允许通过在地址栏上键入其他任何内容来直接访问此页面。如果用户在地址栏上键入任何其他操作名称 he/she 应该再次重定向到登录页面,这就是为什么我在下面的代码中写了这个 response.sendRedirect("Index.jsp");
SessionFilter.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
private ArrayList<String> urlList;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean allowedRequest = false;
if (urlList.contains(url)) {
allowedRequest = true;
}
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
response.sendRedirect("Index.jsp");
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
String urls = config.getInitParameter("avoid-urls");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
}
首先,访问级别检查不应该在 jsp 页面上。此页面应仅显示视图。用户是否有权访问特定资源应该在服务器端使用某种用户级别或角色级别的安全性来处理。为此,您可以实现自己的过滤器,也可以使用已经可用的安全库,例如 spring-security 或 shiro security.
但是如果您不想这样做并想坚持您当前的方法,那么您可以检查每个请求的 header X-Requested-With
。对于 ajax 个请求,它包含 XMLHttpRequest
。但它不是标准的header,所有browsers/user-agents可能不会发送这个header。为确保 ajax 请求,您可以向从您的页面发送的每个请求添加一些自定义 header。
但是再次使用这种方法,如果未经授权的用户想要访问某个操作,he/she 可以通过手动将 header 添加到他们的请求中来实现。所以在服务器端而不是在客户端检查授权是一个不错的选择。
您可以实施过滤器来检查授权访问并通过将他们重定向到登录或索引页面来拒绝任何未经授权的访问。
但是因为你使用了struts2;您可以利用 struts2 拦截器:
要定义一个 struts2 拦截器:
public class LogInInterceptor implements Interceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Map<String, Object> sessionMap = ActionContext.getContext().getSession();
if (sessionMap.get("urlList").contains(url)) {
return invocation.invoke();
} else {
return "index-jsp-alias";
}
}
// setters and getters.
}
在 struts.xml 文件中定义这个拦截器:
<interceptors>
<interceptor name="mylogging" class="LogInInterceptor" />
<interceptor-stack name="loggingStack">
<interceptor-ref name="mylogging" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="loggingStack" />
<global-results>
<result name="index-jsp-alias">Index.jsp</result>
</global-results>
我找到了我的问题的解决方案并在我的应用程序中成功实施。非常感谢所有有用的答案和建议。
我的实现如下:-
web.xml
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
Security.SessionFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SessionFilter.java
package Security;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
req.setCharacterEncoding("UTF-8");
HttpServletRequest request = (HttpServletRequest) req;
String referrer = request.getHeader("referer");
if (null == request.getSession(true).getAttribute("emp_id")) {
if (referrer == null) {
if (isSessionExcluded(req)) {
req.setAttribute("isSessionExpire", "true");
RequestDispatcher reqDisp = req.getRequestDispatcher("/Index.jsp");
reqDisp.forward(req, resp);
}
}
} else {
if (referrer == null) {
RequestDispatcher reqDisp = req.getRequestDispatcher("/Error.jsp");
reqDisp.forward(req, resp);
}
}
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
private boolean isSessionExcluded(ServletRequest req) {
if (req instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) req;
String contextPath = request.getContextPath();
String reqUri = request.getRequestURI();
if (!(contextPath + "/Index.jsp").equals(reqUri)) {
return true;
}
}
return false;
}
}
I have used
String referrer = request.getHeader("referer");
indoFilter
method. This will distinguish the requests whether the request generated by typing on address bar or by clicking some link. In case when the request is generated by address bar typing, the value of referrer will be null.
我希望这个解决方案对其他人也有帮助。