2015-03-01 23 views
17

używam aktualnej wersji Spring Data Rest i Spring Data JPA i mają następujące jednostki:Wiosna danych rekreacyjne: projekcja oparta Bezpieczeństwo

public class User { 
    @Id 
    @GeneratedValue 
    private Long id; 
    private String name; 
    private String password; 
    private String email; 
    ...getter/setter methods... 
} 

Jestem również za pomocą Spring Security.

moim repozytorium użytkownika:

@RepositoryRestResource(
    collectionResourceRel = "user", 
    path = "user", 
    excerptProjection = UserSimpleProjection.class) 
public interface UserRepository extends PagingAndSortingRepository<User, Long> { 

} 

Dla przykładu:

  • Użytkownik 1 jest zalogowany
  • użytkownika 1 wnioski http://localhost:8080/user/1 - wszystkie pola są widoczne
  • User 1 Wnioski http://localhost:8080/user/2 - tylko id i name są visibl mi.

Próbowałem różnych rozwiązań z Jackson, żaden z nich nie rozwiązuje mojego problemu:

  • Zastosowanie JsonView: znalazłem żadnego sposobu, aby zmienić widok na ObjectMapper zależności od zalogowanego użytkownika
  • Zaimplementowano różne filtry Jackson opisane w artykule here z tym samym problemem, który uniemożliwił zmianę konfiguracji ObjectMapper dla różnych żądań.

Następnie znalazłem Projections.

stworzyłem projekcji:

@Projection(name = "simple", types = User.class) 
public interface UserSimpleProjection { 

    public Long getId(); 

    public String getName(); 
} 

i inny szczegółowy One:

@Projection(name = "detailed", types = User.class) 
public interface UserDetailProjection extends UserSimpleProjection{ 

    public String getEmail(); 
} 

tej pory tak dobry, mam różne wyniki w zależności od mojego wniosku.

Czy istnieje sposób automatycznego przełączania projekcji w zależności od Spring Security i/lub ograniczania różnych projekcji dla różnych ról?

+0

Czy przypadkiem udaje się występy rolę oparte? – ArunM

+0

Nie, przykro mi. Porzuciłem wtedy i stworzyłem niestandardowych kontrolerów. – Plechi

Odpowiedz

14

Można dodać „wirtualny” właściwość wartość do projekcji, które wywołać metodę usług z kontroli bezpieczeństwa:

@Projection(name = "detailed", types = User.class) 
public interface UserDetailProjection extends UserSimpleProjection{ 

    @Value("#{@userService.checkAccess(target)? target.email : null}") 
    public String getEmail(); 
} 

Gdzie komponent niestandardowy UserService wróci true jeśli e-mail powinien być wystawiony lub po prostu ma @PreAuthorize na checkAccess(..) rzucać AccessDeniedException, co jest dla ciebie lepsze.

Uwaga, właściwość target w Spel zawiera oryginalny obiekt - udostępniany przez Spring-DATA.

+0

To wszystko! Dzięki! – Plechi

+0

Dlaczego ta funkcja nie działa @Value ("# {principal.username.equalsIgnoreCase ('admin')? Target.password: null}") – ArslanAnjum

+1

Ponieważ 'principal' nie jest własnością obiektu głównego SpEL używanego w tym kontekście. Aby uzyskać dostęp do komponentu bean, można użyć prefiksu '@ '. Pls czytaj więcej o Spel: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html – aux

0

Nie, projekcje REST dla Spring Data nie obsługują tego.

1

Można również zrobić to za pomocą RegexRequestMatcher w config wiosny Bezpieczeństwa tak:

.regexMatchers(HttpMethod.GET,"/user/.*projection=simple.*").hasRole("ROLE_ADMIN") 
Powiązane problemy