Конфигурация Springboot Web Security не перенаправляет на страницу входа - PullRequest
0 голосов
/ 19 февраля 2020

Я создал небольшое приложение для изучения веб-безопасности при загрузке спринта. Пример приложения в основном основан на частичных инструкциях, приведенных в книге «Spring Boot in Action».

Проблема, с которой я сталкиваюсь, заключается в том, что, несмотря на настройку доступа, как показано ниже, при открытии http://localhost: 8080 / reader / ishwar приложение не может перейти на страницу входа. Сразу открывается страница, представленная http://localhost: 8080 / reader / ishwar . Насколько я понял безопасность пружины, если применяется .access (""), то для проверки доступа по умолчанию пружина должна перенаправить пользователя на страницу входа. Но это не так.

package com.example.readingList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ReaderRepository readerRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.
                authorizeRequests()
                    .antMatchers("/readers").access("hasRole('READER')")
                    .antMatchers("/login").permitAll()
                .and()
                    .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .failureUrl("/login?error=true");

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                return readerRepository.getOne(username);
            }
        });
    }
}

НО , если я изменю код на ниже, то при просмотре http://localhost: 8080 / reader / ishwar я перенаправлюсь на страница авторизации. Что не так в первой конструкции? Я имею в виду, почему .access ("") не работает

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ReaderRepository readerRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.
                authorizeRequests()
                    .anyRequest().authenticated()
                .and()
                    .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .failureUrl("/login?error=true");

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                return readerRepository.getOne(username);
            }
        });
    }
}

Ниже показано, как написано ReaderRepository

package com.example.readingList;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReaderRepository extends JpaRepository<Reader, String> {

}

Ниже представлен класс Reader. Я намеренно предоставил роль «ПИСАТЕЛЬ», так как хочу видеть, что попытка доступа к странице должна завершиться неудачей, так как отсутствует разрешение READER. Но как таковой, даже если я включаю разрешение «ЧИТАТЕЛЬ», в поведении нет никаких изменений.

package com.example.readingList;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Arrays;
import java.util.Collection;

@Entity
public class Reader implements UserDetails {

    private static final long serialVersionUID = 1L;

    @Id
    private String username;
    private String password;
    private String fullname;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("WRITER"));
    }

    //@Override
    public String getPassword() {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    //@Override
    public String getUsername() {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getFullname()
    {
        return fullname;
    }

    public void setFullname(String fullname)
    {
        this.fullname = fullname;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

Пожалуйста, обратите внимание, что я не реализовал источник данных для хранения / извлечения пользователя и пароля. Я ожидал увидеть по крайней мере перенаправление на http://localhost: 8080 / login первым, но не произойдет, если я использую первую конструкцию.

Ниже мой pom. xml file

https://maven.apache.org/xsd/maven-4.0.0.xsd "> 4.0.0

<groupId>com.example</groupId>
<artifactId>readingList</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>readingList</name>
<description>Reading List project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <java.version>1.8</java.version>
</properties>

<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-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Класс ReadingListApplication

@Configuration
@SpringBootApplication
public class ReadingListApplication implements WebMvcConfigurer
{

    public static void main(String[] args) {
        SpringApplication.run(ReadingListApplication.class, args);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}

Класс ReadingListController

package com.example.readingList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class ReadingListController {
    private ReadingListRepository readingListRepository;

    @Autowired
    public ReadingListController(ReadingListRepository readingListRepository)
    {
        this.readingListRepository = readingListRepository;
    }

    @RequestMapping(value="/readers/{reader}", method= RequestMethod.GET)
    public String readersBook(@PathVariable("reader") String reader, Model model)
    {
        List<Book> readingList = readingListRepository.findByReader(reader);
        if (readingList.isEmpty() == false) {
            model.addAttribute("books", readingList);
        }
        return "readingList";
    }

    @RequestMapping(value="/readers/{reader}", method= RequestMethod.POST)
    public String addToReadingList(@PathVariable("reader") String reader, Book book)
    {
        book.setReader(reader);
        readingListRepository.save(book);
        return "redirect:/readers/{reader}";
    }
}

1 Ответ

0 голосов
/ 19 февраля 2020

Это связано с AntPathRequestMatcher. В первом примере вызов .antMatchers("/readers").access("hasRole('READER')") не будет соответствовать /readers/ishwar.

Конечно, authorizeRequests().anyRequest().authenticated() будет, поэтому вы получаете другое поведение.

Попробуйте выполнить следующее:

http.antMatchers("/readers/**")
        .access("hasRole('READER')")
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...