[Spring] Update uprawnień dla użytkownika

0

Witam, mam aplikację w której jest kilku użytkowników. Chciałbym dodać możliwość zmiany uprawnień dla każdego z nich. Czy istnieje możliwość zmiany uprawnień innego użytkownika bez konieczności ponownego logowania? Obecnie robię to zapisując uprawnienia użytkownika do bazy, następnie za pomocą SessionRegistry kończę sesję użytkownika i jest on zmuszony do ponownego logowania. Wtedy spring zaciąga nowe dane z bazy i zalogowany użytkownik ma zmienione authorities. Potrafię zmienić uprawnienia dla użykownika na którym jestem zalogowany bez konieczności wylogowywania się, natomiast chciałbym zrobić coś podobnego dla innych zalogowanych użytkowników. Czy spotkał się ktoś z podobnym problemem?

1

Ale w jaki sposób robisz autentykacje? Session cookie? JWT? Bo to co napisałeś brzmi trochę jak JWT i wtedy trochę ciężko, bo musiałbyś sprytnie w aplikacji zaszyć sobie logikę która podmieni komuś token jak sie coś zmieniło. Niemniej to i tak słabe, bo ktoś moze token mieć zapisany.

0

Za pomocą czegoś takiego

@Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }
@Bean
    DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        authenticationProvider.setUserDetailsService(this.userService);
        return authenticationProvider;
    }
0

No to czemu nie weźmiesz tego SessionRegistry i nie zrobisz tam nowej sesji dla usera któremu sie coś zmieniło, wrzucając tam zaktualizowane informacje? Zamiast usuwać sesje to zrób tam registerNewSession z tym samym sessionID ;]

0

Nie za bardzo wiem co powinienem przekazać do nowej sesji, co powinienem wstawić do registerNewSession

0

Obiekt Authentication, podobny do tego który możesz wyciągnąć z SessionRegistry.

0

Próbuję to zrobić w ten sposób ale nie działa, wiesz co jest nie tak?

List<Object> loggedUsers = sessionRegistry.getAllPrincipals();
        for (Object principal : loggedUsers) {
            if(principal instanceof User) {
                final User loggedUser = (User) principal;
                if(name.equals(loggedUser.getUsername())) {
                    List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false);
                    if(null != sessionsInfo && sessionsInfo.size() > 0) {
                        for (SessionInformation sessionInformation : sessionsInfo) {
                            List<GrantedAuthority> updatedAuthorities = new ArrayList<>(loggedUser.getAuthorities());
                            updatedAuthorities.add(new SimpleGrantedAuthority(newPermission));
                            Authentication newAuth = new UsernamePasswordAuthenticationToken(loggedUser.getUsername(), loggedUser.getPassword(), updatedAuthorities);
                            String sessionId = sessionInformation.getSessionId();
                            sessionRegistry.getSessionInformation(sessionId).expireNow();
                            sessionRegistry.registerNewSession(sessionId, newAuth);
                        }
                    }
                }
            }
        }
0

A jaki jest efekt? User jest wylogowany? Jest zalogowany ale ma złe authorities? Wyskakują różowe słonie?

0

Efekt jest taki jak poprzednio, zmiana Authorities dokonuje się po wylogowaniu i zalogowaniu usera. Powyższy kod nie powoduje wylogowania usera. Wydaje mi się że w tej sytuacji nie dokonała się zmiana authorities, a po ponownym zalogowaniu zaciąga authorities z bazy.

0

Możliwe, ale zauważ że jednak utworzyłeś nową sesje! Dla pewności możesz sprawdzić co sie stanie jak pominiesz to registerNewSession.
Jeśli to wyloguje usera, to znaczy że jednak aplikacja MUSI używać tej sesji którą tam wrzuciłeś. Więc jeśli nie działa, to znaczy że musi z nią coś być nie tak.
Jeśli to nie wyloguje usera, to znaczy że gdzieś jeszcze jest informacja o sesji.

Możesz też postawić breakpoint w tym SessionRegistry i zobaczyć co i kiedy jest z niego czytane.
Komputery to nie jest magia, skądś te informacje muszą być czytane.

0

Po usunięcie linijki z registerNewSession user został wylogowany. Wydaje mi się że problemem jest to że nie potrafię pobrać Authorities innego użytkownika z poprzedniej sesji, i przypisać ich do nowej. Znasz sposób na pobranie authorities konkretnego usera?

0

Jeżeli to ja jestem zalogowanym użytkownikiem, zmiana uprawnień bez wylogowania dzieje się w następujący sposób:

            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
            updatedAuthorities.add(new SimpleGrantedAuthority(newPermission));
            Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);
            SecurityContextHolder.getContext().setAuthentication(newAuth);

Jak dobrać się do powyższych danych dla innego użytkownika, który również jest zalogowany? I jak te dane zapisać?

0

Masz przecież ten DaoAuthenticationProvider który potrafi zwrócić UserDetails a tam masz authorities.

0

Czy podczas tworzenia sesji za pomocą registerNewSession na pewno powinienem dawać w nim obiekt Authentication, nie powinien być tam User?

0

Problem rozwiązany, temat do zamknięcia.
Wykorzystałem HandlerInterceptor, i sprawdzam przy każdym requeście czy role zostały zmienione.
Wydaje się to trochę nieoptymalne ale działa :)

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