Search code examples
spring-webfluxspring-cloud-gatewayspring-session

Spring Websession does not encode session id while setting Cookie


HttpSession encode the sessionid(base64) but WebSession not. Is there any way we can encode session id in websession too.

HttpSession has following code which allows us to control encoding while setting cookie


DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setUseBase64Encoding(true);
return serializer;

Do websession allow any customization or properties to enable encoding similar to httpsession?


Solution

  • You can define an WebSessionIdResolver bean like so

    @Component
    public class CustomWebSessionIdResolver extends CookieWebSessionIdResolver {
    
        private boolean useBase64Encoding = true;
    
        private final ServerProperties serverProperties;
    
        public CustomWebSessionIdResolver(ServerProperties serverProperties) {
            this.serverProperties = serverProperties;
            String cookieName = serverProperties.getReactive().getSession().getCookie().getName();
            if (StringUtils.hasText(cookieName)) {
                setCookieName(cookieName);
            }
            addCookieInitializer(this::initializeCookie);
        }
    
        @Override
        public List<String> resolveSessionIds(ServerWebExchange exchange) {
            MultiValueMap<String, HttpCookie> cookieMap = exchange.getRequest().getCookies();
            List<HttpCookie> cookies = cookieMap.get(getCookieName());
            if (cookies == null) {
                return Collections.emptyList();
            }
            return cookies.stream().map(cookie -> (this.useBase64Encoding ? base64Decode(cookie.getValue()) : cookie.getValue())).toList();
        }
    
        @Override
        public void setSessionId(ServerWebExchange exchange, String id) {
            super.setSessionId(exchange, (this.useBase64Encoding ? base64Encode(id) : id));
        }
    
        private void initializeCookie(ResponseCookie.ResponseCookieBuilder builder) {
            Cookie cookie = this.serverProperties.getReactive().getSession().getCookie();
            PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
            map.from(cookie::getDomain).to(builder::domain);
            map.from(cookie::getPath).to(builder::path);
            map.from(cookie::getHttpOnly).to(builder::httpOnly);
            map.from(cookie::getSecure).to(builder::secure);
            map.from(cookie::getMaxAge).to(builder::maxAge);
            map.from(getSameSite(cookie)).to(builder::sameSite);
        }
    
        private String getSameSite(Cookie properties) {
            Cookie.SameSite sameSite = properties.getSameSite();
            return (sameSite != null) ? sameSite.attributeValue() : null;
        }
    
        private String base64Encode(String value) {
            byte[] encodedCookieBytes = Base64.getEncoder().encode(value.getBytes());
            return new String(encodedCookieBytes);
        }
    
        private String base64Decode(String base64Value) {
            try {
                byte[] decodedCookieBytes = Base64.getDecoder().decode(base64Value);
                return new String(decodedCookieBytes);
            }
            catch (Exception ex) {
                return null;
            }
        }
    
    }