Spring boot + security - problem z rolami

Spring boot + security - problem z rolami
P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

Witam,
tworzę w celach naukowych małą aplikację w spring boot i chcę do aplikacji dodać dwie role.

Moja klasa z konfiguracją security wygląda tak :

Kopiuj
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(
                "/registration",
                "/js/**",
                "/css/**",
                "/img/**",
                "/webjars/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and().rememberMe().key("uniqueAndSecret").userDetailsService(userService)
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
            .permitAll();
        http.csrf().disable();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService);
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

}

W widoku próbuję zrobić coś takiego jak poniżej jednak to nie działa i wszystko wyświetlane jest każdemu. Czy mógłby mi ktoś podpowiedzieć co tu może być nie tak ?

Kopiuj
   <div sec:authorize="hasRole('ROLE_ADMIN')">
            This content is only shown to administrators.
        </div>
        <div sec:authorize="hasRole('ROLE_USER')">
            This content is only shown to users.
        </div>
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
0

A pokaż swoją implementację UserService.

P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

To jest UserServiceImpl:

Kopiuj
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(email);
        if (user == null){
            throw new UsernameNotFoundException("Invalid username or password.");
        }
        return new org.springframework.security.core.userdetails.User(user.getEmail(),
            user.getPassword(),
            mapRolesToAuthorities(user.getRoles()));
    }

    public User findByEmail(String email){
        return userRepository.findByEmail(email);
    }

    public User save(UserRegistrationDto registration){
        User user = new User();
        user.setFirstName(registration.getFirstName());
        user.setLastName(registration.getLastName());
        user.setEmail(registration.getEmail());
        user.setPassword(passwordEncoder.encode(registration.getPassword()));
        user.setRoles(Arrays.asList(new Role("ROLE_USER")));
        return userRepository.save(user);
    }

    private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles){
        return roles.stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
    }
}
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
0

Jak się zalogujesz to wszystko wszystkim jest wyświetlane czy nawet bez logowania widzisz te div'y?

P0
Te div'y mam umieszczone w widoku do którego jest się przenoszonym po zalogowaniu. I wszystko jest wszystkim wyświetlane ;/
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
0

A czy taki sposób ewentualnie działa:

Kopiuj
sec:authorize="hasAuthority('ADMIN')

EDIT:
Zobacz jeszcze co Ci zwróci:

Kopiuj
<div sec:authentication="principal.authorities"></div>

Kiedyś kojarzę że czytałem jak te implementację Spring Security są zaimplementowane i bodajże ta metoda hasRole dodawała przedrostek ROLE_ więc może kwestia jest taka że po prostu gdzieś się to wywala z nazwami roli... Implementacja UserService wygląda okej, podobnie jest z konfigiem więc potestuj jeszcze "hasAuthority('ADMIN') albo "hasRole('ROLE_ADMIN')". Kojarzę że można było również zrobić tak:

Kopiuj
<sec:authorize access="hasRole('ROLE_ADMIN')">

Edit:
Rozumiem że taką zależność:

Kopiuj
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

masz dodaną do poma?

edytowany 4x, ostatnio: eL
P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

Niestety nie, bo też to już testowałem.
Dodatkowo przetestowałem również takie coś jak poniżej. Dodałem to w panelu do logowania, więc napis powinien być nie widoczny, ale wyświetlił się ;/

Kopiuj
   <div sec:authorize="isAuthenticated()">
                This content is only shown to authenticated users.
            </div>
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
0
  1. Zależność masz dodaną?
  2. Co zwraca Ci:
Kopiuj
<div sec:authentication="principal.authorities"></div>
P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0
  1. To jest mój plik pom.xml
Kopiuj
<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7-1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.30</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>
  1. Tekst się pojawia
EL
Ale co Ci to <div sec:authentication="principal.authorities"></div> zwraca ? Powinno wyświetlić role zalogowanego usera.
EL
Ps. Uruchom wszystko w trybie incognito albo pokasuje cookies i cache bo czasami coś starego potrafi się przykleić i trzymać przez jakiś czas.
P0
Aaaa, no to w takim razie nic mi nie wyświetliło.
P0
Cały czas testuję na trybie incognito
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
0

Jeśli nie wyświetliło Ci nic (a powinno wyświetlić listę roli tego usera) to sprawdz w debuggerze co Ci w takim razie zwraca ta linijka:

Kopiuj
 mapRolesToAuthorities(user.getRoles()));

