gpt4 book ai didi

security - 如何为 jsessionid cookie 启用相同站点

转载 作者:行者123 更新时间:2023-12-04 13:56:44 29 4
gpt4 key购买 nike

如何为在 wildfly 上运行的 Web 应用程序启用相同站点。
已检查 standalone.xml但是在其中找不到合适的标签

<servlet-container name="default">
<session-cookie http-only="true" secure="true"/>
<jsp-config/>
</servlet-container>

最佳答案

至于现在 Java Servlet 4.0 规范不支持 SameSite cookie 属性。您可以通过打开 javax.servlet.http.Cookie 查看可用属性java类。
但是,有几个解决方法。您可以手动覆盖 Set-Cookie 属性。
方法 #1(使用自定义 Spring HttpFirewall 和请求包装器):
您需要在创建 session 后立即包装请求并调整 cookie。您可以通过定义以下类来实现它:
一个bean(如果你想把所有东西都放在一个地方,你可以在SecurityConfig中定义它。为了简洁起见,我只是在上面放了@Component注释)

package hello.approach1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Component;

@Component
public class CustomHttpFirewall implements HttpFirewall {

@Override
public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
return new RequestWrapper(request);
}

@Override
public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
return new ResponseWrapper(response);
}

}
第一个包装类
package hello.approach1;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
* Wrapper around HttpServletRequest that overwrites Set-Cookie response header and adds SameSite=None portion.
*/
public class RequestWrapper extends FirewalledRequest {

/**
* Constructs a request object wrapping the given request.
*
* @param request The request to wrap
* @throws IllegalArgumentException if the request is null
*/
public RequestWrapper(HttpServletRequest request) {
super(request);
}

/**
* Must be empty by default in Spring Boot. See FirewalledRequest.
*/
@Override
public void reset() {
}

@Override
public HttpSession getSession(boolean create) {
HttpSession session = super.getSession(create);

if (create) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) {
overwriteSetCookie(ra.getResponse());
}
}

return session;
}

@Override
public String changeSessionId() {
String newSessionId = super.changeSessionId();
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) {
overwriteSetCookie(ra.getResponse());
}
return newSessionId;
}

private void overwriteSetCookie(HttpServletResponse response) {
if (response != null) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=None")); // set
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=None")); // add
}
}
}
}
第二个包装类
package hello.approach1;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
* Dummy implementation.
* To be aligned with RequestWrapper.
*/
public class ResponseWrapper extends HttpServletResponseWrapper {
/**
* Constructs a response adaptor wrapping the given response.
*
* @param response The response to be wrapped
* @throws IllegalArgumentException if the response is null
*/
public ResponseWrapper(HttpServletResponse response) {
super(response);
}
}
方法 #2(使用 Spring 的 AuthenticationSuccessHandler):

This approach doesn't work for basic authentication.In case basic authentication, response is flushed/committed right after controller returns response object, before AuthenticationSuccessHandlerImpl#addSameSiteCookieAttribute is called.


package hello.approach2;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
addSameSiteCookieAttribute(response); // add SameSite=strict to Set-Cookie attribute
response.sendRedirect("/hello"); // redirect to hello.html after success auth
}

private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}
}
方法 #3(使用 javax.servlet.Filter):

This approach doesn't work for basic authentication.In case basic authentication, response is flushed/committed right after controller returns response object, before SameSiteFilter#addSameSiteCookieAttribute is called.


package hello.approach3;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpHeaders;

public class SameSiteFilter implements javax.servlet.Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
addSameSiteCookieAttribute((HttpServletResponse) response); // add SameSite=strict cookie attribute
}

private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}

@Override
public void destroy() {

}
}
方法 #4(如果您使用的是 Tomcat 9.0.21/Tomcat 8.5.42 或更高版本)
在您的 Web 应用程序中,在 META-INF 文件夹中创建一个 context.xml 文件,其中包含以下内容:
<Context>
<CookieProcessor sameSiteCookies="strict" />
</Context>
从 Tomcat 9.0.28/Tomcat 8.5.48 开始可以将 SameSite 设置为 none)
this pull request更多细节。
演示项目
你可以看看 this demo project有关前 3 种方法的配置的更多详细信息,请访问 GitHub。
SecurityConfig包含所有必要的配置。

Using addHeader is not guaranteed to work because basically theServlet container manages the creation of the Session and Cookie. Forexample, the second and third approaches won't work in case you return JSON inresponse body because application server will overwrite Set-Cookieheader during flushing of response. However, second and third approaches willwork in cases, when you redirect a user to another page after successfulauthentication.


Pay attention that Postman doesn't render/support SameSite cookie attribute under Cookies section (at least at the time of writing). You can look at Set-Cookie response header or use curl to see if SameSite cookie attribute was added.

关于security - 如何为 jsessionid cookie 启用相同站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49697449/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com