如何保护RepositoryRestController

时间:2015-07-04 22:51:24

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

假设我有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应该只有 通过帖子和/ medias /访问应该返回403或404
  • 只有拥有ROLE_USER的用户才能创建帖子
  • 只有已创建帖子的用户或拥有ROLE_ADMIN的用户才能更新帖子。
  • 只有拥有ROLE_ADMIN的用户才能删除帖子

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

1 个答案:

答案 0 :(得分:3)

是的,您可以直接将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注释保护存储库方法。 e.g。

@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
}