Ten user na pewno w bazie ma dodane jakieś role? Sama implementacja metody mapRolesToAuthorities wygląda okej ale może przekazujesz tam pustą kolekcję...
Chociaż z drugiej strony jeśli user nie ma żadnej roli to też bezsensu że security wyświetla mu content dla admina... No ale nic, sprawdź tę metodę aby mieć pewność że security user jest tworzony poprawnie.
Przy okazji zrób clean'a projektu i zbuduj na nowo.

EDIT:
@pawlo00 Pokaż jeszcze początek pliku html jak robisz import tego "sec"

edytowany 3x, ostatnio: eL
P0
Ale gdzie tą linijkę dodać ?
EL
Ta linijka jest z Twojego kodu. W metodzie loadUserByUsername tworzysz security usera na podstawie swojego usera z bazy. Tam też wywołujesz tę linijkę więc nigdzie jej nie dodawać tylko w debuggerze sprawdź co Ci zwraca.
P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

To mi zwraca :

Kopiuj
user : "User(id=1, firstName=Test, lastname=test, email=test@gmail.com, password=$2a$10$FndsS43/.pJ1UBEGnexqxH5FxasWif365Fbl56FLBm, roles=[Role(id=2, name=ROLE_USER)])"
Zobacz pozostały 1 komentarz
EL
Która linijka to Ci zwraca? Bo to wygląda na user z Twojego db
EL
Pokaż dokładnie co zwraca ta linijka: mapRolesToAuthorities(user.getRoles())); Możesz to zrobić w debbugerze. Wstaw gdzieś tam na tworzeniu Usera breakpointa a potem zaznacz ten fragment -> PPM -> evaluate expression i zwróci Ci wywołanie dla tego fragmentu. Zobacz czy utworzone są poprawnie nazwy ról.
EL
Według powyższego hasAuthority powinno Ci bez problemu działać. Zobacz tylko czy masz Role_Admin czy Admin. Dodatkowo zobacz to: https://stackoverflow.com/a/53373249/5877109 bo tak jak wcześniej Ci pisałem, przedrostek Role jest automatycznie dodawany więc może po prostu gdzieś te nazwy Ci się rozjeżdżają.
P0
W bazie danych mam ROLE_USER i ROLE_ADMIN
P0
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

Tutaj jest screen, może będzie lepiej widać
http://pokazywarka.pl/hoxw6g/

Zobacz pozostałe 8 komentarzy
P0
Ale jakby tak było to i w bazie miał bym złe nazwy, a w bazie mam ROLE_ADMIN i ROLE_USER
EL
W bazie masz tak jak sam dodasz. Skoro robisz tak: user.setRoles(Arrays.asList(new Role("ROLE_USER"))); to takie nazwy będziesz miał w bazie.
EL
Btw. Robienie coś takiego new Role("ROLE_USER") też jest słabe bo tworzysz nową instancję ROLE_USER. Potem jak robisz inserta usera z taką rolą i ten obiekt roli nie ma żadnego ID to do bazy będzie dodawana nowa rola. Sprawdź to jeszcze ale moim zdaniem dodanie każdego usera powoduje dodanie nowej roli ROLE_USER. Jak chcesz to naprawić to zanim podstawisz tę rolę u tego usera to ją zaciągnij z bazy. Wówczas będziesz miał też ID i hibernate zrobi tam po prostu relacje bez dodawania nowego rekordu do roli.
P0
Tak, każde tworzenie nowego usera tworzy również nową rolę ;/
EL
Napisałem Ci przecież jak to poprawić. Zamiast tworzyć nową instancję roli, pobierają ja z bazy danych, np. rolerepository.findByName("ROLE_USER"); Dostajesz rolę i ją podstawiasz.
EL
  • Rejestracja:około 13 lat
  • Ostatnio:3 miesiące
2

Ehm, trochę się z tym nawalczyłem.
Myślę że to kwestia jakichś konfliktów z wersjami w twoim projekcie.
Zaaktualizuj sobie zależności:

Kopiuj
		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf-spring5</artifactId>
			<version>3.0.11.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity5</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>

thymeleaf-extras-springsecurity5 masz mieć w wersji 5
Potem po stronie widoku:

Kopiuj
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">

To robiąc takiego div'a:

Kopiuj
            <div sec:authorize="isAuthenticated()">
                This content is only shown to authenticated users.
            </div>

nie widze kontentu dopóki się nie zaloguje.
Nie sprawdzałem z rolami ale powinno wszystko już działać. Sprawdź i daj znać.

edytowany 1x, ostatnio: eL
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)