Search code examples
springsecurityspring-securityhttp-postspring-boot-admin

cannot make the POST request. Shows ststus 404 page not found


I am a new in Spring Security and I met the problem that when I rey to add a new User in my web interfase I receive that page not found. If I remove authentication I receive that I have no priveges to make post request.

Please, help to understand the problem. May be I try to look for problem not in right way....

here is my SecurityConfig file :

package com.fuji.inventory.fujiInv.configurations;

import jakarta.servlet.DispatcherType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Slf4j
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Autowired
    private CustomUserDetailsService customUserDetailsService;

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

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http

                .authorizeHttpRequests(auth -> auth
//   -------------------- Access to all API
                                .requestMatchers(HttpMethod.GET, "/**").hasAnyRole("ADMIN", "USER")
//   -------------------- Access for API ASSETS
                                .requestMatchers(HttpMethod.POST, "/assets/**", "/users/create").hasRole("ROLE_ADMIN")
                                .requestMatchers(HttpMethod.DELETE, "/assets/**", "/users/delete/{id}").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/assets/**", "/users/create").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/assets/**", "/users/create").hasRole("ADMIN")
//   -------------------- Access for API USERS
                                .requestMatchers(HttpMethod.DELETE, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.POST, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/users/**").hasRole("ADMIN")
                                .anyRequest()
////   -----------permit all without authentication
////                .permitAll()
////   -----------configure authentication
                                .authenticated()
                )
                .formLogin()
                .and()
                .exceptionHandling()
                .accessDeniedPage("/accessDennie")
                .and()
                .authenticationProvider(authenticationProvider())
                .build();
    }
    @Bean
    AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(this.customUserDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setHideUserNotFoundExceptions(true);
        return daoAuthenticationProvider;
    }
}

here is my CustomUsersDetails file:

package com.fuji.inventory.fujiInv.configurations;
import com.fuji.inventory.fujiInv.models.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.*;

public class CustomUserDetails implements UserDetails {

    private final User user;
    private final String username;
    private final String password;
    private final boolean active;

    public CustomUserDetails(User user) {
        this.user = user;
        username = user.getUsername();
        password = user.getPassword();
        active = user.isActive();
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        //list of permissions (name)
        this.user.getPermissionsList().forEach(p -> {
            GrantedAuthority authority = new SimpleGrantedAuthority(p);
            authorities.add(authority);
        });

        //list of roles (ROLE_name)
        this.user.getRoleList().forEach(r -> {
            GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+r);
            authorities.add(authority);
        });

        return authorities;

    }

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

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

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

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

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

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

here is my UserController file :

package com.fuji.inventory.fujiInv.controllers;

import com.fuji.inventory.fujiInv.models.User;
import com.fuji.inventory.fujiInv.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;


@Controller
@RequiredArgsConstructor
public class UserController {

    @Autowired
    private final UserService userService;

    @GetMapping("/login")
    public String login(){
        return "login";
    }
    @GetMapping("/user-add")
    @PreAuthorize("hasRole('ADMIN')")
    public String users(@RequestParam(name = "usersModel", required = false) String usersModel,
                        Model model
    ){

        model.addAttribute("users", userService.usersModel(usersModel));
        model.addAttribute("currentUserEmail", currentUserMail());
        return("/add-user");
    }

    @GetMapping("/user/{username}")
    @PreAuthorize("hasRole('ADMIN')")
    public String userInfo(@PathVariable String username, Model model){
        User userInfo = userService.getUserByUserName(username);
        model.addAttribute("userInfo", userInfo);
        return "user-info";
    }
//    @GetMapping("/users/{id}/edition")
//    @PreAuthorize("hasRole('ADMIN')")
//    public String updateUser(@PathVariable Long id, Model model){
//        User user = userService.getUserById(id);
//        return "/add-user";
//    }

    @PostMapping("/users/create")
    @PreAuthorize("hasRole('ADMIN')")
    public String createUser(User user, Model model){
        if(!userService.createUser(user)){
                model.addAttribute("userAddError", "User with same data "+user+" already exists!");
            return "redirect:/add-user";
        }
        userService.saveUser(user);
        model.addAttribute("user_added", "New User added successfully!");
       return "redirect:/add-user";
    }




    @PostMapping("/users/delete/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public String deleteUser(@PathVariable Long id){
        userService.deleteUser(id);
        return "redirect:/add-user";
    }

    @GetMapping("/access-dennied")
    public String accessDennied(){
        return "accessDennie";
    }
    public String currentUserMail(){
        return "@eu.fujikura.com";
    }
}

here is my USEr entity :

package com.fuji.inventory.fujiInv.models;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


@Entity
@Table(name = "users")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long id;
    @Column(name = "username", unique = true)
    @NonNull
    private String username;
    @Column(name = "email", unique = true)
    @NonNull
    private String email;
    @Column(name = "isActive")
    private boolean isActive;
    @Column(name = "password")
    @NonNull
    private String password;
    @Column(name = "roles")
    private String roles;
    @Column(name = "permissions")
    private String permissions;
    @Column(name = "creationDate")
    @NonNull
    private LocalDateTime creationDate;
    @Column(name = "department")
    @NonNull
    private String department;
    @Column(name = "plant")
    @NonNull
    private String plant;

    @PrePersist
    private void init() {
        creationDate = LocalDateTime.now();
    }


    public List<String> getRoleList(){
        if(this.roles.length()>0){
            return Arrays.asList(this.roles.split(","));
        }
        return new ArrayList<>();
    }

    public List<String> getPermissionsList(){
        if (this.permissions.length()>0){
            return Arrays.asList(this.roles.split(","));
        }
        return new ArrayList<>();
    }

}

I can make a GET requests. I can access all the pages...but I cannot create new records in DB. I receive the message that page not found, but all the routes are specified normally.

enter image description here

I tried to disable the authentication, I tried to enable authentication.

I tried this option :

.authorizeHttpRequests(auth -> auth
//   -------------------- Access to all API
                                .requestMatchers(HttpMethod.GET, "/**").hasAnyRole("ADMIN", "USER")
//   -------------------- Access for API ASSETS
                                .requestMatchers(HttpMethod.POST, "/assets/**", "/users/create").hasRole("ROLE_ADMIN")
                                .requestMatchers(HttpMethod.DELETE, "/assets/**", "/users/delete/{id}").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/assets/**", "/users/create").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/assets/**", "/users/create").hasRole("ADMIN")
//   -------------------- Access for API USERS
                                .requestMatchers(HttpMethod.DELETE, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.POST, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/users/**").hasRole("ADMIN")
                                .anyRequest()
////   -----------permit all without authentication
////                .permitAll()
////   -----------configure authentication
                                .authenticated()
                )

I tried this option :

.authorizeHttpRequests()
//   -------------------- Access to all API
                                .requestMatchers(HttpMethod.GET, "/**").hasAnyRole("ADMIN", "USER")
//   -------------------- Access for API ASSETS
                                .requestMatchers(HttpMethod.POST, "/assets/**", "/users/create").hasRole("ROLE_ADMIN")
                                .requestMatchers(HttpMethod.DELETE, "/assets/**", "/users/delete/{id}").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/assets/**", "/users/create").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/assets/**", "/users/create").hasRole("ADMIN")
//   -------------------- Access for API USERS
                                .requestMatchers(HttpMethod.DELETE, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.POST, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PATCH, "/users/**").hasRole("ADMIN")
                                .requestMatchers(HttpMethod.PUT, "/users/**").hasRole("ADMIN")
                                .anyRequest()
////   -----------permit all without authentication
////                .permitAll()
////   -----------configure authentication
                                .authenticated()
                ```


Solution

  • The problem was solved bye adding .csrf().disable() in a SecurityConfig file.

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            return http
    
    
                    .csrf().disable()
                    .authorizeHttpRequests(auth -> auth
    //   -------------------- Access to all API
                                    .requestMatchers(HttpMethod.GET, "/**").hasAnyRole("ADMIN", "USER")
    //   -------------------- Access for API ASSETS
                                    .requestMatchers(HttpMethod.POST, "/assets/**", "/users/create").hasRole("ROLE_ADMIN")
                                    .requestMatchers(HttpMethod.DELETE, "/assets/**", "/users/delete/{id}").hasRole("ROLE_ADMIN")
    

    but comment about wrong route of access dennied page was also usefull.

    I have tottaly forgot about token.

    Thanks!