Могу ли я использовать как GlobalMethodSecurityConfiguration, так и WebSecurityConfigurerAdapter в приложении Spring

В моем приложении есть классы конфигурации 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;
    }

Любой вход приветствуется...

Ответы

Ответ 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

Вы можете переопределить метод configure (AuthencationManagerBuilder auth) в WebSecurityConfigurerAdapter. Если ваше требование просто использует ваш UserDetailsService, вы можете сделать это ниже

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

Из вашего кода вы можете использовать метод ниже.

authenticationManagerBuilder.authenticationProvider(AuthenticationProvider authenticationProvider)

Если у вас более сложное требование, вы можете обратиться к API безопасности spring. http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.html