Spring Security:@PreAuthorized(“hasAuthority()”)未被检查

时间:2014-01-14 22:58:45

标签: spring-security

根据Spring Security 3.2.0文档,我创建了一个Spring Security配置并在getRootConfigClasses中引用它:

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[]{RootConfiguration.class, SpringSecurityConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SpringWebConfiguration.class};
}

我可以证明这主要是因为Spring Security强制用户按照我的配置登录。问题在于方法安全性。我用@EnableGlobalMethodSecurity注释了SpringSecurityConfig,如下所示:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

然后在我的控制器中注释一个方法:

@PreAuthorize("hasAuthority('ROLE_ADMIN')")

的想法是只允许那些使用ROLE_ADMIN访问此控制器方法的人。但是,使用ROLE_USER和ROLE_ADMIN登录的用户可以调用此方法,而不是预期的方法。

通过修改我的Web应用程序初始化程序以加倍包含Spring Security配置它开始工作,但我想对我的根上下文中的方法以及Web上下文使用方法身份验证,我似乎无法做发生:

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[]{RootConfiguration.class, SpringSecurityConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SpringSecurityConfig.class, SpringWebConfiguration.class};
}

每个上下文是否都需要自己的安全配置?或者父上下文中的一个应该是否足够?

感谢。

1 个答案:

答案 0 :(得分:2)

我终于设法有一个根上下文,带有子Web上下文,并且@Pre和@Post授权注释适用于控制器。

诀窍是公开在RootContext中创建的AuthenticationProvider,默认情况下不会公开。

所以,我的设置是:

@Order(1)
public class SecurityWebAppInitializer extends AbstractSecurityWebApplicationInitializer {}



@Order(2)
public class ApiDispatcherInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfiguration.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { ApiWebMvcConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/*" };
    }
}


@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // IMPORTANT: to expose it to the WebContext
    @Bean(name = "myAuthenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}



@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.PROXY, proxyTargetClass = true) // <-- IMPORTANT to make it work for controllers
@ComponentScan(basePackageClasses = { foo.bar.Package.class }, useDefaultFilters = false, includeFilters = { @Filter(Controller.class) })
public class WebMvcConfig extends WebMvcConfigurerAdapter {

}

希望这可能有助于某人。