Skip to content

Introduce SessionAttributeCompressor #2008

@quaff

Description

@quaff
public interface SessionAttributeCompressor<T> {

	boolean accepts(String attributeName);

	T compress(Object attributeValue);

	Object uncompress(T serializedAttributeValue);

}

then we can compress spring security SecurityContext to username

import lombok.RequiredArgsConstructor;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.util.StringUtils;

@RequiredArgsConstructor
public class SecurityContextSessionAttributeCompressor implements SessionAttributeCompressor<String> {

	private final UserDetailsService userDetailsService;

	@Override
	public boolean accepts(String attributeName) {
		return HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY.equals(attributeName);
	}

	@Override
	public String compress(Object securityContext) {
		SecurityContext sc = (SecurityContext) securityContext;
		if (sc == null || sc.getAuthentication() == null) {
			return null;
		}
		return sc.getAuthentication().getName();
	}

	@Override
	public Object uncompress(String compressedSecurityContext) {
		SecurityContext sc = SecurityContextHolder.getContext();
		if (StringUtils.hasLength(compressedSecurityContext)) {
			UserDetails ud = this.userDetailsService.loadUserByUsername(compressedSecurityContext);
			Authentication auth = new UsernamePasswordAuthenticationToken(ud, ud.getPassword(), ud.getAuthorities());
			sc.setAuthentication(auth);
		}
		return sc;
	}

}

Two advantages:

  1. Minified serialized session
  2. Avoid stale state of UserDetails, currently UserDetails in session is not synchronized with UserDetailsService, session is valid even if user is deleted.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions