Czy istnieje możliwość wyciągnięcia danych użytkownika z sesji ale NIE w kontrolerze?

0

Cześć,

Potrzebuje wyciągnąć imię/nazwisko lub nick z obiektu Authentication/Principal lub SecurityContextHolder ( jak już użytkownik zaloguje się poprzez google, OpenID ) jednak nie działa mi to w klasie modelowej ( dostaję nulla ) - chcę w getterze od razu mieć nadane jego dane aby móc to wykorzystać w innym miejscu w aplikacji.
W taki sposób:

@RestController
public class TestController {
@GetMapping("/test2")
    public String test2(Authentication authentication) {
//  Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "Hello " + authentication.getName();
    } }

widzę, że mi wyrzuca dane jakie chcę ale czy jest jakaś alterantywa dla klas modelowych bez dodatkowych adnotacji/endpointów?

Czuję, że mam jakieś braki w znajomości w/w klas i po co/jak i do czego zostały stworzone; i lub że w klasie modelowej chcę to chyba zrobić bardzo brzydko :D

8
  1. Nie bardzo, bo przecież skądś te dane przychodzą (tutaj z thread local albo z requestu).
  2. Absolutnie NIE POWINIENEŚ PRÓBOWAĆ TAK ROBIĆ. Bierz to z requestu jako argument kontrolera i przekazuj dalej. Jest to jedyne logiczne i sensowne rozwiązanie. Cokolwiek innego (w tym używanie SecurityContextHolder i wyciąganie tego z thread local) to bardzo zły pomysł i bardzo łatwo się na tym wywalić.

Tutaj nie ma zadnej magii wbrew temu co niektórym się może wydawać. W kontrolerze te dane przychodzą razem z requestem. W przypadku SecurityContextHolder te dane są zapisane w thread local (co oczywiście przestanie działać jak przełączysz się na inny wątek...).

5

@Shalom prawdę pisze... ale dodam komentarz starego zgreda, niszczyciela dobrej zabawy w springu

Nawet jak ograniczysz magię i przekażesz w parametrze (dobry pomysł) to i tak problem ThreadLocala nie znika.

Jeśli gdzieś niżej (na serwisie) kontrolujesz dostęp przez @Secured to jeśli tylko przełączysz wątek to może to sprawdzanie security przestać działać.
Czyli to nie używanie ThreadLocal i branie z parametru to pomysł na przyszłość jak już będziecie te wszystkie serwisy przepisywać ze Springa na coś normalnego - będzie trochę mniej pracy. Na szczęście też mało kto korzysta z wątków - więc problemy są raczej rzadkością. Nie po to mamy przecież wszystkie te nowe procki z fifnastoma rdzeniami, żeby z tego od razu korzystać, jak jacyś narwańcy.

0

@Shalom: hm, mam takiego potworka:

    @GetMapping(value = "/username")
    public String currentUserName(HttpServletRequest request) {
        Principal principal = request.getUserPrincipal();
        return principal.getName();
    }

Ale jak w klasie modelowej zainicjować HttpServletRequest jako argument currentUserName żeby nie rzucał nullem? Czy ja to w ogóle dobrze zrozumiałem?

2

W ogóle nic nie zrozumiałeś. Czy ty chcesz ręcznie wywołać metodę kontrolera? o_O Ty w ogóle rozumiesz jak działa HTTP i co próbujesz zrobic? Przecież to nie ma najmniejszego sensu. Przecież ten twój, pożal sie Boże, obiekt modelowy to tworzysz SAM w odpowiedzi na request który przechodzi przez kontroler. Weź w takim razie w TAMTYM KONTROLERZE daj sobie Principal jako jeden z argumentów i problem z głowy.
Pokaż może konkretnie ten kod w którym jest problem i nie możesz się dostać do principala?

0

@Shalom: chciałem ręcznie wywołać metodę kontrolera w klasie modelowej:

public class User {

    private GetUserNameFromHttpServletRequest user = new GetUserNameFromHttpServletRequest();
    private HttpServletRequest request; // <- jak tutaj zrobić by nie było nulla

    public String getUser() {
        return user.currentUserName(request);
    }
}

oj, coś czuję, że ten mój pomysł jest cały do kosza :D

1

@Sasori jeszcze raz: czy ty rozumiesz co to jest HTTP i jak działa? :D Przychodzi request do aplikacji i tylko wtedy można w ogóle mówić o jakimś userze. Co więcej przecież userów może być milion i każdy wyśle request do aplikacji w tym samym czasie i jak wtedy ten twój kod ma działać? :D

0
<snarky> sumarycznie 40 lat expa w javce w tym wątku, a zagadka OPa dalej nierozwiązana, huh? </snarky>
0

@Shalom: Ale user już jest zalogowany poprzez OpenId więc te dane da się wyciągnąć tylko nie wiem jak :D czas chyba zobaczyć na przykładzie jakimś jak działa HTTP, a nie tylko w teorii :)

3

Ale user już jest zalogowany poprzez OpenId

Zalogowany gdzie? Przecież to znaczy tylko tyle że ma token i wysyła ten token razem z requestem http a ty możesz sprawdzić jego poprawność. Ale to sie dzieje tylko w czasie obsługi requestu kiedy masz dostęp do tego tokena!
Mam wrażenie ze ty traktujesz zalogowanie jako jakąś magiczną operacje po której aplikacja za pomocą jakichś czarów wie nagle którego usera obsługuje, a to nie ma nic wspólnego z rzeczywistością. Do aplikacji razem z requestem przychodzi token jwt, albo session cookie albo jeszcze coś innego i na tej podstawie aplikacja wie jak dany request obsługiwać i dla kogo.
Poza zasięgiem requestu w ogóle nie można mówić o użytkowniku bo niby jak?

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