2015-11-13 24 views
5

Używam Spring-Data/Rest (http://docs.spring.io/spring-data/rest/docs/current/reference/html/) z Spring Boot i podstawowym Spring Security.W jaki sposób zabezpieczyć SpringBoot/Spring-Data Rest, aby użytkownik mógł uzyskać dostęp tylko do swoich jednostek?

Mam następujące podmioty.

Items 
    -->ID 

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

Obecnie z resztą wiosennej, każdy użytkownik może zobaczyć/szt/1,2,3,4,5

Chcę tylko, aby umożliwić użytkownikom, aby zobaczyć tylko swoje własne elementy.

Czy jest to możliwe bez konieczności kodowania niestandardowego kontrolera?

Odpowiedz

0

Tak, możesz.

W tym celu można przypisać każdemu użytkownikowi określoną rolę. Na przykład w twoim przypadku przypisz użytkownika, który jest właścicielem pozycji jako kolumna roli ADMIN i wszystkich innych ANONIMOWYCH lub UŻYTKOWNIKÓW, wybierz. Po tym przy użyciu wiosny zabezpieczenia, które można spowodować, że żądanie nie powiedzie się użytkownikom mającym ANONIMOWĄ lub UŻYTKOWNIKOWĄ rolę dla adresu URL elementów i zezwalają tylko użytkownikom z rolą ADMIN na przeglądanie elementów.

Teraz można to osiągnąć poprzez zabezpieczenie sprężyny na wiele sposobów:

1. Za pomocà @PreAuthorize tagów dla poszczególnych metod testowania i ról kontrolera admin/user/.. Ale, jak sądzę, nie chcesz aby zmodyfikować kontroler jako taki drastycznie.

  1. Krótka ręczny sposób, który jest, w celu utworzenia obiektu uwierzytelniania w uchwycie kontekstowe i sprężyny zabezpieczający bagażnik konfiguracyjne, takie jak poniżej, np

    @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); 
    
    ... 
    
    } 
    

i klasy konfiguracji zabezpieczeń:

@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. Używaj UserDetailsService w konfiguracji zabezpieczeń powyżej oraz obciążenia t użytkownik i jego rola w wcześniej uwierzytelnionym dostawcy uwierzytelniania. Patrz: http://docs.spring.io/autorepo/docs/spring-security/3.2.2.RELEASE/apidocs/org/springframework/security/core/userdetails/UserDetailsService.html

Powiedziawszy to wszystko, jej też dobry projekt nie zdać przedmioty (1,2,3) numery pośrednictwem adresu URL, ponieważ może prowadzić do potencjalnych problemów później, więc należy używać GET i przekazać wniosek JSON ciało jest takie jak:

/items RequestMethod.GET 

{ 
"itemList" : [1,2,3,4,5] 
} 

Hope that helps. 
+0

Pytanie było jak ograniczyć wyniki tylko do podmiotów, które należą do użytkownika. Role w żaden sposób nie pomagają. Nie obchodzi mnie, czy użytkownik jest administratorem czy śmiertelnym użytkownikiem - nie powinno mu się pozwalać na oglądanie podmiotów, które do niego należą. –

+0

huh? Zawsze dobrze jest dołączyć role do listy przedmiotów lub zasobów. Jest to dobra praktyka. Jeśli nie jest wymagana, możesz po prostu powtórzyć w oparciu o klucz z repozytorium JPA przez: repository.findByUserId (Long userId), który jest po prostu zwykłe dane sprężystości jpa, (brak zabezpieczenia sprężystego jako takiego, konflikty z pytaniem). Co więcej, w powyższym stwierdzeniu zaprzeczasz sobie "nie powinno się pozwalać na dostrzeganie istot, które należą do niego" ... proszę poprawić ... dzięki . –

+1

Tak, powinno być "to nie * nie * należy do siebie", ale wygląda na to, że SO nie pozwala na edycję komentarzy po pewnym czasie. Tak, role są w porządku i używam ich. Ale nie ma to nic wspólnego z sytuacją w pytaniu. Problem polega na tym, że spakowanie danych sprężynowych powoduje, że wszystkie repozytoria są dostępne w odwzorowaniu '/ {repozytorium}, umożliwiając dostęp do wszystkich encji. Pytanie więc, jak zwrócić tylko te jednostki, które należą do użytkownika. –

0

myślę multitenancy na poziomie WZP może być miłym przejrzyste podejście do spearating danych użytkownik może zobaczyć. Proszę zobaczyć moją odpowiedź tutaj dla szczegółów: https://stackoverflow.com/a/33648305/5371736