Spring session - nadpisanie sesji?

0

Cześć,
Mój config sesji wygląda w ten sposób:

        http
                .sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(true)
                .sessionRegistry(sessionRegistry());

Co w rezultacie, gdy logujemy się z innej przeglądarki czy karty incognito rzuca wyjątkiem:
org.springframework.security.web.authentication.session.SessionAuthenticationException: Maximum sessions of 1 for this principal exceeded

Docelowo chciałbym, aby przy próbie logowania z nowej (drugiej) przeglądarki nadpisywać ta pierwszą sesje i dać możliwość poprawnego zalogowania, zaś 'stara' sesja powinna zostać usunięta, oraz ten sam użytkownik powinien zostać wylogowany z pierwszej przeglądarki.

Czy ktoś mógłby rzucić jakimś rozwiązaniem? Będę wdzięczny.

1

Wystarczy samo .maximumSessions(1), bez .maxSessionsPreventsLogin(true).

0

bump?

1

Poczytałem fragment dokumentacji Spring Security - Concurrent Session Control.
Niestety, wygląda na to, że raczej wszystko zrobiłeś zgodnie z założeniami, ale nie znam defaultów w Spring Boot Security.

Może spróbuj dodać SessionAuthenticationStrategy?

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    final ConcurrentSessionControlAuthenticationStrategy sessionAuthStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
    sessionAuthStrategy.setMaximumSessions(1); // to akurat standardowo ma wartość 1
    sessionAuthStrategy.setExceptionIfMaximumExceeded(false); // wyłącz rzucanie wyjątku, gdy przekroczono max liczbę sesji
    http.sessionManagement()
        .sessionAuthenticationStrategy(sessionAuthStrategy)
        .maximumSessions(1); // wydaje mi się, że wówczas jest to zbędny parametr, ale zweryfikuj ;)
  }

Zerkając w kod ConcurrentSessionControlAuthenticationStrategy, w przypadku gdy przekroczona zostanie maksymalna liczba sesji, wygaszona zostnie najstarsza sesja.

/**
	 * Allows subclasses to customise behaviour when too many sessions are detected.
	 *
	 * @param sessions either <code>null</code> or all unexpired sessions associated with
	 * the principal
	 * @param allowableSessions the number of concurrent sessions the user is allowed to
	 * have
	 * @param registry an instance of the <code>SessionRegistry</code> for subclass use
	 *
	 */
	protected void allowableSessionsExceeded(List<SessionInformation> sessions,
			int allowableSessions, SessionRegistry registry)
			throws SessionAuthenticationException {
		if (exceptionIfMaximumExceeded || (sessions == null)) {
			throw new SessionAuthenticationException(messages.getMessage(
					"ConcurrentSessionControlAuthenticationStrategy.exceededAllowed",
					new Object[] { Integer.valueOf(allowableSessions) },
					"Maximum sessions of {0} for this principal exceeded"));
		}

		// Determine least recently used session, and mark it for invalidation
		SessionInformation leastRecentlyUsed = null;

		for (SessionInformation session : sessions) {
			if ((leastRecentlyUsed == null)
					|| session.getLastRequest()
							.before(leastRecentlyUsed.getLastRequest())) {
				leastRecentlyUsed = session;
			}
		}

		leastRecentlyUsed.expireNow();
	}

1 użytkowników online, w tym zalogowanych: 0, gości: 1