如何保护SpringBoot / Spring-Data Rest,以便用户只能访问自己的实体

时间:2015-11-13 22:35:19

标签: spring-mvc spring-security spring-data spring-data-rest

我使用Spring-Data / Rest(http://docs.spring.io/spring-data/rest/docs/current/reference/html/)和Spring Boot以及基本的Spring Security。

我有以下实体。

Items
  -->ID

User
 --> ID
 --> List<Items> items

目前有弹簧休息,任何用户都可以看到/ items / 1,2,3,4,5

我只想让用户只能看到自己的物品。

这是否可以实现而无需编写自定义控制器?

2 个答案:

答案 0 :(得分:0)

是的,你可以。

为此,您可以为每个用户分配一个特定的角色。例如,在您的情况下,将拥有项目的用户分配为角色列ADMIN,并将所有其他用户ANONYMOUS或USER分配给您。在此之后,使用spring security对于具有项目URL的ANONYMOUS或USER角色的用户,您可以使请求失败,并且只允许具有ADMIN角色的用户查看项目。

现在,这可以通过弹簧安全以多种方式实现:

1.使用@PreAuthorize标记用于各个控制器方法和测试角色ADMIN / USER / .. 但是,我想,你不想彻底修改控制器。

  1. 简短的手动方式,即将身份验证对象创建到上下文持有者并使用spring boot security config,例如下面的内容,例如:

     @Order(1)
     public class UserFilter extends Filter {
    
     @Autowired
     UserService userService;
     ...
    
     UserObject userObject = userService.getUser(arg..);
     List<GrantedAuthority> grantedAuthorityList = new ArrayList<GrantedAuthority>();
     grantedAuthorityList.add( new SimpleGrantedAuthority((userObject.getRoleName()));//Either ROLE_ADMIN or ROLE_USER
    Authentication authentication = new    PreAuthenticatedAuthenticationToken(userObject.getId(), new Object(), grantedAuthorityList);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    chain.doFilter(request,response);
    
    ...
    
    }
    
  2. 安全配置类:

      @Configuration
      @EnableWebSecurity
      public class SecurityConfigREST extends WebSecurityConfigurerAdapter {
    
    
      SecurityConfigREST(){
        super(true);
      }
      @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        PreAuthenticatedAuthenticationProvider pap=new PreAuthenticatedAuthenticationProvider();
        pap.setPreAuthenticatedUserDetailsService(new PreAuthenticatedGrantedAuthoritiesUserDetailsService());
        auth.authenticationProvider(pap);
    }
    @Override
      protected void configure(HttpSecurity http) throws Exception {
       http
          .authorizeRequests()
          .regexMatchers("^/items.*$").hasAuthority("ROLE_ADMIN") //The role which should have access to /items/1,2.. URL
          .anyRequest().authenticated();
      }
      } 
    
    1. 在上面的安全配置中使用UserDetailsS​​ervice,并在预验证的身份验证提供程序中加载用户及其角色。 请参阅:http://docs.spring.io/autorepo/docs/spring-security/3.2.2.RELEASE/apidocs/org/springframework/security/core/userdetails/UserDetailsService.html
    2. 说了这么多,它也是一个不通过URL传递项目(1,2,3)数字的好设计,因为可能会导致以后出现潜在问题,所以使用GET并将JSON请求体传递给它,例如: / p>

      /items RequestMethod.GET 
      
      {
      "itemList" : [1,2,3,4,5]
      }
      
      Hope that helps.
      

答案 1 :(得分:0)

我认为JPA级别的多租户可能是一种很好的透明方法,用于表示用户可以看到的数据。有关详细信息,请参阅我的答案: https://stackoverflow.com/a/33648305/5371736