I have encounter this samesite issue as well for our 5.3.x CAS servers, and I come up with an ugly custom fix, I am sharing here if anyone need quick fix.
Since I manage multiple SPs for our CAS, and one SP with a different domain use CAS inside an iframe which trigger this issue.
At least on last time I research, seems like Spring are still taking some time to fix this issue, so we will need to code it ourselves.
And implement our own TGCCookieRetrievingCookieGenerator.
And change it to Java.
We have tested enough device before making the deployment, and seems fairly stable no one complain about compatibility issue:
SamesiteCookieChecker.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* and convert it to Java compatible
*
*
*/
public class SamesiteCookieChecker {
// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0
// Don’t send `SameSite=None` to known incompatible clients.
public boolean shouldSendSameSiteNone(String useragent) {
return !isSameSiteNoneIncompatible(useragent);
}
// Classes of browsers known to be incompatible.
private boolean isSameSiteNoneIncompatible(String useragent) {
return hasWebKitSameSiteBug(useragent) ||
dropsUnrecognizedSameSiteCookies(useragent);
}
private boolean hasWebKitSameSiteBug(String useragent) {
return isIosVersion(12, useragent) ||
(isMacosxVersion(10, 14, useragent) &&
(isSafari(useragent) || isMacEmbeddedBrowser(useragent)));
}
private boolean dropsUnrecognizedSameSiteCookies(String useragent) {
if (isUcBrowser(useragent)){
return !isUcBrowserVersionAtLeast(12, 13, 2, useragent);
}
return isChromiumBased(useragent) &&
isChromiumVersionAtLeast(51, useragent) &&
!isChromiumVersionAtLeast(67, useragent);
}
// Regex parsing of User-Agent string. (See note above!)
private boolean isIosVersion(int major, String useragent) {
String regex = "\\(iP.+; CPU .*OS (\\d+)[_\\d]*.*\\) AppleWebKit\\/";
// Extract digits from first capturing group.
Matcher m = Pattern.compile(regex).matcher(useragent);
if(!m.find()) {
return false;
}
//return useragent.regexMatch(regex)[0] == intToString(major);
return m.group(1).equals(String.valueOf(major));
}
private boolean isMacosxVersion(int major, int minor, String useragent) {
String regex = "\\(Macintosh;.*Mac OS X (\\d+)_(\\d+)[_\\d]*.*\\) AppleWebKit\\/";
// Extract digits from first and second capturing groups.
Matcher m = Pattern.compile(regex).matcher(useragent);
if(!m.find()) {
return false;
}
// return (useragent.regexMatch(regex)[0] == intToString(major)) &&
// (useragent.regexMatch(regex)[1] == intToString(minor));
return m.group(1).equals(String.valueOf(major)) &&
m.group(2).equals(String.valueOf(minor));
}
private boolean isSafari(String useragent) {
String safari_regex = "Version\\/.* Safari\\/";
// return useragent.regexContains(safari_regex) &&
// !isChromiumBased(useragent);
return Pattern.compile(safari_regex).matcher(useragent).find() &&
!isChromiumBased(useragent);
}
private boolean isMacEmbeddedBrowser(String useragent) {
String regex = "^Mozilla\\/[\\.\\d]+ \\(Macintosh;.*Mac OS X [_\\d]+\\) "
+ "AppleWebKit\\/[\\.\\d]+ \\(KHTML, like Gecko\\)$";
return Pattern.compile(regex).matcher(useragent).find();
}
private boolean isChromiumBased(String useragent) {
String regex = "Chrom(e|ium)";
return Pattern.compile(regex).matcher(useragent).find();
}
private boolean isChromiumVersionAtLeast(int major, String useragent) {
String regex = "Chrom[^ \\/]+\\/(\\d+)[\\.\\d]* ";
// Extract digits from first capturing group.
Matcher m = Pattern.compile(regex).matcher(useragent);
if(!m.find()) {
return false;
}
String version = m.group(1);
int intVersion;
try {
intVersion = Integer.parseInt(version);
} catch(NumberFormatException nfe) {
return false;
}
return intVersion >= major;
//int version = stringToInt(useragent.regexMatch(regex)[0]);
//return version >= major;
}
private boolean isUcBrowser(String useragent) {
String regex = "UCBrowser\\/";
return Pattern.compile(regex).matcher(useragent).find();
}
private boolean isUcBrowserVersionAtLeast(int major, int minor, int build, String useragent) {
String regex = "UCBrowser\\/(\\d+)\\.(\\d+)\\.(\\d+)[\\.\\d]* ";
Matcher m = Pattern.compile(regex).matcher(useragent);
if(!m.find()) {
return false;
}
// Extract digits from three capturing groups.
int major_version;
int minor_version;
int build_version;
try {
major_version = Integer.parseInt(m.group(1));
minor_version = Integer.parseInt(m.group(2));
build_version = Integer.parseInt(m.group(3));
} catch(NumberFormatException nfe) {
return false;
}
if (major_version != major) {
return major_version > major;
}
if (minor_version != minor) {
return minor_version > minor;
}
return build_version >= build;
}
}
Using the above I am managed to hot fix this samesite=none issue. Hopefully Spring will be able to fix this later down the timeline, so no need code it like this outselves.