【问题标题】:Cookie http only with spring security and servlet 2.5?Cookie http 仅适用于 spring security 和 servlet 2.5?
【发布时间】:2016-05-27 02:02:27
【问题描述】:

我只想让我的 cookie 安全且只请求 http 请求。

我看过很多类似this 的帖子,似乎工作正常,但使用的是配置文件和 servlet +3。

我基本上想做的是只设置我的cookie http 和(如果可能的话)ssl。

到目前为止,我已将此添加到我的 web.xml 中

    <session-config>
        <session-timeout>60</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

没有做任何事情,据我阅读,我还必须配置我的 servlet.xml 以启用此功能,但我不知道如何......

知道怎么做吗?

编辑:

由于我使用的是 servlets 2.5,xml 配置不是一个选项,也许是一个过滤器?

【问题讨论】:

  • 这个问题的赏金怎么了??
  • 我没有接受任何答案,因为它们都不起作用,并且赏金期限已过...
  • “过滤器工作顺利”不意味着答案有帮助吗?如果您不将赏金奖励给提供帮助的人,那么您就破坏了赏金系统,人们将来可能不会帮助您。在下面的回复中添加了一些注释(这是 IMO 的另一个问题)。
  • 有,但没有设置cookie...对不起,如果我没有给你赏金,你要知道,即使我没有给,赏金从提供的积分中打折赏金,所以,如果我不给它,是因为即使过滤器工作得很好,cookie 也没有......
  • 好吧,我不再帮忙了,所以我们看看你的效果如何。

标签: java spring servlets cookies


【解决方案1】:

我讨厌 XML 配置,所以我花了一些时间寻找非 XML 解决方案。

从 Spring Security 1.3 开始你可以使用

server.session.cookie.http-only=true
server.session.cookie.secure=true

在您的 application.properties 文件中。

也许有一种方法可以使用纯 Java 配置进行设置,但我找不到它们。

【讨论】:

  • 这些配置已弃用
【解决方案2】:

我们最近遇到了这个问题。我尝试了 http-only 的属性设置,它在本地工作,但在我们部署到我们的测试环境时却没有。环境中可能有一些默认设置覆盖了这些本地设置。有效的是在 Spring 配置文件中设置属性:

@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
            SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
            sessionCookieConfig.setHttpOnly(true);
            sessionCookieConfig.setSecure(true);
        }
    };
}

