Получение кода состояния 302 при попытке входа в систему с использованием настраиваемой формы с использованием Spring Security в приложении Spring Boot - PullRequest
0 голосов
/ 07 мая 2020
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.snippets</groupId>
    <artifactId>SpringSnippets</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringSnippets</name>
    <description>Sample snippets for using in a project</description>

    <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.security</groupId>
            <artifactId>spring-security-web</artifactId>

        </dependency>
        <!-- spring-security-config -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>

        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </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>

</project>




     @Controller
     public class ViewController {

    @Autowired UserService userService;

    @GetMapping("/user/login")
    public String showLogin() {
        return "login.html";
    }

    @GetMapping("/")
    public String home() {

        return "home.html";
    }


    @GetMapping(value = "/loginFailed")

    public String loginError(Model model) {

        model.addAttribute("error", "true");

        return "login";

    }

    @GetMapping(value = "/logout")

    public String logout(SessionStatus session) {

        SecurityContextHolder.getContext().setAuthentication(null);

        session.setComplete();

        return "redirect:/welcome";

    }

    @GetMapping("/registration")
    public String showRegistrationForm(Model model) {

        UserDto userDto = new UserDto();
        model.addAttribute("user", userDto);
        return "register.html";
    }

    @PostMapping(value = "/postLogin")

    public String postLogin(Model model, HttpSession session) {


        // read principal out of security context and set it to session

        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

        validatePrinciple(authentication.getPrincipal());

        User loggedInUser = ((PdfUserDetails) authentication.getPrincipal()).getUserDetails();

        model.addAttribute("currentUser", loggedInUser.getUserName());

        session.setAttribute("userId", loggedInUser.getId());

        return "register.html";

    }

    private void validatePrinciple(Object principal) {

        if (!(principal instanceof PdfUserDetails)) {

            throw new  IllegalArgumentException("Principal can not be null!");

        }

    }


    @PostMapping("/registration/confirm")
    public String registerUserAccount( UserDto user) {

        ModelAndView mav = new ModelAndView();

        try {
            userService.registerNewUserAccount(user);
        } catch (UserExistsException uaeEx) {
            mav.addObject("message", "An account for that username/email already exists.");
        }

        return "login.html";
    }
}




    @Configuration
     @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired UserDetailsService userDetailsService;

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService);
    }

    @Bean

    public UserDetailsService userDetailsService() {

        return new UserLoginService();

    }



    @Bean

    public DaoAuthenticationProvider authenticationProvider() {

        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

        authProvider.setUserDetailsService(userDetailsService());

        authProvider.setPasswordEncoder(passwordEncoder());

        return authProvider;

    }

     @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http
              .csrf().disable()
              .authorizeRequests()
              .antMatchers("/css/**", "/js/**", "/images/**").permitAll()
              .antMatchers("/registration").permitAll()

              .anyRequest().authenticated()
              .and()
              .formLogin()
              .loginPage("/user/login")
              .defaultSuccessUrl("/", true).permitAll()
              .and()
              .logout()
              .logoutUrl("/logout")
              .logoutSuccessUrl("/user/login")
              .permitAll();
        }

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





     @Service
      @Transactional
      public class UserLoginService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        Optional<User> user = userRepository.findByUserName(userName);

        if (user == null)
            throw new UsernameNotFoundException("No user found with username: " + userName);



        return new PdfUserDetails(user.get());

    }

}





     public class PdfUserDetails implements UserDetails {


    private static final long serialVersionUID = 1L;
    private User user;

    public PdfUserDetails(User user) {

        this.user = user;

    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

            List<GrantedAuthority> l1 = new ArrayList<GrantedAuthority>();
            l1.add(new SimpleGrantedAuthority(this.user.getRole()));

            return l1;
    }

    public Long getId() {

        return user.getId();

    }

    @Override

    public String getPassword() {

        return user.getPassword();

    }

    @Override

    public String getUsername() {

        return user.getUserName();

    }

    @Override

    public boolean isAccountNonExpired() {

        return true;

    }

    @Override

    public boolean isAccountNonLocked() {

        return true;

    }

    @Override

    public boolean isCredentialsNonExpired() {

        return true;

    }

    @Override

    public boolean isEnabled() {

        return true;

    }

    public User getUserDetails() {

        return user;

    }

}


<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

    <link rel="stylesheet" th:href="@{/css/login.css}">
</head>

<body>

    <div class="container">
        <div class="row justify-content-center">
            <div class="col-4">
                <form class="form-group" action="/postLogin" th:object="${user}" method="POST" enctype="utf8">
                  <h5  class="text-center text-info mb-2">  <label for="">Login</label></h5>
                    <div class="input-group my-2">
                        <div class="input-group-prepend">
                            <span class="input-group-text"><i class="fa fa-user"></i></span>
                        </div>
                        <input name="username" type="text" class="form-control" placeholder="Username">

                    </div>

                    <div class="input-group my-2">
                        <div class="input-group-prepend">
                            <span class="input-group-text"><i class="fa fa-unlock"></i></span>
                        </div>
                        <input name="password" type="password" class="form-control" placeholder="Password">
                    </div>


                    <button class="btn btn-outline-danger my-2 mx-5">Cancel</button>
                    <button class="btn btn-outline-success my-2 mx-2">Login</button>
                    <h6 class="text-center mt-3"><label for="">Not a member? <a th:href="@{/registration}">Signup</a></label></h6>
                </form>
            </div>
        </div>
    </div>

</body>

</html>

Я получаю сообщение об ошибке статуса 302 при попытке входа в систему с помощью настраиваемой формы, пожалуйста, помогите в решении проблемы. Я везде проверял и не могу понять, что не так. Я пытаюсь использовать безопасность Spring с помощью UserDetailsService, используя mysql db. В весенних документах процедура также не очень четко прописана, и я не могу решить проблему.

1 Ответ

0 голосов
/ 07 мая 2020

Статус 302 не ошибка, а информация о редиректе. Узнать больше traling .html из методов, которые возвращают представление в классах, аннотированных @Controller just return "login"; et c.

...