当前位置: 首页 > 知识库问答 >
问题:

Spring Security: hasAuthorize, hasRole和PreAuthorize不工作

林玮
2023-03-14

我正在尝试测试使用标准Spring Security注释和方法保护的web api。我查看了网站上的所有选项,没有任何帮助,下面是代码。没有角色,一切都很好。我为这个问题痛苦了好几天。我会感谢你的帮助,谢谢。

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

    @Autowired
    private UserDetailsServiceImp userDetailsService;

    @Autowired
    JwtFilter jwtFilter;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST,"/authenticate").permitAll()
                .antMatchers(HttpMethod.GET,"/userData").permitAll()
                .antMatchers(HttpMethod.GET,"/allUsers").hasAuthority("ROLE_ADMIN")
                .anyRequest().authenticated()
                .and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint())
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
                http.addFilterAfter(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

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

控制器类

@RestController
public class AuthenticationController {

    @Autowired
    public AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImp userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserRepository userRepository;


    @RequestMapping(value = "/userData", method = RequestMethod.GET)
    public String hello(){
        return "Hello new User";
    }

    @RequestMapping(value = "/allUsers", method = RequestMethod.GET)
    public List<UserD> findAll(){
        return userRepository.findAll();
    }

    @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest jwtRequest) throws Exception{
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(jwtRequest.getName(), jwtRequest.getPassword()));
        }catch(BadCredentialsException e){
            throw new Exception("Incorrect username and password", e);
            }
        final UserD userD = (UserD)userDetailsService.loadUserByUsername(jwtRequest.getName());

        final String token = jwtUtil.generateToken(userD.getName(), userD.getRole());

        Map<Object, Object> model = new HashMap<>();
        model.put("username", jwtRequest.getName());
        model.put("token", token);

        return ResponseEntity.ok(model);
    }
}

如果antMatcher(Httpmethod.GET,"/allUser"). permitAll(),然后它返回用户,因为它应该

UserDetailsServiceImp

@Service
public class UserDetailsServiceImp implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userRepository.findByName(username).get(0);
    }
}

和添加角色的用户数据

@Component
public class DataInitializer implements CommandLineRunner {

    @Autowired
    UserRepository userRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public void run(String... args) throws Exception {
        UserD user = new UserD();
        user.setName("user");
        user.setPassword(passwordEncoder.encode("password"));
        user.setRole("ROLE_USER");
        userRepository.save(user);

        UserD admin = new UserD();
        admin.setName("admin");
        admin.setPassword(passwordEncoder.encode("password"));
        admin.setRole("ROLE_ADMIN");
        userRepository.save(admin);
     }
}

这是数据库返回的内容

共有1个答案

陶睿
2023-03-14

我想先澄清一些事情,这可能有助于你确定问题:

UserDetailsServiceImp是否从数据库、LDAP或其他存储库检索用户名和角色?从html" target="_blank">数据库、LDAP或其他存储库检索什么角色?它是否已经有前缀“ROLE_u”?

如果从数据库中检索到的角色是“ADMIN”,则在调用hasAuthority()时,不能自行添加角色。

.antMatchers(HttpMethod.GET,"/allUsers").hasAuthority("ADMIN")

如果不是这样,请在日志中启用调试,以查看/allUsers请求到底发生了什么。

更新:我怀疑的一件事是你实现了UserDetailsServiceImp。

您必须确保已将角色设置为“用户详细信息”。在您的实现中,您似乎直接从DB查询,不确定是否将角色设置为userDetails。

return userRepository.findByName(username).get(0);

以下是它应该发生的事情:

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    //assume, there is only one user with the username
    UserD user = userRepository.findByUsername(username);
    if (user == null) {
        throw new UsernameNotFoundException("User not found with username: " + username);
    }
    List<GrantedAuthority> roles = new ArrayList<>();
    //assume, there is only one role for the user
    roles.add(new SimpleGrantedAuthority(user.getRole()));
    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                roles);
    }
 类似资料:
  • 在过去的几天里,我一直在进行故障排除,我似乎无法让表达式hasRole工作。我使用的是sping-Security 4.0.1 我的Spring Securityxml 我的所有角色都存储在数据库中,其模式类似于此链接中的1。在自定义的userDetailService中,我将从数据库中加载它。我的角色价值观是这样的 我甚至试着加上前缀“ROLE\uux”,但我似乎无法实现。 下面是关于如何使用h

  • 我的spring security xml 我的所有角色都存储在数据库中,并且有一个类似于此链接中的1的模式。在我的自定义中,我将从数据库加载它。我的角色价值观是这样的 我甚至尝试过把前缀“role_”,但我似乎不能让它工作。

  • 我在使用Spring Security&Thymeleaf时遇到了一个问题,特别是在尝试使用hasRole表达式时。admin“用户有一个角色”admin“,但在尝试时解析为false 我得HTML: 结果如下: 我已经在security.xml文件中启用了use-expressions 并且在我的配置中包含了SpringSecurityDiscuale 而具有一组 为什么不起作用? 我很感激你的

  • 实际:200 我在MyController中有以下方法: 我创建了以下abstract-security-test.xml:

  • 我正在学习一个关于微软文档的教程,介绍如何使用Spring Boot Starter for Azure Active Directory保护我的Spring MVC应用程序。我正在努力保护我网站的管理区域。我在控制器方法上有一个@PreAuthorize注释,我只希望admin组中的用户可以访问它。我可以得到一个登录提示,但成功登录后,我得到了该控制器方法的403。当我删除@PreAuthori

  • 我尝试在我的应用程序中扮演角色。但我一直有个消息。 在数据库中,我有列角色和值USER或ADMIN 重新控制器 如果我评论