【问题标题】:Can I use both a GlobalMethodSecurityConfiguration and a WebSecurityConfigurerAdapter in a Spring app我可以在 Spring 应用程序中同时使用 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter
【发布时间】:2014-04-25 22:48:06
【问题描述】:

我的应用程序同时具有 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter 配置类。我的实现如下:

我的 GlobalMethodSecurityConfiguration 实现

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {

    @Override
    protected AuthenticationManager authenticationManager() {
        AuthenticationManager authenticationManager = new ProviderManager();
        return authenticationManager;
    }

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(permissionEvaluator());
        return expressionHandler;
    }

    @Bean
    public ApplicationPermissionEvaluator permissionEvaluator() {
        return new ApplicationPermissionEvaluator(permissionMap());
    }

    private Map<String, Permission> permissionMap() {
        Map<String, Permission> map = new HashMap<>();
        map.put("CurriculumService:findCurriculumIsAllowed", curriculumByIdOwnerPermission());
        map.put("CurriculumService:updateCurriculumIsAllowed", curriculumOwnerPermission());

        return map;
    }

    @Bean(autowire=Autowire.BY_NAME)
    public CurriculumByIdOwnerPermission curriculumByIdOwnerPermission() {
        return new CurriculumByIdOwnerPermission();
    }

    @Bean(autowire=Autowire.BY_NAME)
    public CurriculumOwnerPermission curriculumOwnerPermission() {
        return new CurriculumOwnerPermission();
    }

}

和我的 WebSecurityConfigurerAdapter 实现

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //@formatter:off
        http
        //.csrf().disable()
        .exceptionHandling().authenticationEntryPoint(delegatingAuthenticationEntryPoint())
        .and().formLogin()
            .loginProcessingUrl("/signin")
            .loginPage("/signin")
            .failureUrl("/signin?login_error=t")
            .defaultSuccessUrl("/dashboard", Boolean.TRUE)
        .and().logout()
            .logoutUrl("/resources/j_spring_security_logout")
            .logoutSuccessUrl("/signin")
        .and().authorizeRequests()
            .accessDecisionManager(accessDecisionManager())
            .antMatchers("/preference/sendPasswordReset/**", "/preference/passwordReset/**", "/preference/activateEmail/**", "/preference/resendActivationEmail/**").permitAll()
            .antMatchers("/preference/**").access("hasAnyRole('ROLE_BASIC_CHILDMINDER', 'ROLE_BASIC_FAMILY')")
            .antMatchers("/dashboard").access("hasAnyRole('ROLE_BASIC_CHILDMINDER', 'ROLE_BASIC_FAMILY')")
            .antMatchers("/curriculum/**").access("hasRole('ROLE_BASIC_CHILDMINDER')")
            .antMatchers("/advertisement/**/view/**").permitAll()
            .antMatchers("/advertisement/family/**").access("hasRole('ROLE_BASIC_FAMILY')")
            .antMatchers("/advertisement/childminder/**").access("hasRole('ROLE_BASIC_CHILDMINDER')")
            .antMatchers("/resources/**", "/**").permitAll();
        //@formatter:on
        super.configure(http);
    }

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

    @Bean
    public MemberUserDetailsService userDetailsService() {
        return new MemberUserDetailsService();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder;
    }

    @Bean
    public SessionRegistryImpl sessionRegistry() {
        SessionRegistryImpl sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }

    @Bean
    public AffirmativeBased accessDecisionManager() {
        AffirmativeBased accessDecisionManager = new AffirmativeBased(accessDecisionVoters());
        return accessDecisionManager;
    }

    public List<AccessDecisionVoter> accessDecisionVoters() {
        List<AccessDecisionVoter> accessDecisionVoters = new ArrayList<>();
        accessDecisionVoters.add(roleHierarchyVoter());
        accessDecisionVoters.add(webExpressionVoter());
        return accessDecisionVoters;
    }

    @Bean
    public WebExpressionVoter webExpressionVoter() {
        WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
        webExpressionVoter.setExpressionHandler(defaultWebSecurityExpressionHandler());
        return webExpressionVoter;
    }

    @Bean
    public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
        DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
        defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
        return defaultWebSecurityExpressionHandler;
    }

    @Bean
    public RoleHierarchyVoter roleHierarchyVoter() {
        RoleHierarchyVoter roleHierarchyVoter = new RoleHierarchyVoter(roleHierarchy());
        return roleHierarchyVoter;
    }

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        //@formatter:off
        roleHierarchy.setHierarchy(
                "ROLE_ADMINISTRATOR > ROLE_MODERATOR\n" +
                "ROLE_MODERATOR > ROLE_SUBSCRIBED_FAMILY\n" +
                "ROLE_MODERATOR > ROLE_SUBSCRIBED_CHILDMINDER\n" +
                "ROLE_SUBSCRIBED_FAMILY > ROLE_BASIC_FAMILY\n" +
                "ROLE_SUBSCRIBED_CHILDMINDER > ROLE_BASIC_CHILDMINDER");
        //@formatter:on
        return roleHierarchy;
    }

    @Bean
    public DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() {
        DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint = new DelegatingAuthenticationEntryPoint(map());
        delegatingAuthenticationEntryPoint.setDefaultEntryPoint(loginUrlAuthenticationEntryPoint());
        return delegatingAuthenticationEntryPoint;
    }

    public LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map() {
        LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = new LinkedHashMap<>();
        map.put(ajaxRequestMatcher(), ajaxAuthenticationEntryPoint());
        return map;
    }

    @Bean
    public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint() {
        LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/signin");
        return loginUrlAuthenticationEntryPoint;
    }

    @Bean
    public AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint() {
        AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint = new AjaxAuthenticationEntryPoint();
        return ajaxAuthenticationEntryPoint;
    }

    @Bean
    public AjaxRequestMatcher ajaxRequestMatcher() {
        AjaxRequestMatcher ajaxRequestMatcher = new AjaxRequestMatcher();
        return ajaxRequestMatcher;
    }

    @Bean
    public RequestDataValueProcessor requestDataValueProcessor() {
        return new CsrfRequestDataValueProcessor();
    }
}

