Spring:通过java配置在Controller层中启用全局方法安全性

时间:2014-02-04 13:38:10

标签: java spring spring-mvc spring-security spring-java-config

我正在尝试将我的xml servlet配置迁移到java配置。

以下配置是我的 servlet配置,它可以在Controller层上启用自定义安全注释。

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="expressionHandler" class="yyy.MyMethodSecurityExpressionHandler" />

我还有一个有效的spring security xml配置,即为了被java配置替换,但现在还没有。这里有一些我的安全配置:

<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
    </bean>

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <constructor-arg>
         <ref bean="authenticationProvider"/>
    </constructor-arg>
</bean>

<security:authentication-manager>
    <security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>

<security:global-method-security pre-post-annotations="enabled" />

我想开始迁移 servlet config ,在Controller层中启用安全@PreAuthorize@PostAuthorize标记。

我找到了这个注释:@EnableGlobalMethodSecurity(prePostEnabled=true),但把它放在我的servlet配置上:

@Configuration
@ComponentScan(basePackages= {
        "....."         
})
@EnableGlobalMethodSecurity(prePostEnabled=true)

public class WebappServletConfig extends WebMvcConfigurationSupport {

我得到了这个例外:

java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []

此外,我不知道如何设置我的自定义表达式处理程序!

某人有一些提示吗?谢谢

2 个答案:

答案 0 :(得分:5)

更新(更新后的问题)

您似乎遇到了SEC-2479。有几种方法可以解决这个问题。最简单的方法是使用@Autowired的结果作为AuthenticationManager。为此,您必须扩展GlobalMethodSecurityConfiguration并覆盖authenticationManager方法。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Autowired
    private AuthenticationManager am;

    @Override
    protected AuthenticationManager authenticationManager() {
        return am;
    }
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        // ... create and return custom MethodSecurityExpressionHandler ...
        return expressionHander;
    }
}

原始答案

您需要配置某种身份验证。所以你需要有以下内容:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
}

如果您没有使用基于Web的安全性,那么reference provides an example如何配置方法安全表达式处理程序。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        // ... create and return custom MethodSecurityExpressionHandler ...
        return expressionHander;
    }
}

如果您只想要一个自定义方法表达式处理程序来提供权限评估程序,那么您只需要创建一个这样的PermissionEvaluator bean:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
    @Bean
    public PermissionEvaluator permissionEvaluator() {
        // ... create and return custom PermissionEvaluator ...
        return permissionEvaluator;
    }
}

答案 1 :(得分:3)

首先,您需要一个单独的Configuration类,如

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {...

您需要定义

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
}

应该有助于你的例外。

我不知道如何配置expressionHandler,但似乎你可以在configure(WebSecurity web)中调整它

@Override
public void configure(WebSecurity web) throws Exception {
    web.expressionHandler().....
}