-
Notifications
You must be signed in to change notification settings - Fork 6k
Allow to set the cookie domain in class CookieCsrfTokenRepository #4315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We're experiencing the same problem. We have api.example.com with web.example.com as the front-end, in Angular2. The Set-Cookie comes back from Spring but, being a different domain, the cookie is lost. @renannprado , did you find another way to approach this? |
@jh409 I'm no longer using this, 'cause we've changed the XSRF protection we're using. import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.util.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
/**
* TODO: change the implementation when https://github.com/spring-projects/spring-security/issues/4315 is fixed
*/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${xx.csrf.cookie.domain}")
private String CSRF_COOKIE_DOMAIN;
@Value("${xx.csrf.cookie.name}")
private String CSRF_COOKIE_NAME;
@Autowired
private Environment environment;
@Override
protected void configure(HttpSecurity http) throws Exception {
final CsrfConfigurer<HttpSecurity> httpSecurityCsrfConfigurer = http.csrf()
.csrfTokenRepository(new CustomDomainCookieCsrfTokenRepository(CSRF_COOKIE_DOMAIN, CSRF_COOKIE_NAME))
// the method to verify if the links are saved won't require CSRF protection
.ignoringAntMatchers("/**/xx/yy/*");
// will let the CSRF protection enabled unless we have the disable-csrf profile active
if (Arrays.stream(environment.getActiveProfiles()).anyMatch(profile -> profile.equals("disable-csrf"))) {
httpSecurityCsrfConfigurer.disable();
}
}
/**
* saveToken method had to be coped from {@link CookieCsrfTokenRepository} because the class is final
*/
public static class CustomDomainCookieCsrfTokenRepository implements CsrfTokenRepository {
private final CookieCsrfTokenRepository cookieCsrfTokenRepository;
private final String cookieDomain;
private final String cookieName;
public CustomDomainCookieCsrfTokenRepository(final String cookieDomain, final String cookieName) {
this.cookieCsrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
this.cookieCsrfTokenRepository.setCookieName(cookieName);
this.cookieDomain = cookieDomain;
this.cookieName = cookieName;
}
@Override
public CsrfToken generateToken(final HttpServletRequest request) {
return cookieCsrfTokenRepository.generateToken(request);
}
@Override
public void saveToken(final CsrfToken token, final HttpServletRequest request, final HttpServletResponse response) {
String tokenValue = token == null ? "" : token.getToken();
Cookie cookie = new Cookie(cookieName, tokenValue);
cookie.setSecure(request.isSecure());
cookie.setDomain(cookieDomain);
if (!StringUtils.isEmpty(this.cookieCsrfTokenRepository.getCookiePath())) {
cookie.setPath(this.cookieCsrfTokenRepository.getCookiePath());
} else {
cookie.setPath(this.getRequestContext(request));
}
if (token == null) {
cookie.setMaxAge(0);
}
else {
cookie.setMaxAge(-1);
}
// we don't need this because our cookie won't be http only
// if (cookieHttpOnly && setHttpOnlyMethod != null) {
// ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE);
// }
response.addCookie(cookie);
}
@Override
public CsrfToken loadToken(final HttpServletRequest request) {
return cookieCsrfTokenRepository.loadToken(request);
}
private String getRequestContext(HttpServletRequest request) {
String contextPath = request.getContextPath();
return contextPath.length() > 0 ? contextPath : "/";
}
}
} |
Any thoughts on this from the spring team? This would be useful to us as well. |
Any updates on this? |
We don't have any plans for implementing this ourselves a the moment. However, if someone wants to provide a PR that would be very welcome. |
@rwinch I'd like to take it |
Summary
We need to set the domain of the CSRF cookie, because we have many subdomains accessing the our API under api.example.com. With the current implementation the cookie is only accessible from api.example.com, but the users will never go to this domain. They will go to x.example.com, example.com, etc...
Actual Behavior
No method to set the cookie domain.
Expected Behavior
Provided method to customize the cookie domain
Version
4.2.2.RELEASE
Sample
The text was updated successfully, but these errors were encountered: