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
你必须注意 id
是 private
所以,你的代码应该调用 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;
}
}
我正在使用 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
你必须注意 id
是 private
所以,你的代码应该调用 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;
}
}