axt*_*avt 68

是的,它工作正常.

你需要<security:global-method-security pre-post-annotations="enabled" />...-servlet.xml.它还需要CGLIB代理,因此您的控制器不应该有接口,或者您应该使用proxy-target-class = true.

  • 我说,`global-method-security`应该在DispatcherServlet的上下文(`...- servlet.xml`)中,不在"spring security application context"中. (13认同)
  • 他们没有合并.`DispatcherServlet`的上下文是`ContextLoaderListener`的子上下文.因此它们具有不同的AOP配置,因此需要不同的"<global-method-security>". (2认同)

Tom*_*asz 23

请参阅Spring Security FAQ(强调我的).

在Spring Web应用程序中,为调度程序servlet保存Spring MVC bean的应用程序上下文通常与主应用程序上下文分开.它通常在名为myapp-servlet.xml的文件中定义,其中"myapp"是在web.xml中分配给Spring DispatcherServlet的名称.应用程序可以有多个DispatcherServlet,每个DispatcherServlet都有自己独立的应用程序上下文.这些"子"上下文中的bean对于应用程序的其余部分是不可见的."父"应用程序上下文由您在web.xml中定义的ContextLoaderListener加载,并且对所有子上下文都可见.此父上下文通常是您定义安全配置的位置,包括元素).因此,不会强制应用于这些Web Bean中的方法的任何安全性约束,因为无法从DispatcherServlet上下文中看到Bean.您需要将声明移动到Web上下文或将要保护的bean移动到主应用程序上下文中.

通常,我们建议在服务层而不是单个Web控制器上应用方法安全性.

如果将切入点应用于服务层,则只需<global-method-security>在应用程序的安全上下文中进行设置.


and*_*ndy 17

如果你使用的是Spring 3.1,你可以用它来做一些非常酷的东西.请查看https://github.com/mohchi/spring-security-request-mapping.这是一个示例项目,它将@PreAuthorize与Spring MVC的RequestMappingHandlerMapping集成在一起,以便您可以执行以下操作:

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

@RequestMapping("/")
public String homePage() {
    return "homePage";
}
Run Code Online (Sandbox Code Playgroud)

如果用户通过身份验证,请求"/"将调用authenticatedHomePage().否则它将调用homePage().


dom*_*nik 9

这是两年多以来,这一问题被提出,但由于问题今天我有我宁愿反对使用@Secured,@PreAuthorize等上@Controller秒.

什么对我不起作用@Validated@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) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

验证器根本不会触发(Spring MVC 4.1.2,Spring Security 3.2.5)并且不执行任何检查.

类似的问题是由Spring使用的CGLIB代理引起的(当没有类由类实现时,Spring创建CGLIB代理;如果类实现了任何接口,那么生成JDK代理 - 文档,这里这里都有很好的解释).

正如我在上面链接的答案中所提到的,最好在通常实现接口的服务层上使用Spring Security注释(因此使用JDK Proxies),因为这不会导致此类问题.

如果您想要保护Web控制器,更好的想法是使用<http><intercept-url />绑定到特定URL而不是控制器中的方法,并且工作得很好.就我而言:

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

    ...

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

</http>
Run Code Online (Sandbox Code Playgroud)


Olg*_*zek 6

已经有关于如何通过更改xml配置使其工作的回复; 但是,如果您正在使用基于代码的配置,则可以通过在@Configuration类上放置以下注释来实现相同的功能:

@EnableGlobalMethodSecurity(prePostEnabled=true)
Run Code Online (Sandbox Code Playgroud)