【问题标题】:spring boot AuthenticationManager returns 403 every timespring boot AuthenticationManager 每次都返回 403
【发布时间】:2023-03-12 01:57:02
【问题描述】:

我是 Spring Security 新手,并试图在 Spring Boot Rest 服务上实现基本身份验证。我正在使用基于数据库的身份验证并拥有 User 和 Role 表。当我在我的应用程序中使用正确的凭据请求任何控制器时,它会给我总是 403 被禁止。我不知道为什么。我多次检查角色是正确的。在数据库中角色名称是“USER”和“RESTAURANT”和“ADMIN”。我尝试使用 ROLE_ 前缀和独立的大写语法方法不起作用。不知道我在做什么错。这是我的配置类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled=true,jsr250Enabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService customUserDetailsService;

    @Autowired
    private AuthenticationEntryPoint authEntryPoint;

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

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception
    {
        auth.userDetailsService(customUserDetailsService)
        .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .httpBasic()
            .authenticationEntryPoint(authEntryPoint)
            .and()
            .authorizeRequests()
            .antMatchers("/user/register","/forgotPassword").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
             ;
    }
    }

这是我的 UserDetailService 实现:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
        User user = userRepository.findByUsername(username);
        System.out.println(user.toString()); //here i check if it's finding right user 
        if (user == null) {
            throw  new UsernameNotFoundException(username +" not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user));
    }

    private static Collection<? extends GrantedAuthority> getAuthorities(User user)
    {
        String[] userRoles = user.getRoles()
                                    .stream()
                                    .map((role) -> role.getName())
                                    .toArray(String[]::new);
        Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(userRoles);
        return authorities;
    }
}

这是我返回 403 的控制器之一:

@PreAuthorize("hasRole('USER')")
    //@Secured("USER")
    @GetMapping("/{restaurantmenu}") //bütün menüyü çeker
    Collection<Menu> getMenu(@PathVariable("restaurantmenu") Long id) {
        return menuService.getMenuItemsByRestaurant(restaurantService.getRestaurant(id));
    }

为了您的信息。我有一个注册 url,所以我通过 json 获取新用户并使用加密(Bcrypt)密码将其注册到数据库中,我正在尝试使用它进行身份验证。我能够检索新用户并注册到 db 并正确加密密码。 我不知道我是否能够在以这种方式注册时控制用户名和电子邮件,但如果你关心这里的响应控制器方法:

@RestController
@RequestMapping(value="/user")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/register")
    void registerUser(@Valid @RequestBody User user) {
        userService.save(user);
    }
}

我们将不胜感激每一个帮助和建议。

【问题讨论】:

标签: spring rest spring-boot spring-security basic-authentication


【解决方案1】:

在数据库中将角色保存为 ROLE_USER、ROLE_ADMIN 并添加特定方法可能会对您有所帮助。

.antMatchers(HttpMethod.POST,"/user/register","/forgotPassword").permitAll()
.antMatchers(HttpMethod.GET,"/restaurantURL").permitAll()

编辑: Refer this to get more details on Roles

【讨论】:

  • 它确实有效!谢谢伙计,我只保存了带有 ROLE_ 前缀的角色并且可以工作,但我想知道为什么必须这样?为什么 spring security 不能只解析角色名称?
猜你喜欢
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 2017-10-07
  • 2015-08-21
  • 2019-02-26
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多