我不确定如何配置身份验证管理器。以下是正确的处理方式吗?

 @Override
    protected AuthenticationManager authenticationManager() {
        AuthenticationManager authenticationManager = new ProviderManager();
        return authenticationManager;
    }

欢迎任何意见...

【问题讨论】:

  • 您的配置是否有任何特定异常?我也有,我得到一个“java.lang.IllegalArgumentException:期望只找到一个类型接口org.springframework.security.authentication.AuthenticationManager的bean,但找到[]”
  • 我处于类似的情况,并且由于在上下文中找不到 AuthenticationManager 而导致 BeanInitializationException。我不确定如何进行。有什么建议吗?什么解决了你的问题?

标签: spring-security


【解决方案1】:

我也在寻找一种方法来做到这一点。以下对我有用:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
    @Autowired
    protected void configureGlobal (AuthenticationManagerBuilder auth) {
        // Configure auth mgr
    }

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        // Configure expression handler
    }

    @Configuration
    public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Configure HTTP security
        }
    }
}

【讨论】:

    【解决方案2】:

    您可以覆盖 WebSecurityConfigurerAdapter 中的 configure(AuthencationManagerBuilder auth) 方法。如果您的要求只是使用您的 UserDetailsS​​ervice,您可以执行以下操作

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());
    }
    

    从您的代码中,您可以使用以下方法。

    authenticationManagerBuilder.authenticationProvider(AuthenticationProvider authenticationProvider)
    

    如果你有更复杂的需求,你可以参考spring security API。 http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.html

    【讨论】:

    • 你好。你的意思是?能详细点吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2018-10-15
    • 2018-12-16
    相关资源
    最近更新 更多