【问题标题】:403 forbidden - Spring Security403 禁止 - Spring Security
【发布时间】:2020-12-18 16:47:44
【问题描述】:

我正在尝试使用 Spring 安全性来保护我的网站,但我不断收到 403 Forbidden 错误。我在网上看过很多帖子,但没有一个适合我的情况。

我正在使用 Springboot 构建后端 RESTapi,并且正在使用 Postman 对其进行测试。

我已禁用http.csrf().disable();,但403 error 仍然存在。

我可以访问所有用户都拥有许可的部分它还可以识别我是否输入了错误的凭据,但是当我尝试访问只有角色为 ADMINUSER 的用户可以访问的部分时,我立即出现以下错误。

{
    "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();
    }


}

CustomUserDetailsS​​ervice.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;
    }

}

用户控制器。爪哇

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

更新

当我用

调试部分代码时
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toSet());

我找回了我用来登录的用户...

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

【问题讨论】:

    标签: java spring-boot spring-security


    【解决方案1】:

    使用new SimpleGrantedAuthority("ROLE_" + role.getRole())) 代替new SimpleGrantedAuthority("ROLE_" + role))

    【讨论】:

      猜你喜欢
      • 2018-12-24
      • 2020-07-31
      • 2015-08-16
      • 2015-07-24
      • 2017-11-11
      • 2014-12-01
      • 2023-02-08
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多