Spring boot + security - problem z rolami

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 :

@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 ?

   <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>
0

A pokaż swoją implementację UserService.

0

To jest UserServiceImpl:

@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());
    }
}
0

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

0

A czy taki sposób ewentualnie działa:

sec:authorize="hasAuthority('ADMIN')

EDIT:
Zobacz jeszcze co Ci zwróci:

<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:

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

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

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

masz dodaną do poma?

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ę ;/

   <div sec:authorize="isAuthenticated()">
                This content is only shown to authenticated users.
            </div>
0
  1. Zależność masz dodaną?
  2. Co zwraca Ci:
    <div sec:authentication="principal.authorities"></div>
0
  1. To jest mój plik pom.xml

    <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>
  2. Tekst się pojawia

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:

 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"

0

To mi zwraca :

user : "User(id=1, firstName=Test, lastname=test, [email protected], password=$2a$10$FndsS43/.pJ1UBEGnexqxH5FxasWif365Fbl56FLBm, roles=[Role(id=2, name=ROLE_USER)])"

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