我一直在研究一个简单的 jsf 安全传输机制,其中配置的 https 约束在 web.xml 中设置为机密。现在,我想做的是选择一个特定的页面进行安全传输。我有一个登录页面,可以将我带到另一个页面。登录页面需要一个用户名和密码,并应通过安全层将其传输到一个 ejb,该 ejb 在显示请求的页面之前验证其真实性。现在当我使用像 / 这样的 url 模式时faces/pageToView.xhtml 对于 web.xml 中请求的页面,我得到了一个我不太理解的有趣行为。首先,当我登录时,我的 pageToView.xhtml 显示时没有 https,当我点击转到另一个 pageToView2.xhtml 我的第一个 pageToView.xhtml 使用 https 重新显示。即使我没有为安全传输配置它们,我导航到的所有其他页面不仅显示 https。我需要知道为特定页面配置安全传输行为的正确方法。提前致谢。
1 回答
看起来的方式是,当您访问 https 时,并且您通常会在登录页面上执行此操作,您会停留在 https 上。在我看来,对于安全要求有限的应用程序来说,这似乎是一个很大的开销,但在研究它时,一致认为最大的风险是会话劫持。因此,如果您有 2 个安全页面登录和购物并且所有其他页面不使用 ssl,他们将通过无线/有线方式以明文方式发送会话 cookie,并且可以嗅探 cookie。
我认为,如果您的应用程序服务器前面有一个 apache Web 服务器,那么您有更多选择,例如在客户端浏览器和某些页面的 apache 之间使用 https,但在 apache 和应用程序服务器之间使用 http。我相当确定你可以做到这一点,但我不是专家,也没有尝试过。
当我前段时间研究这个时,我遇到了由 Glassfish 团队之一编写的这个过滤器,它应该从 https - http 降档。我的回忆是,当与容器安全性结合使用时,所有东西都降档后才停止工作。
通过一些调整,您可以使其适应您的环境,在此示例中,main.xhtml 文件是 web.xml 中的欢迎文件,其想法是这将是成功登录时加载的页面,因此最早的点从 https - http 降档。您需要取消注释 @WebServlet,使用您自己的日志记录代替 Log.log() 并检查任何 url/路径名。
在花时间在这之前,请记住我永远无法让它工作,建议接受打击并一直使用 https。
package uk.co.sportquest.jsfbeans.helper;
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU General
* Public License Version 2 only ("GPL") or the Common Development and
* Distribution License("CDDL") (collectively, the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy of the
* License at https://glassfish.dev.java.net/public/CDDL+GPL.html or
* glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year] [name of copyright
* owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or only
* the GPL Version 2, indicate your decision by adding "[Contributor] elects to
* include this software in this distribution under the [CDDL or GPL Version 2]
* license." If you don't indicate a single choice of license, a recipient has
* the option to distribute your version of this file under either the CDDL, the
* GPL Version 2 or to extend the choice of license to its licensees as provided
* above. However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is made
* subject to such option by the copyright holder.
*/
import java.io.*;
import java.util.*;
import java.security.*;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.security.jacc.*;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.*;
import uk.co.sportquest.general.Log;
/**
* Filter that downshifts from https to http if the given request came in over
* https, but the target resource does not require any confidentiality
* protection.
*
* @author jluehe
* @author monzillo
*/
//@WebFilter(filterName = "CacheFilterStatic", urlPatterns = {"/faces/secure/main.xhtml"},
// dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.ERROR, DispatcherType.REQUEST, DispatcherType.INCLUDE})
public class MyFilter implements Filter {
private static final CodeSource cs =
new CodeSource(null, (java.security.cert.Certificate[]) null);
private static final ProtectionDomain pd =
new ProtectionDomain(cs, null, null, null);
// private static final Policy policy = Policy.getPolicy();
private static final Policy policy = Policy.getPolicy();
private static final String httpPort = "8080";
@Override
public void init(javax.servlet.FilterConfig filterConfig)
throws ServletException {
//httpPort = filterConfig.getInitParameter("httpPort");
}
@Override
@SuppressWarnings("static-access")
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain filterChain)
throws IOException, ServletException {
if (req.isSecure()) {
HttpServletRequest httpReq = (HttpServletRequest) req;
Permission p = new WebUserDataPermission(httpReq);
p = new WebUserDataPermission(p.getName(), httpReq.getMethod());
//SQLog.log("Filter: " + httpReq.getRequestURI());
boolean isTransportProtected = policy.implies(pd, p) ? false : true;
Log.log();
if (!isTransportProtected) {
// Downshift from https to http, by redirecting to the
// target resource using http
String redirectUrl = "http://" + req.getServerName() + ":"
+ httpPort + httpReq.getRequestURI();
String queryString = httpReq.getQueryString();
if (queryString != null) {
redirectUrl += "?" + queryString;
}
//redirectUrl = "http://localhost:8080/SportQuest/faces/secure/main.xhtml";
Log.log("url: " + redirectUrl);
((HttpServletResponse) res).sendRedirect(redirectUrl);
} else {
// Perform normal request processing
Log.log("normal");
filterChain.doFilter(req, res);
}
} else {
// Perform normal request processing
Log.log("even more normal");
filterChain.doFilter(req, res);
}
}
@Override
public void destroy() {
// Do nothing
}
}