Kolejny raz przekonuję się, że Spring Security to kombajn, w którym teoretycznie każdy komponent można podmienić, ale są tak ze sobą powiązane, że chcąc coś zrobić inaczej, trzeba przepisać połowę komponentów.
Udało mi się nieco okiełznać klienta OAuth2:
1. Tworząc filtr, który na podstawie nagłówka X-USER-ID utworzy obiekt Authentication - otóż SS nie akceptuje anonimowych klas Authentication ani jak przekażemy #!$%@? w formie ciągu znaków przy ręcznym utworzeniu OAuth2AuthorizeRequest.
2. Dostosowując aplikację do Redirect URI (niestety jest on weryfikowany w usłudze, z którą się łączę i nie mogę zmienić) - otóż SS weryfikuje go w OAuth2AuthorizationCodeGrantFilter i jeśli się nie zgadza, to zamiast strzelić po token, to od nowa przekierowuje do serwera uwierzytelniania. No i jak tu robić testy na różnych środowiskach, w których adres będzie się trochę różnił? No ostatecznie można nadpisać OAuth2AuthorizationCodeGrantFilter i wyrzucić weryfikację Redirect URI.
3. Jeśli stworzę filtr, który podmieni Redirect URI w zapisanym w sesji requeście, to błędny Redirect URI pójdzie w strzale po token i zwróci błąd.
4. Można też podmienić HttpSessionOAuth2AuthorizationRequestRepository, żeby requesty trzymał w bazie, a nie w sesji (bo co w przypadku wielu instancji aplikacji, które będą mieć osobne sesje?)
5. Żeby spring użył Authorization Code with PKCE, to trzeba usunąć z konfiguracji client-secret i ustawić client-authentication-method: NONE
6. Aby przechowywać tokeny w bazie, to jest o tym sekcja w dokumentacji, więc nie będzie z tym dużego problemu - a może będzie, bo nie używam relacyjnej bazy, lecz NoSQL - do sprawdzenia, czy zadziała z taką bazą (wymóg klienta)
Czyli tak w skrócie z czym mam problem:
1. Weryfikacja Redirect URI w SS - można to obejść jak wyżej 2. Aplikacja może mieć wiele instancji i jedna może przekierować użytkownika, a druga strzelać po token - patrz pkt 4 wyżej
Nie wiem, czy dalej w to brnąć, czy pisać własną implementację OAuth. Nie jest to trudne, ale trzeba ręcznie dbać też o odświeżanie tokenów. Zamiast filtrów SS miałbym konkretny endpoint, w którym zawarłbym logikę i przynajmniej bym wiedział, co się dzieje.
1. jaki jest sens walidacji redirect URI? 2. nie wiem co do końca chcesz osiągnąć taką implementacją, ale chyba idziesz w aplikację stateful zamiast stateless
Szanuję za wytrwałość, ale obawiam się, że większość rzeczy, o których piszesz SS od wersji 5.0 rozwiązuje out-of-the-box
@SendMeAnAngel: albo źle zrozumiałem ale mam wrażenie że mocno tu wszystko przekombinowane. Po co trzymać requesty i tokeny w bazie? Nie korzystasz z profili z odpowiednią konfiguracją pod środowisko, a w ogóle to musisz wadlidować redirect?
@SendMeAnAngel: zacząłbym od weryfikacji czy na pewno potrzebujesz spring-security-oauth2-client, czy może wystarczy ci spring-security-oauth2-resource-server. W każdym razie:
1. Tworząc filtr, który na podstawie nagłówka X-USER-ID utworzy obiekt Authentication - otóż SS nie akceptuje anonimowych klas Authentication ani jak przekażemy #!$%@? w formie ciągu znaków przy ręcznym utworzeniu OAuth2AuthorizeRequest.
Jaki jest Use Case tego customowego headera? Jeżeli chcesz mieć dwa flow uwierzytelnienia - jeden OAuthowy (np. code grant), a drugi na podstawie
Generalnie brzmi jakbyś strasznie kombinował. Opisz bardziej architekturę i potrzeby. Generalnie Spring wyciąga Redirect URI na podstawie properties, czyli możesz to ustawić zmiennymi środowiskowymi, więc różne Client/Resource Servery mogą integrować się z jednym Authorization Serverem, a powrót do "dobrego" środowiska (nie koniecznie instancji, bo sesje można wspołdzielić) ogarnąć ENVem
Celem jest napisanie komunikacji z zewnętrzną usługą w imieniu konkretnego użytkownika. Czyli użytkownik loguje się w tej usłudze i wyraża zgodę na dostęp do swoich danych lub wykonywania pewnych czynności. Chodzi o coś takiego jak jest na Facebooku, kiedy zezwalasz innej aplikacji na dostęp do twojego konta. Potem aplikacja może sama uzyskać dostęp do usługi, mając ważny token.
@SendMeAnAngel: moim zdaniem za duży margines błędu dotyczący bezpieczeństwa jest używając Spring Security, jaka masz pewność że zabdasz o każdy corner case? Nie wiem jak to wygląda ale na AWSie już się nie używa Spring Security tylko korzysta z gotowych komponentów, tak samo z innymi rozwiązaniami jak istio ale szanuje za wytrwałość ( ͡°͜ʖ͡°)
Udało mi się nieco okiełznać klienta OAuth2:
1. Tworząc filtr, który na podstawie nagłówka X-USER-ID utworzy obiekt Authentication - otóż SS nie akceptuje anonimowych klas Authentication ani jak przekażemy #!$%@? w formie ciągu znaków przy ręcznym utworzeniu OAuth2AuthorizeRequest.
2. Dostosowując aplikację do Redirect URI (niestety jest on weryfikowany w usłudze, z którą się łączę i nie mogę zmienić) - otóż SS weryfikuje go w OAuth2AuthorizationCodeGrantFilter i jeśli się nie zgadza, to zamiast strzelić po token, to od nowa przekierowuje do serwera uwierzytelniania. No i jak tu robić testy na różnych środowiskach, w których adres będzie się trochę różnił? No ostatecznie można nadpisać OAuth2AuthorizationCodeGrantFilter i wyrzucić weryfikację Redirect URI.
3. Jeśli stworzę filtr, który podmieni Redirect URI w zapisanym w sesji requeście, to błędny Redirect URI pójdzie w strzale po token i zwróci błąd.
4. Można też podmienić HttpSessionOAuth2AuthorizationRequestRepository, żeby requesty trzymał w bazie, a nie w sesji (bo co w przypadku wielu instancji aplikacji, które będą mieć osobne sesje?)
5. Żeby spring użył Authorization Code with PKCE, to trzeba usunąć z konfiguracji client-secret i ustawić client-authentication-method: NONE
6. Aby przechowywać tokeny w bazie, to jest o tym sekcja w dokumentacji, więc nie będzie z tym dużego problemu - a może będzie, bo nie używam relacyjnej bazy, lecz NoSQL - do sprawdzenia, czy zadziała z taką bazą (wymóg klienta)
Czyli tak w skrócie z czym mam problem:
1. Weryfikacja Redirect URI w SS - można to obejść jak wyżej
2. Aplikacja może mieć wiele instancji i jedna może przekierować użytkownika, a druga strzelać po token - patrz pkt 4 wyżej
Nie wiem, czy dalej w to brnąć, czy pisać własną implementację OAuth. Nie jest to trudne, ale trzeba ręcznie dbać też o odświeżanie tokenów. Zamiast filtrów SS miałbym konkretny endpoint, w którym zawarłbym logikę i przynajmniej bym wiedział, co się dzieje.
#spring #springsecurity #java #programowanie
1. jaki jest sens walidacji redirect URI?
2. nie wiem co do końca chcesz osiągnąć taką implementacją, ale chyba idziesz w aplikację stateful zamiast stateless
Szanuję za wytrwałość, ale obawiam się, że większość rzeczy, o których piszesz SS od wersji 5.0 rozwiązuje out-of-the-box
Po co trzymać requesty i tokeny w bazie? Nie korzystasz z profili z odpowiednią konfiguracją pod środowisko, a w ogóle to musisz wadlidować redirect?
Jaki jest Use Case tego customowego headera? Jeżeli chcesz mieć dwa flow uwierzytelnienia - jeden OAuthowy (np. code grant), a drugi na podstawie
Generalnie brzmi jakbyś strasznie kombinował. Opisz bardziej architekturę i potrzeby. Generalnie Spring wyciąga Redirect URI na podstawie properties, czyli możesz to ustawić zmiennymi środowiskowymi, więc różne Client/Resource Servery mogą integrować się z jednym Authorization Serverem, a powrót do "dobrego" środowiska (nie koniecznie instancji, bo sesje można wspołdzielić) ogarnąć ENVem
@whoru: Integruję się z zewnętrzną usługą