【讨论】:

    【解决方案3】:

    javagc 提到的 context.xml 更改只会重新配置您的会话 cookie。

    要更改所有 cookie,您有 2 个选项:

    选项 1) 更新您的应用程序代码以使用更安全的方法添加 cookie。示例:https://stackoverflow.com/a/30488471/95674

    选项 2)您可以配置一个 servlet 过滤器来更改通过系统的所有(其他)cookie。将这 2 个类添加到 WAR 中的适当包中。然后更新您的 web.xml,如下所述。

    如果您愿意添加对 OWASP 库的依赖项,可以在 OWASP 站点上列出一个更简单的选项 2 示例。位于此处:https://www.owasp.org/index.php/HttpOnly#Using_Java_to_Set_HttpOnly

    响应包装器

    这会将 http only 标志添加到包装响应上的所有 cookie。

    public class HttpOnlyResponseWrapper extends HttpServletResponseWrapper {
    
     public HttpOnlyResponseWrapper(HttpServletResponse res) {
       super(res);
     }
    
     public void addCookie(Cookie cookie) {
       StringBuilder header = new StringBuilder();
       if ((cookie.getName() != null) && (!cookie.getName().equals(""))) {
         header.append(cookie.getName());
       }
       if (cookie.getValue() != null) {
         // Empty values allowed for deleting cookie
         header.append("=" + cookie.getValue());
       }
    
       if (cookie.getVersion() == 1) {
         header.append(";Version=1");
         if (cookie.getComment() != null) {
           header.append(";Comment=\"" + cookie.getComment() + "\"");
         }
         if (cookie.getMaxAge() > -1) {
           header.append(";Max-Age=" + cookie.getMaxAge());
         }
       } else {
         if (cookie.getMaxAge() > -1) {
           Date now = new Date();
           now.setTime(now.getTime() + (1000L * cookie.getMaxAge()));
           SimpleDateFormat cookieFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz");
           header.append(";Expires=" + cookieFormat.format(now));
         }
       }
    
       if (cookie.getDomain() != null) {
         header.append(";Domain=" + cookie.getDomain());
       }
       if (cookie.getPath() != null) {
         header.append(";Path=" + cookie.getPath());
       }
       if (cookie.getSecure()) {
         header.append(";Secure");
       }
       header.append(";httpOnly");
       addHeader("Set-Cookie", header.toString());
     }
    }
    

    过滤器

    此过滤器将配置的响应包装在上述包装器中。

    package yourpackage;
    
    @WebFilter(filterName = "HttpOnlyFilter", urlPatterns = {"/*"})
    public class HttpOnlyFilter implements Filter {
     private FilterConfig config;
    
     @Override
     public void destroy() {
       this.config = null;
     }
    
     @Override
     public void doFilter(ServletRequest req, ServletResponse res,
         FilterChain chain) throws IOException, ServletException {
    
       HttpOnlyResponseWrapper hres = new HttpOnlyResponseWrapper((HttpServletResponse)res);
       chain.doFilter(req, hres);
     }
    
     public FilterConfig getFilterConfig() {
       return this.config;
     }
    
     @Override
     public void init(FilterConfig config) throws ServletException {
       this.config = config;
     }
    }
    

    改编自(警告:不是精确副本!)来源:http://sylvanvonstuppe.blogspot.com/2007/07/servlet-filter-for-httponly.html

    web.xml

    最后一个细节:仅当您在系统中关闭注释扫描时:

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             version="2.5" ***metadata-complete="true"***>
    </web-app> 
    

    然后你需要在你的 web.xml 文件中手动配置上面的过滤器,像这样:

    <filter>
        <filter-name>HttpOnlyFilter
        <filter-class>yourpackage.HttpOnlyFilter
    </filter>
    <filter-mapping>
        <filter-name>HttpOnlyFilter
        <url-pattern>/*
    </filter-mapping>
    

    如果您的应用扫描注释(这是默认设置),则不需要 web.xml 部分。

    【讨论】:

    • 您好,我看到了第一个选项,但不知道在哪里设置...这是最好的方法吗?我看到了课程...但是,我将其添加到过滤器中?
    • 过滤器运行顺畅!只是想知道,如果不再使用xml配置,我该如何设置域名或secure = true?还是只是将它们硬编码到类中?
    • XML配置只针对会话cookie;它不适用于您的应用程序设置的所有 cookie。如果您想为应用设置的 cookie 设置域或安全值,您需要在 cookie 本身上设置它们。我过去曾使用过 Cookie 的子类来执行此操作。 (public class MyCookie extends Cookie,在构造函数中为 domain/secure 设置默认值。添加 getter 和 setter 为所有内容调用 super,然后确保每个人都使用它而不是 Cookie。)
    【解决方案4】:

    ServletContextListener 的帮助下,我们可以在 Tomcat 启动和关闭时控制 servlet。所以这里在tomcat启动时我们设置httponly的配置。

    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    public final class ContextListener implements ServletContextListener {
    
        private ServletContext context = null;
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            this.context = null;
        }
        @Override
        public void contextInitialized(ServletContextEvent event) {
            this.context = event.getServletContext();
            this.context.getSessionCookieConfig().setHttpOnly(true);
    
        }
    }
    

    web.xml 中的 Abb 下面w 条目

    <listener>
    <description>contextListener</description>
    <listener-class>
            main.ContextListener 
        </listener-class>
     </listener>
    

    【讨论】:

    • java.lang.UnsupportedOperationException: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with @WebListenerevent.getServletContext().getSessionCookieConfig();
    【解决方案5】:

    我相信您缺少安全标签。尝试添加:

    <secure>false</secure>
    

    【讨论】:

    • 谢谢,但这对配置没有任何影响
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2023-04-08
    • 2017-07-15
    • 1970-01-01
    • 2018-01-22
    • 2021-03-25
    相关资源
    最近更新 更多