<i id='VPKN3'><tr id='VPKN3'><dt id='VPKN3'><q id='VPKN3'><span id='VPKN3'><b id='VPKN3'><form id='VPKN3'><ins id='VPKN3'></ins><ul id='VPKN3'></ul><sub id='VPKN3'></sub></form><legend id='VPKN3'></legend><bdo id='VPKN3'><pre id='VPKN3'><center id='VPKN3'></center></pre></bdo></b><th id='VPKN3'></th></span></q></dt></tr></i><div id='VPKN3'><tfoot id='VPKN3'></tfoot><dl id='VPKN3'><fieldset id='VPKN3'></fieldset></dl></div>
  • <small id='VPKN3'></small><noframes id='VPKN3'>

  • <tfoot id='VPKN3'></tfoot>

      <bdo id='VPKN3'></bdo><ul id='VPKN3'></ul>

    <legend id='VPKN3'><style id='VPKN3'><dir id='VPKN3'><q id='VPKN3'></q></dir></style></legend>

        基于用户主体的 Spring Data Rest 中的存储库访问控制

        时间:2024-08-23
      1. <tfoot id='9wUao'></tfoot>

        1. <legend id='9wUao'><style id='9wUao'><dir id='9wUao'><q id='9wUao'></q></dir></style></legend>
          • <i id='9wUao'><tr id='9wUao'><dt id='9wUao'><q id='9wUao'><span id='9wUao'><b id='9wUao'><form id='9wUao'><ins id='9wUao'></ins><ul id='9wUao'></ul><sub id='9wUao'></sub></form><legend id='9wUao'></legend><bdo id='9wUao'><pre id='9wUao'><center id='9wUao'></center></pre></bdo></b><th id='9wUao'></th></span></q></dt></tr></i><div id='9wUao'><tfoot id='9wUao'></tfoot><dl id='9wUao'><fieldset id='9wUao'></fieldset></dl></div>
          • <small id='9wUao'></small><noframes id='9wUao'>

                <tbody id='9wUao'></tbody>

                  <bdo id='9wUao'></bdo><ul id='9wUao'></ul>
                • 本文介绍了基于用户主体的 Spring Data Rest 中的存储库访问控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在尝试实现细粒度访问控制,同时仍然利用 Spring 数据休息.

                  I'm attempting to implement fine grain access control while still taking advantage of Spring data rest.

                  我正在努力保护 CrudRepository,以便用户只能修改或插入属于他们的数据.我正在使用 @PreAuthorize/@PostAuthorize@PreFilter/@PostFilter 来锁定访问权限现任校长.

                  I'm working on securing a CrudRepository so users can only modify or insert data that belongs to them. I'm making use of @PreAuthorize/@PostAuthorize and @PreFilter/@PostFilter to lock access down to the current principal.

                  到目前为止,我的存储库看起来像这样.

                  So far my repository looks like this.

                  public interface MyRepository extends CrudRepository<MyObject, Integer> {
                  
                      @PreAuthorize("#entity.userId == principal.id")
                      @Override
                      <S extends MyObject> S save(S entity);
                  
                      @PreFilter("filterObject.userId === principal.id")
                      @Override
                      <S extends MyObject> Iterable<S> save(Iterable<S> entities);
                  
                      @PostAuthorize("returnObject.userId == principal.id")
                      @Override
                      MyObject findOne(Integer integer);
                  
                      @PostFilter("filterObject.userId == principal.id")
                      @Override
                      Iterable<MyObject> findAll();
                  
                  }
                  

                  虽然这有点乏味,但它似乎确实完成了我所追求的.(如果有人知道更好的方法,请随时告诉我!)

                  While this is a bit tedious, it does seem to accomplish what I'm after. (If anyone knows a better way, feel free to let me know!)

                  我遇到问题的地方是 delete()count()exists()

                  Where I'm running into problems is with delete(), count() and exists()

                      @Override
                      long count();
                  
                      @Override
                      void delete(Integer integer);
                  
                      @Override
                      void delete(MyObject entity);
                  
                      @Override
                      void deleteAll();
                  
                      @Override
                      boolean exists(Integer integer);
                  

                  这些方法要么采用 Integer ID 参数,要么根本不采用.似乎我必须首先选择具有输入 ID 的实体,然后执行身份验证检查.

                  These methods either take an Integer ID parameter or none at all. It seems like I would have to first select the entity with the input ID and then perform the auth check.

                  在存储库中是否可以进行这种类型的授权?

                  Is this type of authorization possible within the repository?

                  谢谢

                  感谢 ksokol,这似乎现在可以工作了.

                  Thanks to ksokol this seems to be working now.

                  我向 @Configuration 类添加了一个新 bean

                  I added a new bean to a @Configuration class

                  @Bean
                  public EvaluationContextExtension securityExtension() {
                      return new SecurityEvaluationContextExtensionImpl();
                  }
                  

                  此 bean 扩展了 EvaluationContextExtensionSupport 并覆盖 getRootObject 以返回包含我的自定义主体的 SecurityExpressionRoot.

                  This bean extends EvaluationContextExtensionSupport and overrides getRootObject to return a SecurityExpressionRoot that holds my custom principal.

                  public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
                  @Override
                  public String getExtensionId() {
                      return "security";
                  }
                  
                  @Override
                  public Object getRootObject() {
                          Authentication authentication =   SecurityContextHolder.getContext().getAuthentication();
                          return new SecurityExpressionRoot(authentication){};
                      }
                  }
                  

                  推荐答案

                  截至 Spring Security 4.0 你可以在 Spring Data JPA 查询中访问安全上下文.

                  As of Spring Security 4.0 you can access security context in Spring Data JPA queries.

                  SecurityEvaluationContextExtension bean 添加到您的 bean 上下文中:

                  Add SecurityEvaluationContextExtension bean to your bean context:

                  @Bean
                  public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
                      return new SecurityEvaluationContextExtension();
                  }
                  

                  现在您应该可以在 Spring Data 查询中访问 Principal:

                  Now you should be able to access Principal in your Spring Data queries:

                  @Query("select count(m) from MyObject as m where m.user.id = ?#{ principal?.id }")
                  @Override
                  long count();
                  
                  @Modifying
                  @Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
                  @Override
                  void delete(Integer integer);
                  
                  @Modifying
                  @Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
                  @Override
                  void delete(MyObject entity);
                  
                  @Modifying
                  @Query("delete from MyObject as m where m.user.id = ?#{ principal?.id }")
                  @Override
                  void deleteAll();
                  
                  @Query("select 1 from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
                  @Override
                  boolean exists(Integer integer);
                  

                  小心.查询可能有错误.我没有时间测试它.

                  Caution. Queries might have errors. I hadn't the time to test it.

                  这篇关于基于用户主体的 Spring Data Rest 中的存储库访问控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:PersistenceAnnotationBeanPostProcessor 有什么用处吗? 下一篇:Spring Data PageImpl 没有返回正确大小的页面?

                  相关文章

                  <legend id='8rbvm'><style id='8rbvm'><dir id='8rbvm'><q id='8rbvm'></q></dir></style></legend>

                    <bdo id='8rbvm'></bdo><ul id='8rbvm'></ul>

                    <i id='8rbvm'><tr id='8rbvm'><dt id='8rbvm'><q id='8rbvm'><span id='8rbvm'><b id='8rbvm'><form id='8rbvm'><ins id='8rbvm'></ins><ul id='8rbvm'></ul><sub id='8rbvm'></sub></form><legend id='8rbvm'></legend><bdo id='8rbvm'><pre id='8rbvm'><center id='8rbvm'></center></pre></bdo></b><th id='8rbvm'></th></span></q></dt></tr></i><div id='8rbvm'><tfoot id='8rbvm'></tfoot><dl id='8rbvm'><fieldset id='8rbvm'></fieldset></dl></div>

                    <small id='8rbvm'></small><noframes id='8rbvm'>

                    1. <tfoot id='8rbvm'></tfoot>