简体   繁体   中英

403 forbidden - Spring Security

I'm trying to secure my website using Spring security but I am keep getting 403 Forbidden error. I have seen many posts online but none was applying for my situation.

I am building a backend RESTapi using Springboot and I am testing it with Postman.

I have disabled http.csrf().disable(); but still 403 error is there.

I can access part where all users have permition It also recognizes if I put bad credentials but when I try to access part where only user with role ADMIN or USER have access I immediately have following error.

{
    "timestamp": "2020-08-30T02:08:36.033+00:00",
    "status": 403,
    "error": "Forbidden",
    "message": "",
    "path": "/secure/auth/addUser"
 }

SecurityConfiguration.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(encodePWD());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();
        http
                .httpBasic()
                .and()
                .authorizeRequests()
                .antMatchers("/rest/**").permitAll()
                .and()
                .authorizeRequests()
                .antMatchers("/secure/**").hasAnyRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll();


    }

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


}

CustomUserDetailsService.java

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        CustomUserDetails userDetails = null;

        if(user != null){
            userDetails = new CustomUserDetails();
            userDetails.setUser(user);
        }else{
            throw new UserNotFoundException("User doesn't exist with this username: " + username);
        }
        return userDetails;

    }

}

CustomUserDetails.java

@Getter
@Setter
public class CustomUserDetails implements UserDetails {

    private User user;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toSet());

    }
    
    @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;
    }

}

UserController. java

@RequestMapping("/secure/auth/")
public class UserController {

 @Autowired
    private BCryptPasswordEncoder passwordEncoder;

 @PreAuthorize("hasAnyRole('ADMIN')")
    //POST method for adding one user
    @PostMapping("/addUser")
    public User addUser(@RequestBody User user){
        String pwd = user.getPassword();
        String encriptPwd = passwordEncoder.encode(pwd);
        user.setPassword(encriptPwd);
        return service.saveUser(user);
    }

//other code needed
}

BookContoller.java

@RestController
@RequestMapping("/rest/auth")
public class BookContoller {

    @Autowired
    private BookService service;

    //GET method display all books
    @GetMapping("/books")
    public List<Book> findAllBooks(){
        return service.getAllBooks();
    }

UPDATE

When I debug part of code with

return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toSet());

I get back User that I am using to log in...

User(id=1, name=chad, surname=huskins, username=chad, email=chad.huskins@gmail.com, password=$2a$10$SMH1T6fQ4HqzTAop.XOR/eDlfKzyjSkGGsT/qDCy1JYnncpdkqv32, roles=[Role(id=1, role=ADMIN)])

User.java

public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;
    private String surname;
    private String username;
    private String email;
    private String password;

    //@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    //private List<Rent> rent = new ArrayList<>();

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;
    
    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
}

Role.java

@Table(name = "Roles")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String role;
}

Use new SimpleGrantedAuthority("ROLE_" + role.getRole())) instead of new SimpleGrantedAuthority("ROLE_" + role))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM