6

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

下面的配置是我的servlet 配置,它在控制器层启用自定义安全注释。

<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 config 取代,但不是现在。这是我的一些安全配置:

<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 配置,在控制器层启用安全性@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 []

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

有人有一些提示吗?谢谢

4

2 回答 2

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 的安全性,该参考提供了如何配置方法安全性表达式处理程序的示例。

@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;
    }
}
于 2014-02-04T13:57:40.687 回答
3

首先,您需要一个单独的配置类,例如

@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().....
}
于 2014-02-04T13:52:34.077 回答