Java Spring数据JPA Rest的安全问题(JpaRepository)
我(试图:)在我的spring boot应用程序中使用spring boot starter数据rest,通过真实、完整、restFULL api快速为模型提供服务。这很有效 问题1(安全): SpringJParepository的优点是我不需要编写基本函数(save、findAll等)。有没有可能在不覆盖所有方法的情况下保护这些自动实现的方法(浪费Spring为我提供的东西)?i、 e:Java Spring数据JPA Rest的安全问题(JpaRepository),java,spring,spring-boot,spring-security,dto,Java,Spring,Spring Boot,Spring Security,Dto,我(试图:)在我的spring boot应用程序中使用spring boot starter数据rest,通过真实、完整、restFULL api快速为模型提供服务。这很有效 问题1(安全): SpringJParepository的优点是我不需要编写基本函数(save、findAll等)。有没有可能在不覆盖所有方法的情况下保护这些自动实现的方法(浪费Spring为我提供的东西)?i、 e: 公共接口BookRepository扩展了JpaRepository{ @预授权(“hasRole('R
公共接口BookRepository扩展了JpaRepository{
@预授权(“hasRole('ROLE_ADMIN'))
图书保存;
}
问题2(安全):
如何确保JpaRepository的安全以防止更新用户中的loggeg不是所有者的项目?
i、 e:用户只能修改自己的属性。
i、 e.2:用户只能修改/删除自己创建的帖子。
这里非常欢迎使用示例代码
问题3(DTO):
不久前,我和一位开发人员朋友发生了一场争论:他认为一定有从SpringMVC控制器返回的DTO。即使DTO是模型对象的1-1副本。然后我进行了研究,询问了其他人,并确认了这一点:DTO需要划分/隔离应用层
这与JpaRepositories有何关系?如何将DTO与Spring auto-serverd rest repos一起使用?我到底该不该做DTO
提前感谢您的提示/回答问题1:安全 有人提到: […]您向您无法控制的客户机公开了一组预定义的操作,到目前为止,这些操作几乎是全部或全部没有。似乎没有办法只公开读取操作,而完全隐藏改变状态的操作 这意味着所有方法都是自动继承的(同样,根据标准的
java
继承行为)
根据文档,您还可以将注释放置在类/接口声明上
因此,您可以只使用一个基本接口扩展JpaRepository
@NoRepositoryBean // tell Spring not create instances of this one
@PreAuthorize("hasRole('ROLE_ADMIN')") // all methods will inherit this behavior
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {}
或者像以前一样
@Service
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface BookService {
ActionResult saveToDatabase(final BookDTO book);
}
此外,确保用户只能修改自己的对象可以通过多种方式完成
Spring
提供了所有必要的资源,如前所述
或者,如果您熟悉AOP
,您可以实现自己的逻辑
例如(dummyCode):
支票:
public class EnsureUserOwnershipInterceptor implements MethodInterceptor {
@Autowired
private AuthenticationService authenticationService;
@Override
public Object invoke(Invocation invocation) throws Throwable {
// 1. get the BookDTO argument from the invocation
// 2. get the current user from the auth service
// 3. ensure the owner ID and the current user ID match
// ...
}
}
有关AOP
的有用资源可以找到并找到
问题3:
DTO
和DB型号
我到底该不该做DTO
是的,是的,你应该。即使您的项目只有几个模型,并且您的编程只是为了好玩(仅在本地主机上部署,学习,…)
你越早养成分离模型的习惯,效果就越好
另外,从概念上讲,一个是来自未知源的对象,另一个表示数据库中的表
这与JpaRepositories有何关系?
如何将DTO与Spring auto-serverd rest repos一起使用
这就是重点!您不能将DTO
放入@存储库中。您必须将一个转换为另一个。同时,您还必须验证转换是否有效
您基本上是在确保DTO
s(脏数据)不会以任何方式接触数据库,并且在数据库和应用程序的其余部分之间放置一堵由逻辑约束构成的墙
此外,我知道Spring能很好地与集成
那么,多层
/模块化
web应用程序的优势是什么
- 应用程序可以快速增长。特别是当你有很多开发人员在工作的时候。一些开发人员倾向于寻找最快的解决方案,实施肮脏的技巧或更改访问修饰符以尽快完成任务。您应该强制人们只能通过一些明确定义的渠道访问某些资源。
从一开始设置的规则越多,遵循正确编程模式的时间就越长。不到一年,我就看到银行申请变得一团糟。当需要
热修复程序时,更改某些代码会产生另外两个bug
- 应用程序可能会消耗过多的操作系统资源。比如说,如果您有一个包含应用程序后台作业的模块
module batch
,那么将其提取并实现到另一个应用程序中会更容易。如果您的模块包含查询数据库、访问任何类型的数据、为前端提供API、ecc。。。您将被迫将所有代码导出到新应用程序中。到那时,重构将是一个棘手的问题
- 假设您想雇佣一些数据库专家来分析应用程序执行的查询。使用定义良好且分离的逻辑,您可以让他们只访问必要的
模块
,而不是整个应用程序。这同样适用于前端自由职业者ecc。。。我也经历过这种情况。该公司希望数据库专家修复应用程序执行的查询,但不希望他们能够访问整个代码。最后,他们放弃了数据库优化,因为这样会在外部暴露太多敏感信息
而DTO
/DB模型
分离的优势是什么
DTO
不会接触数据库。这使您能够更安全地抵御来自外部的攻击
- 你可以决定在另一边发生什么。您的
DTO
不需要将所有字段实现为db模型。实际上,您甚至可以将一个DAO
映射到许多DTO
或oth
@Service
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface BookService {
ActionResult saveToDatabase(final BookDTO book);
}
@Service
public interface BookService {
// custom annotation here
@RequireUserOwnership(allowAdmin = false)
ActionResult saveToDatabase(final BookDTO book);
}
public class EnsureUserOwnershipInterceptor implements MethodInterceptor {
@Autowired
private AuthenticationService authenticationService;
@Override
public Object invoke(Invocation invocation) throws Throwable {
// 1. get the BookDTO argument from the invocation
// 2. get the current user from the auth service
// 3. ensure the owner ID and the current user ID match
// ...
}
}