2010-06-21 10 views

Odpowiedz

63

Tak, działa poprawnie.

Potrzebujesz <security:global-method-security pre-post-annotations="enabled" /> w ...-servlet.xml. Wymaga także CGLIB proxies, więc albo twoje kontrolery nie powinny mieć interfejsów, albo powinieneś użyć proxy-target-class = true.

+1

kładę, że w moim wiosennym kontekście aplikacji bezpieczeństwa (miałem już go właściwie), ale Spring nie robi nic z kontrolerami używającymi @Controller. Czy muszę robić coś wyjątkowego, aby to działało ponad to, co powiedziałeś? W – egervari

+13

Powiedziałem, że 'global-method-security' powinno znajdować się w kontekście DispatcherServlet (' ...- servlet.xml'), a nie w "kontekście aplikacji Spring Security". – axtavt

+0

Dzięki! Nie poruszyłem tego, ponieważ nie mogłem zrozumieć, dlaczego to się zmieni, ponieważ zostanie scalone ... Myślę, że tak się nie stało;) Działa teraz! – egervari

20

Zobacz Spring Security FAQ (podkreślenie moje).

w aplikacji internetowej Wiosna, kontekst aplikacji, która przechowuje Wiosna MVC fasolę do dyspozytora serwletu jest często oddzielone od głównego kontekstu aplikacji. Często jest to zdefiniowane w pliku o nazwie myapp-servlet.xml, gdzie "mojaapp" to nazwa przypisana do Spring DispatcherServlet w pliku web.xml. Aplikacja może mieć wiele serwerów DispatcherServlet , każdy z własnym izolowanym kontekstem aplikacji. Ziarna w tych kontekstach "potomnych" nie są widoczne dla reszty aplikacji . Kontekst aplikacji "nadrzędny" jest ładowany przez obiekt ContextLoaderListener zdefiniowany w pliku web.xml i jest widoczny dla wszystkich kontekstów podrzędnych dla wszystkich . Ten kontekst nadrzędny jest zwykle definiowany jako Twoja konfiguracja zabezpieczeń, w tym element ). W rezultacie wszelkie ograniczenia zabezpieczeń zastosowane do metod w tych ziarnach WWW nie będą wymuszane, ponieważ fasola nie może być widziana z kontekstu DispatcherServlet. Musisz przenieść deklarację do kontekstu sieci lub przenieść komponenty bean, które chcesz zabezpieczyć, do kontekstu aplikacji głównej.

Generalnie zalecamy stosowanie metody zabezpieczeń w warstwie serwisowej , a nie na poszczególnych kontrolerach internetowych.

Jeśli stosuje się do punktów przekroju warstwy usługowej trzeba tylko ustawić <global-method-security> w kontekście zabezpieczeń swojej aplikacji.

+0

Próbowałem użyć @PreAuthorize w kontrolerze, nie działało, działało po przejściu do warstwy usługi. – MarCrazyness

16

Jeśli używasz Spring 3.1, możesz zrobić z tego całkiem fajne rzeczy. Spójrz na https://github.com/mohchi/spring-security-request-mapping. Jest to przykładowy projekt, który integruje @PreAuthorize z RequestMappingHandlerMapping MVC wiosny, tak, że można zrobić coś takiego:

@RequestMapping("/") 
@PreAuthorize("isAuthenticated()") 
public String authenticatedHomePage() { 
    return "authenticatedHomePage"; 
} 

@RequestMapping("/") 
public String homePage() { 
    return "homePage"; 
} 

Żądanie „/” wezwie authenticatedHomePage(), jeśli użytkownik jest uwierzytelniony. W przeciwnym razie wywoła on funkcję homePage().

9

Minęło ponad dwa lata, odkąd zadawano to pytanie, ale z powodu problemów, które miałem dzisiaj wolałbym odradzać używanie @Secured, @PreAuthorize, itp. Na @Controller s.

Co nie działa dla mnie było @Validated połączeniu z @Secured kontrolera:

@Controller 
@Secured("ROLE_ADMIN") 
public class AdministrationController { 

// @InitBinder here... 

@RequestMapping(value = "/administration/add-product", method = RequestMethod.POST) 
public String addProductPost(@ModelAttribute("product") @Validated ProductDto product, BindingResult bindingResult) { 
    // ... 
} 

Validator po prostu nie uruchamia (wiosna MVC 4.1.2, 3.2.5 Bezpieczeństwo wiosna) i żadne kontrole są przeprowadzane.

Podobne problemy spowodowane CGLIB proxy wykorzystywanych przez sprężynę (kiedy nie ma interfejsu realizowane przez klasę Spring tworzy CGLIB proxy, gdy klasa realizuje dowolnego interfejsu następnie JDK Pełnomocnik generowany - documentation, well explained here i here).

Jak wspomniano w odpowiedziach, które podałem powyżej, lepiej nie używać adnotacji Spring Security na warstwie usługowej, która zwykle implementuje interfejsy (dlatego używa się proxy JDK), ponieważ nie prowadzi to do takich problemów.

Jeśli chcesz zabezpieczyć kontrolery sieciowe, lepszym rozwiązaniem jest użycie <http> i <intercept-url />, które są powiązane z określonymi adresami URL, a nie z metodami w kontrolerach i działają całkiem nieźle. W moim przypadku:

<http use-expressions="true" disable-url-rewriting="true"> 

    ... 

    <intercept-url pattern="/administration/**" access="hasRole('ROLE_ADMIN')" /> 

</http> 
1

przedłużyć odpowiedź dostarczoną przez Andy, można użyć:

@PreAuthorize("hasRole('foo')") 

sprawdzić konkretną rolę.

2

Istnieje już odpowiedź na pytanie, jak to zrobić, zmieniając konfigurację XML; Jednakże, jeśli pracujesz z konfiguracją kodu oparte, można osiągnąć to samo, umieszczając następującą adnotację na swojej klasie @Configuration:

@EnableGlobalMethodSecurity(prePostEnabled=true) 
Powiązane problemy