【问题标题】:How to secure RepositoryRestController如何保护 RepositoryRestController
【发布时间】:2015-09-22 09:52:55
【问题描述】:

假设我有 2 个必须实体:

@Entity
public class Post {
    @NotEmpty
    private String title;
    @NotEmpty
    @Lob
    private String html;
    @NotEmpty
    @Lob
    private String text;
    @ManyToOne
    private Topic topic;
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "content_media", joinColumns = {@JoinColumn(name = "content_id")}, inverseJoinColumns = {@JoinColumn(name = "media_id")})
    private Set<Media> medias = new HashSet<>();
    @CreatedBy
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn
    private User createdBy;

    @LastModifiedBy
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn
    private User lastModifiedBy;
    ...
}
@Entity
public class Media {
    @NotEmpty
    private String localPath;
    @NotEmpty
    private String fileName;
    private long fileLength;
    private String fileType;
    private int focusPointX;
    private int focusPointY;
    ...
}

我正在使用:

@RepositoryRestController
public interface MediaRepository extends JpaRepository<Media, Long> {
}
@RepositoryRestController
public interface PostRepository extends JpaRepository<Post, Long> {
}

我希望这些控制器是安全的。让我自己解释一下。

  • 如果登录用户没有 ROLE_ADMIN,媒体应该只 可通过帖子访问,/medias/ 应返回 403 或 404
  • 只有拥有 ROLE_USER 的用户才能创建帖子
  • 只有创建帖子的用户或拥有 ROLE_ADMIN 的用户才能更新帖子。
  • 只有拥有 ROLE_ADMIN 的用户才能删除帖子

有没有办法使用 RepositoryRestController 和 Spring Security 或 RepositoryRestController 仅用于公共资源,我应该使用 RestController 自己编写服务层?

【问题讨论】:

    标签: java spring-security spring-boot spring-data spring-data-rest


    【解决方案1】:

    是的,您可以直接将 Spring Security 与 Spring Data REST 一起使用。您需要使用 Spring Security Configuration 定义路由的安全性,如下所示:

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
      @Override
      protected void configure(HttpSecurity http) throws Exception {
    
        http.httpBasic().and().authorizeRequests().
            antMatchers(HttpMethod.POST, "/posts").hasRole("USER").
            antMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN").and().
            csrf().disable();
      }
    }
    

    存储库方法将使用 Spring Security 注释进行保护。例如

    @RepositoryRestController
    public interface PostRepository extends JpaRepository<Post, Long> {
        @Override
        @PreAuthorize("hasRole('ROLE_ADMIN')")
        void delete(Long aLong);
    }
    

    上面的代码只是一个指针。您可以根据需要对其进行自定义。 Here is the link to Spring Data examples repository.

    更新 要处理创建用户或 ADMIN_ROLE 中的任何用户对帖子的更新,您需要创建一个控制器类并定义一个方法来处理更新

    @RequestMapping(method={RequestMethod.PUT}, value={"posts/{id}"})
    public void updatePost(@PathVariable("id") Long id, HttpServletRequest request)
    {
        //Fetch the authenticated user name
        SecurityContext securityContext = SecurityContextHolder.getContext();
        Authentication authentication = securityContext.getAuthentication();
        Object principal = authentication.getPrincipal();
    
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
        }
    
        // Make a database call to verify if the user is owner of the post
        Post post = postRepository.getPostByUserName(String username, Long postId);
    
        if (post == null && !request.isUserInRole("ADMIN");) {
            //return 403 error code
        }
    
        //proceed with the update
    }
    

    【讨论】:

    • 我接受了答案,但您的答案不包括“只有创建帖子的用户......应该能够更新帖子。”。
    猜你喜欢
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 2011-05-23
    • 2010-12-27
    • 2011-02-07
    • 2012-07-16
    相关资源
    最近更新 更多