【问题标题】:why iam i getting 403 - forbidden为什么我得到 403 - 禁止
【发布时间】:2022-01-07 19:39:57
【问题描述】:

我正在从事 Spring Boot Security 项目,我在某些端点上进行了身份验证,以防止用户访问,并在我点击此 URL 时授予 ADMIN 权限:admin/users 我得到了登录页面,我输入了凭据而不是返回实际内容,而是返回 type=Forbidden, status=403

这是我的安全配置

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

    // inject spring user details interface
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("/api/**" , "/").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and().formLogin();
    }
    @Bean
    public BCryptPasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

}

管理员用户控制器

@RestController
@RequestMapping("admin/users")
public class UserController {
    //
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

   //  get all users
    @PreAuthorize("hasAnyRole('ADMIN')")
    @GetMapping
    public List<User> getAllUsers(){
        return userRepository.findAll();
    }

    // test
    @PreAuthorize("hasAnyRole('ADMIN')")
    @GetMapping("/test")
    public String message() {
        return "secured end point";
    }

    //create new users
    @PreAuthorize("hasAnyRole('ADMIN')")
    @PostMapping
    public User registerUser(@RequestBody  User user){
        
        String password = user.getPassword();
        String encodedPassword = passwordEncoder.encode(password);
        user.setPassword(encodedPassword);
        return userRepository.save(user);
    }
}

用户详情

public class CustomUserDetails implements UserDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1256711395932122675L;
    private User user;

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

    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

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

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }

}

userDetailsS​​ervice

[![@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

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

      if(user != null) {
        userDetail = new CustomUserDetail();
        userDetail.setUser(user);
      }
      else {
          throw new UsernameNotFoundException("user not exist with username " + username);
      }
        System.out.println("user details" + userDetail);
        return  userDetail;

    }
}][2]][2]

【问题讨论】:

  • 您的权威名称是什么? ADMINROLE_ADMIN 如果是第一次使用 hasAuthority 而不是 hasRole
  • 这里是我的 GrandAuthority 返回 user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
  • 这并不能回答我的问题,数据库中有什么。 ADMINROLE_ADMIN。如果您再次附加 ROLE_,它将以 ROLE_ROLE_ADMIN 结尾,这也不正确。
  • oh ok 在数据库中 ii 有两个角色,ADMIN 和 USER
  • 那么它应该可以工作,所以要么代码没有按照您的想法执行,要么您的角色不是您认为的那样。

标签: spring-boot spring-security


【解决方案1】:

我通过简单地纠正 getAuthorities() 解决了这个问题,我在 simpeGrantedAuthority() 中删除了“ROLE_”,将返回值提取到 userDetail.java 中的变量中,并使用 hasAuthority() 而不是 hasRole()

得到 403 的代码 - 禁止

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

    }

**解决方案**

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

        List<SimpleGrantedAuthority> authorities = user.getRoles().stream().map(role -> 
                        new SimpleGrantedAuthority(role.getRole()))
                .collect(Collectors.toList());
        return authorities;
    }

【讨论】:

    猜你喜欢
    • 2016-06-05
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多