简体   繁体   English

Cookie http仅具有spring security和servlet 2.5?

[英]Cookie http only with spring security and servlet 2.5?

I want to make my cookie secure and http request only. 我想确保我的Cookie的安全和仅HTTP请求。

Ive seen many post like this and seem to work fine, but using configuration files and servlet +3. 我看过很多帖子像这样 ,似乎做工精细,但使用的配置文件和servlet +3。

What I basically want to do is to set my cookie http only and (if possible) ssl only as well. 我基本上想要做的是仅将Cookie http和(如果可能)也设置为ssl。

So far I added this to my web.xml 到目前为止,我已将此添加到我的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>

doesnt do anything, as far as I was reading, I also have to configure my servlet.xml to enable this feature, but I dont know how... 什么也不做,据我所读,我还必须配置servlet.xml来启用此功能,但是我不知道如何...

Any idea how to do this? 任何想法如何做到这一点?

EDIT: 编辑:

Since I am using servlets 2.5 the xml configuration is not an option, maybe a filter? 由于我使用的是servlets 2.5,因此无法选择xml配置,也许是过滤器?

I hate XML configuration, so i spend some time for find non-XML solution. 我讨厌XML配置,所以我花了一些时间来查找非XML解决方案。

Since Spring Security 1.3 you can use 从Spring Security 1.3开始,您可以使用

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

in your application.properties file. 在您的application.properties文件中。

Maybe there is a way to set this using pure Java Configuration, but i can't find them. 也许有一种方法可以使用纯Java配置进行设置,但是我找不到它们。

We ran across this issue recently. 我们最近遇到了这个问题。 I tried the property settings for http-only, which worked locally, but not when we deployed to our test env. 我尝试了仅HTTP的属性设置,该属性设置在本地有效,但是在部署到测试环境时却没有。 It's possible there were some default settings in the env overriding those local settings. env中可能有一些默认设置会覆盖这些本地设置。 What worked was to set the properties in a Spring config file: 起作用的是在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);
        }
    };
}

The context.xml changes mentioned by javagc will only reconfigure your session cookie. javagc提到的context.xml更改只会重新配置您的会话cookie。

To change all of your cookies, you have 2 options: 要更改所有cookie,您有2种选择:

Option 1) Update your application code to add cookies using a more secure method. 选项1)更新您的应用程序代码以使用更安全的方法添加cookie。 Example: https://stackoverflow.com/a/30488471/95674 示例: https//stackoverflow.com/a/30488471/95674

Option 2) You can configure a servlet filter to change ALL (other) cookies coming through the system. 选项2)您可以配置servlet过滤器以更改通过系统的所有(其他)cookie。 Add these 2 classes into the appropriate package in your WAR. 将这两个类添加到WAR中的相应包中。 Then update your web.xml as detailed below. 然后,如下所述更新您的web.xml。

There is a simpler example of Option 2 listed on the OWASP site, if you are willing to add a dependency on the OWASP libraries. 如果您愿意添加对OWASP库的依赖关系,则在OWASP站点上列出了选项2的简单示例。 That is located here: https://www.owasp.org/index.php/HttpOnly#Using_Java_to_Set_HttpOnly 那位于这里: https : //www.owasp.org/index.php/HttpOnly#Using_Java_to_Set_HttpOnly

Response Wrapper 响应包装

This adds the http only flag to all cookies on the wrapped response. 这会将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());
 }
}

Filter 过滤

This Filter wraps configured responses in the above wrapper. 此筛选器将配置的响应包装在上述包装器中。

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;
 }
}

Adapted (WARNING: NOT an exact copy!) from source: http://sylvanvonstuppe.blogspot.com/2007/07/servlet-filter-for-httponly.html 改编自以下来源(警告:不完全相同!),来源: http//sylvanvonstuppe.blogspot.com/2007/07/servlet-filter-for-httponly.html

web.xml web.xml

One last detail: ONLY IF you have annotation scanning turned OFF in your system like this: 最后一个细节:仅当您在系统中关闭注释扫描时,如下所示:

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

Then you will need to manually configure the above Filter in your web.xml file, like this: 然后,您将需要在web.xml文件中手动配置上述过滤器,如下所示:

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

If your app scans annotations (which is the default), the web.xml part is not necessary. 如果您的应用程序扫描注释(默认设置),则不需要web.xml部分。

With the help of ServletContextListener we have control at servlet at tomcat startup and shutdown. 借助ServletContextListener,我们可以在Tomcat启动和关闭时对Servlet进行控制。 So here on tomcat startup we are setting the configuration of httponly. 因此,在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);

    }
}

Abb beloww entry in web.xml web.xml中的Abb beloww条目

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

I believe you are missing the security tag. 我相信您缺少安全标签。 Try adding: 尝试添加:

<secure>false</secure>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM