我刚刚编写了我的第一个servlet过滤器,并且已经出现了问题。我想要做的是进行过滤器句柄身份验证,以便在请求受保护的页面时,过滤器将切入并重定向到登录页面。如果登录成功,则过滤器会将用户重定向到请求的原始页面。
举一个例子,其中一个页面是博客页面。当用户点击“发表评论”时,如果他尚未登录,则过滤器会将其重定向到登录页面。直到这里,过滤器才能完成它的工作。然后用户登录并检查用户名/密码。如果它们没问题,则在jsp中设置会话变量,并再次将页面重定向到评论页面。该请求通过过滤器检查会话变量。但无论如何,我从请求中获得的会话似乎是一个没有设置属性的新会话。我试过调用request.getSession(false),似乎总是返回null。所以不要给我回到我的jsp页面共享的相同会话。
我正在使用tomcat 7.0.2。我不知道这是否是特定于tomcat的,或者只有一些非常明显的东西我不知道。
希望你能帮帮我。
吉斯利
- 更新 -
这是我的代码。猜猜这会很有帮助:)。
基本上,我有一个登录页面,一个博客页面和一个评论页面。在博客页面上,我有这个链接:
<a href="?page=blogg/komment.jsp?id=<%=blog.getID()%>"> Leave comment </a>
在我的过滤器中,我有这个:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse)res;
HttpSession session = request.getSession(false);
Object userObj = null;
if( session != null ) {
userObj = session.getAttribute( "username" );
}
String contextPath = request.getContextPath();
String queryString = request.getQueryString();
String url = request.getRequestURI();
String page = request.getParameter("page");
String user = "<user>";
if( userObj != null )
user = userObj.toString();
if( page == null )
page = "<page>";
if( userObj == null && page.indexOf( "blogg/komment.jsp" ) != -1 ) {
session.setAttribute( "destPage", page );
response.sendRedirect( "index.jsp?page=blogg/login.jsp" );
}
System.out.println( ", Time "
+ new Date().toString() + " " + page + " " + user);
chain.doFilter(req, res);
}
到目前为止,这么好。这会将我重定向到登录页面。在那里,我这样做:
String user = request.getParameter( "username" );
String pass = request.getParameter( "password" );
if( blog.confirmUser( user, pass ) ) {
session.setAttribute( "username", user );
Object destPageObj = session.getAttribute( "destPage" );
String destPage = "xxx";
if( destPageObj != null )
destPage = destPageObj.toString();
response.sendRedirect( "index.jsp?page=" + destPage );
%>
User exists
<%
}
else {
%>
User does not exist
<%
}
字符串“User exists”永远不会被打印出来,但它总是出现,我得到了登录页面。
这是我不明白的。我设置会话变量“username”,以便当下一个请求到达过滤器时,该变量应包含一个值。但它似乎总是空洞的。实际上,当我在过滤器中调用getSession(false)时,我总是返回null。即使会话变量应该始终存在于JSP中,如果它没有表达。
我已尝试在页面之间传递会话变量,并且完美无缺。但是要在页面中设置会话变量并在下一次重定向中将其读回,总是会失败。
我觉得有一种非常明显的东西让我盯着我,我只是花了很长时间才看到它!
希望你们能帮忙!
- 进一步更新 -
写作评论的空间太小:)。我想做的就是这个。我想让我的jsp页面独立于登录页面。即我希望过滤器充当中介。因此,当我将用户发送到我的评论页面时,我不需要担心他是否登录。如果他没有登录,过滤器应该将他重定向到登录页面,然后将他发送到原始目的地。我的博客不是唯一需要身份验证的东西,我希望将这些逻辑放在同一个地方。
出于安全原因,我不想传递用户名/密码作为请求参数。我希望两者都保留为会话属性。
当你说我在登录页面做的事情应该在过滤器中完成时,我不明白你的意思。我需要一个页面来询问用户他的用户名和密码,我不想发送这些请求。我在这里看到了一个例子,link这正是我想要做的。除非由于某种原因这不起作用,因为我似乎无法访问存储用户名的同一会话。
如果我完全弄错了,你能指点我这样做的网页吗?我花了几个小时谷歌搜索,我发现的所有例子似乎都适合每个人,除了我:)。
答案 0 :(得分:1)
经过大量的谷歌搜索和挖掘后,我解决了这个问题。
我没有提到的一件事是,我让Tomcat在代理后面运行。并且代理没有提供会话cookie。在我的虚拟主机定义中,我有这个:
<IfModule proxy_module>
ProxyRequests Off
ProxyPass / http://b6.is:8080/B6/
ProxyPassReverse / http://b6.is:8080/B6/
</IfModule>
因此,所有内容都从根目录传递给B6 webapp。
我只需要翻译cookie路径就是添加这一行:
ProxyPassReverseCookiePath /B6 /
现在它完美无缺。