2010-06-21 33 views

Trả lời

63

Có, nó hoạt động tốt.

Bạn cần <security:global-method-security pre-post-annotations="enabled" /> trong ...-servlet.xml. Nó cũng yêu cầu CGLIB proxies, do đó bộ điều khiển của bạn không nên có giao diện hoặc bạn nên sử dụng proxy-target-class = true.

+1

tôi đặt rằng vào mùa xuân bối cảnh ứng dụng bảo mật của tôi (tôi đã có nó thực sự) nhưng Spring không làm bất cứ điều gì với bộ điều khiển bằng cách sử dụng @Controller. Tôi có phải làm bất cứ điều gì đặc biệt để có được điều này để làm việc ở trên và vượt ra ngoài những gì bạn nói? Trong – egervari

+13

Tôi đã nói, 'global-method-security' nên ở trong ngữ cảnh của DispatcherServlet (' ...- servlet.xml') không có trong "bối cảnh ứng dụng bảo mật mùa xuân". – axtavt

+0

Cảm ơn! Tôi đã không di chuyển nó bởi vì tôi không thể nhìn thấy lý do tại sao nó sẽ tạo ra một sự khác biệt kể từ khi nó được sáp nhập ... Tôi đoán nó đã không;) Làm việc ngay bây giờ! – egervari

20

Xem Spring Security FAQ (nhấn mạnh mỏ).

Trong một ứng dụng web Spring, bối cảnh ứng dụng mà giữ đậu Spring MVC cho servlet phối thường tách rời khỏi bối cảnh ứng dụng chính. Nó thường được định nghĩa trong một tệp có tên là myapp-servlet.xml, trong đó “myapp” là tên được gán cho Spring DispatcherServlet trong tệp web.xml. Ứng dụng có thể có nhiều DispatcherServlets, mỗi ứng dụng có ngữ cảnh ứng dụng riêng biệt. Các hạt trong các ngữ cảnh “con” này không hiển thị đối với phần còn lại của ứng dụng . Ngữ cảnh ứng dụng "gốc" được tải bởi ContextLoaderListener mà bạn xác định trong tệp web.xml của mình và hiển thị cho tất cả các ngữ cảnh con . Ngữ cảnh gốc này thường là nơi bạn xác định cấu hình bảo mật của mình, bao gồm cả phần tử ). Kết quả là bất kỳ ràng buộc bảo mật nào được áp dụng cho các phương thức trong các hạt web này sẽ không được thực thi, vì các bean không thể được nhìn thấy từ ngữ cảnh DispatcherServlet. Bạn cần di chuyển tuyên bố vào ngữ cảnh web hoặc di chuyển các hạt bạn muốn được bảo mật vào ngữ cảnh ứng dụng chính.

Nói chung, chúng tôi khuyên bạn nên áp dụng bảo mật phương pháp tại lớp dịch vụ thay vì trên bộ điều khiển web riêng lẻ.

Nếu bạn áp dụng các phím tắt cho lớp dịch vụ, bạn chỉ cần đặt <global-method-security> trong ngữ cảnh bảo mật của ứng dụng.

+0

Đã cố sử dụng @PreAuthorize trong bộ điều khiển, không hoạt động, đã hoạt động khi tôi chuyển sang lớp dịch vụ. – MarCrazyness

16

Nếu bạn đang sử dụng Spring 3.1, bạn có thể thực hiện một số nội dung thú vị với tính năng này. Hãy xem https://github.com/mohchi/spring-security-request-mapping. Đó là một dự án mẫu tích hợp @PreAuthorize với RequestMappingHandlerMapping Spring MVC của để bạn có thể làm điều gì đó như:

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

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

Một yêu cầu "/" sẽ gọi authenticatedHomePage() nếu người dùng được xác thực. Nếu không, nó sẽ gọi homePage().

9

Đã hơn hai năm kể từ khi câu hỏi này được hỏi nhưng vì những vấn đề tôi có ngày hôm nay tôi muốn khuyến khích sử dụng @Secured, @PreAuthorize, v.v. trên @Controller s.

gì đã không làm việc đối với tôi là @Validated kết hợp với bộ điều khiển @Secured:

@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 chỉ đơn giản là không lửa (Spring MVC 4.1.2, Xuân An 3.2.5) và không kiểm tra được thực hiện.

vấn đề tương tự cũng được gây ra bởi cglib proxy được sử dụng bởi Spring (khi không có giao diện được thực hiện bởi một lớp, mùa xuân tạo cglib proxy; nếu lớp thực hiện bất kỳ giao diện sau đó JDK Proxy được tạo ra - documentation, well explained herehere).

Như đã đề cập trong các câu trả lời mà tôi đã liên kết ở trên, không nên sử dụng chú thích Spring Security trên lớp dịch vụ thường triển khai giao diện (vì vậy JDK Proxies được sử dụng) vì điều này không dẫn đến các vấn đề như vậy.

Nếu bạn muốn bảo mật bộ điều khiển web, ý tưởng tốt hơn là sử dụng <http><intercept-url /> được gắn với url cụ thể thay vì phương pháp trong bộ điều khiển và hoạt động khá tốt. Trong trường hợp của tôi:

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

    ... 

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

</http> 
1

Để Mở rộng câu trả lời cung cấp bởi Andy, bạn có thể sử dụng:

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

để kiểm tra vai trò cụ thể.

2

Đã có câu trả lời về cách làm cho nó hoạt động bằng cách thay đổi cấu hình xml; Tuy nhiên, nếu bạn đang làm việc với cấu hình code-based, bạn có thể đạt được như vậy bằng cách đặt chú thích sau hơn @Configuration lớp học của bạn:

@EnableGlobalMethodSecurity(prePostEnabled=true) 
Các vấn đề liên quan