Same as Why does Chrome ignore Set-Cookie header? but I have provided code for the frameworks I am using.
Here is my original text, I put it as an answer to above (not really an answer but it did provide some code as was requested, but the sysop tells me as it is not an answer I should raise the question again. So here it is...
I have been stuck on this for too long. All works fine in Postman, Firefox, etc, etc, but Chrome stubbornly refuses to accept the Set-Cookie header.
My server (Spring Zuul Proxy)
@Bean
public CorsFilter corsFilter() {
logger.info("=================> corsFilter intialization.");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Collections.singletonList("http://neptune.local.mydoman.org:4200"));
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Arrays.stream(HttpMethod.values()).map(HttpMethod::name).collect(Collectors.toList()));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Pretty open, but not worried about that, I will tighten up once I have it working.
I want to store the refresh_token in a HTTP Only cookie, I have relaxed that for testing to see if the cookie is set.
My PostFilter to set the cookie before response is sent.
@Component
public class CustomPostZuulFilter extends ZuulFilter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper mapper = new ObjectMapper();
// Default is 30 days
@Value("${oauth.http.cookie.maxAge:2592000}")
private int cookieMaxAge;
@Override
public Object run() {
final RequestContext ctx = RequestContext.getCurrentContext();
logger.info("PostZuulFilter called: " + ctx.getRequest().getRequestURI());
final String requestURI = ctx.getRequest().getRequestURI();
final String requestMethod = ctx.getRequest().getMethod();
try {
final InputStream is = ctx.getResponseDataStream();
String responseBody = IOUtils.toString(is, "UTF-8");
if (responseBody.contains("refresh_token")) {
final Map<String, Object> responseMap =
mapper.readValue(responseBody,
new TypeReference<Map<String, Object>>() {
});
final String refreshToken = responseMap.get("refresh_token").toString();
logger.info("Decoding refresh token from response.");
decodeJwtToken(refreshToken);
responseMap.remove("refresh_token");
responseBody = mapper.writeValueAsString(responseMap);
final Cookie cookie = new Cookie("refreshToken", refreshToken);
// cookie.setHttpOnly(true);
// cookie.setSecure(true);
cookie.setPath(ctx.getRequest().getContextPath() + "/oauth/token");
cookie.setMaxAge(cookieMaxAge); // 30 days
ctx.getResponse().addCookie(cookie);
logger.info("PostZuulFilter refresh token now stored in HTTP ONLY cookie:");
logger.info(refreshToken);
}
if (requestURI.contains("oauth/token") && requestMethod.equals("DELETE")) {
final Cookie cookie = new Cookie("refreshToken", "");
cookie.setMaxAge(0);
cookie.setPath(ctx.getRequest().getContextPath() + "/oauth/token");
ctx.getResponse().addCookie(cookie);
}
ctx.setResponseBody(responseBody);
} catch (final IOException e) {
logger.error("Error occured in zuul post filter", e);
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 10;
}
@Override
public String filterType() {
return "post";
}
private String decodeJwtToken(String jwtToken) {
logger.info("------------ Decode JWT ------------");
String[] split_string = jwtToken.split("\\.");
String base64EncodedHeader = split_string[0];
String base64EncodedBody = split_string[1];
String base64EncodedSignature = split_string[2];
logger.info("~~~~~~~~~ JWT Header ~~~~~~~");
Base64 base64Url = new Base64(true);
String header = new String(base64Url.decode(base64EncodedHeader));
System.out.println("JWT Header : " + header);
logger.info("~~~~~~~~~ JWT Body ~~~~~~~");
String body = new String(base64Url.decode(base64EncodedBody));
logger.info("JWT Body : "+body);
return "";
}
}
And finally my Angular Service request.
public obtainAccessToken(params: URLSearchParams): Observable<string> {
console.log('obtainAccessToken');
console.log('Getting access token from ', appConfig.tokenServerUrl);
console.log('Using params: ');
console.dir(params.toString());
// Now fire the request
this.http.post(
'http://neptune.local.domain.org:8084/oauth/token',
params.toString(), {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'}),
withCredentials: true,
observe: 'response'
})
.pipe(map((response) => {
// Try and find the Set-Cookie header! (Good luck)
console.log(response);
console.log('response headers',response.headers.keys());
const respKeySet = response.headers.keys();
for( let x = 0; x < respKeySet.length; x++ ) {
console.log('Key: %s, Value: %s',
respKeySet[x],
response.headers.get(respKeySet[x]));
}
}));
}
My server and my client are running on the same workstation, I have set the FQD name.
So Client is running on. http://neptune.local.mydomain.org:4200
My Server is running on. http://neptune.local.mydomain.org:8084
I never get the Set-Cookie in Chrome???
Anyone know why? Erm, HELP....