【问题标题】:When adding @PreAuthorize to a service class: "An Authentication object was not found in the SecurityContext"将 @PreAuthorize 添加到服务类时:“在 SecurityContext 中找不到身份验证对象”
【发布时间】:2020-03-04 11:05:36
【问题描述】:

我有一个运行良好的 Spring Boot 控制器,并且有以下声明:

@RestController
@RequestMapping("/api/our")
@PreAuthorize(value = "hasRole('ROLE_USER')")
@Api(value="our", produces="Our data")
public class OurController {

当我对我们的代码运行 Fortify 静态分析工具时,它抱怨我们的服务类说:

如果没有适当的访问控制,OurService.java 中的方法 findAll() 可以在第 36 行执行包含攻击者控制的主键的 SQL 语句,从而允许攻击者访问未经授权的记录。

所以我尝试将@PreAuthorize 注解添加到我们的服务类中,如下所示:

@Service
@PreAuthorize(value = "hasRole('ROLE_USER')")
public class OurService {
    private final OurRepository ourRepository;

    public OurService(OurRepository ourRepository) {
        this.ourRepository = ourRepository;
    }

    public Page<Our> findAll(Pageable pageable) {
        return ourRepository.findAll(pageable);
    }

    public Page<Our> findAll(Specification<Our> specification, Pageable pageable) {
        return ourRepository.findAll(specification, pageable);
    }
}

但是在启动我们的应用程序时,它失败了,出现以下异常:

原因:org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:在SecurityContext中找不到Authentication对象

【问题讨论】:

    标签: java spring spring-boot spring-security fortify


    【解决方案1】:

    失败来自一个用@Component 注释的类,它实现了ApplicationRunner 接口。

    我必须在其构造函数中添加以下代码:

    Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
    Authentication authentication = new UsernamePasswordAuthenticationToken(this.getClass().getName(), "ROLE_USER", authorities);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    

    【讨论】:

      【解决方案2】:

      你的配置类中有@EnableGlobalMethodSecurity(prePostEnabled = true)吗?

      • prePostEnabled 属性启用 Spring Security 前/后注释
      • secureEnabled 属性确定是否应启用 @Secured 注释
      • jsr250Enabled 属性允许我们使用@RoleAllowed 注解

      为了使@PreAuthorize(value = "hasRole('ROLE_USER')") 工作,您需要在配置类中添加该注释。

      您可以阅读此Introduction to Spring Method Security 了解更多信息。

      【讨论】:

        【解决方案3】:

        你可以尝试在@PreAuthorize 中不使用 value 关键字吗?

        例如:

        @PreAuthorize("hasRole('ROLE_USER')")
        

        【讨论】:

        猜你喜欢
        • 2014-12-20
        • 2017-09-01
        • 2017-08-03
        • 1970-01-01
        • 1970-01-01
        • 2013-09-20
        • 2011-06-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多