Spring 未找到基于引导表达式的访问控制 属性

Spring Boot expression based access control property not found

我正在使用 Spring-data-rest 公开一些实体,我想使用 Spring 表达式语言配置访问控制并进行预授权,以便用户只能操作属于他的实体。

我的主体对象在其用户名(字符串)中包含用户 ID,用户有一个 属性 ID(长整型):

@Entity
@Table(name = "users")
@Getter
@Setter
public class User {

  @Id
  @Column(name = "user_id", nullable = false, updatable = false)
  private Long id;

  ...

}

我的存储库如下所示:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

  @Override
  @PreAuthorize("hasRole('ROLE_ADMIN')")
  User findOne(Long id);

  @Override
  @PreAuthorize("#user.id == principal.username")
  void delete(User user);

  ...

}

但是,当以 ID 1 的用户身份验证时调用 DELETE /users/1(主体在其用户名中包含此 ID)时,出现以下异常:

java.lang.IllegalArgumentException: Failed to evaluate expression '#user.id == principal.username'
...
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'id' cannot be found on null

我的表达是基于官方Spring documentation。有人可以指出我在这里遗漏了什么吗?

编辑: 我在我的存储库中添加了所有方法,因为它们似乎是相互关联的。

在你的 class User 你必须注意 idprivate 所以,你的代码应该调用 public 方法来获取用户id,所以它必须是这样的:

  @Override
  @PreAuthorize("#user.getId() == authentication.getName()")
  void delete(@RequestParam(name="user", required=true)User user);
  .....

您还必须调用 public 方法才能从主体获取用户名。

另请注意,您可以调用安全检查函数来执行更多逻辑,例如:

  @Autowired
  private SecurityCheck securityCheck;

  ................

  @Override
  @PreAuthorize("@securityCheck.check(#user,authentication)")
  void delete(User user);

而在 SecurityCheck 中 class 可以这样定义:

@Component
public class SecurityCheck {


public boolean check(User user, Authentication authentication) {
    if(user == null)
        return false;
   if(user.getId().equals(authentication.getName()))    
       return true;
   // more logic ... 
   return false;
 }
}