Hi all, 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. There are multiple issue I encounter: - *Spring issue*: CAS are using Spring, but seems the samesite issue still not fix on Spring end, so it is really hard to make clean fix - *Compatbility issue*: If you just enabled the samesite = None, it will break some recent version of Mac, which is really not ideal. What we done to fix it: *Spring 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. For that, we just use generateHeader logic from: https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java And implement our own TGCCookieRetrievingCookieGenerator. *Compatibility issue:* We follows this: https://www.chromium.org/updates/same-site/incompatible-clients 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; /** * Follows the snippet in https://www.chromium.org/updates/same-site/incompatible-clients * 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. Cheers! - Andy -- - Website: https://apereo.github.io/cas - Gitter Chatroom: https://gitter.im/apereo/cas - List Guidelines: https://goo.gl/1VRrw7 - Contributions: https://goo.gl/mh7qDG --- You received this message because you are subscribed to the Google Groups "CAS Community" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/18adee3b-98c8-4605-8bf4-5d4069f1dc1a%40apereo.org.
