当前位置:  开发笔记 > 编程语言 > 正文

如何仅为特定URL添加Spring Security验证码过滤器

如何解决《如何仅为特定URL添加SpringSecurity验证码过滤器》经验,为你挑选了1个好方法。

我正在寻找一种非侵入性的方法来为某些api调用添加验证码过滤器.

我的设置包括两个WebSecurityConfigurerAdapters,每个都有一个过滤器(不是验证码过滤器):

内部api("/ iapi"在所有呼叫上使用过滤器A,但也忽略一些公共请求,如/ authenticate)

外部api("/ eapi"在所有呼叫中使用过滤器B)

如何在Spring Security内容,公共内部api或外部api调用之前添加过滤器?我不需要SecurityContext,只需要检查请求头中的Captcha,转发到filterChain(普通过滤器)或手动拒绝访问.我尝试在web.xml中声明一个过滤器,但这会破坏使用依赖注入的能力.

这是我的Spring安全配置:

@EnableWebSecurity
public class SpringSecurityConfig {
    @Configuration
    @Order(1)
    @EnableGlobalMethodSecurity(securedEnabled = true)
    public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private Filter filterA;

        public InternalApiConfigurerAdapter() {
            super(true);
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/public/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/iapi/**")
                    .exceptionHandling().and()
                    .anonymous().and()
                    .servletApi().and()
                    .authorizeRequests()
                    .anyRequest().authenticated().and()
                    .addFilterBefore(filterA, (Class) UsernamePasswordAuthenticationFilter.class);
        }

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return authenticationManager();
        }
    }

    @Configuration
    @Order(2)
    @EnableGlobalMethodSecurity(securedEnabled = true)
    public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private FilterB filterB;

        public ExternalApiConfigurerAdapter() {
            super(true);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/external/**")
                    .exceptionHandling().and()
                    .anonymous().and()
                    .servletApi().and()
                    .authorizeRequests()
                    .anyRequest().authenticated().and()
                    .addFilterBefore(filterB, (Class) UsernamePasswordAuthenticationFilter.class);
        }

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return authenticationManager();
        }
    }

更新:目前我有一个工作配置,在web.xml中声明了一个过滤器.但是,它的缺点是与Spring Context分离(例如没有bean的自动装配),所以我正在寻找一个利用Spring的更好的解决方案.

摘要:还有两个问题:

    仅为特定URL添加过滤器- 在任何配置中使用beforeFilter(...)会向该配置的所有URL添加过滤器.Antmatchers没有工作.我需要这样的东西:/ iapi/captcha/,/ external/captcha /,/ public/captcha/*.

    我有一个完全绕过Spring Security的公共API :( web .ignoring().antMatchers("/ public/**");).我需要绕过Spring Security,但仍使用Spring自动装配声明过滤器,但不一定是Spring Security功能,因为我的验证码过滤器只能以无状态方式拒绝或转发呼叫.

saljuama.. 7

您已经有一个工作配置,之前插入了过滤器A和B,UsernamePasswordAuthenticationFilter因此应该很容易添加另一个自定义过滤器.

首先,创建过滤器,并将其声明为bean,或者使用@Component或者作为类的@Bean内部注释@Configuration类,以便可以注入它@Autowired.

现在您可以将其作为过滤器A和B注入,并使用它.根据Spring Security参考文档中的Filter Ordering部分,链中的第一个Filter是ChannelProcessingFilter,所以为了在Spring Security过滤器链中的任何其他内容之前插入过滤器,您可以这样做:

@Autowired
private CaptchaFilter captchaFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .antMatcher("/iapi/**")
            .addFilterBefore(captchaFilter, (Class) ChannelProcessingFilter.class)
            .addFilterBefore(filterA, (Class) UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .anyRequest().authenticated();
    }

顺便说一句,exceptionHandling() anonymous()并且servletApi()不需要,因为在扩展时WebSecurityConfigurerAdapter,这些已经包含在内,除非anonymous()您实际指定了更多配置详细信息,因为它声明了HttpSecurityjavadoc

请记住Spring Security"入口点",DelegatingFilterProxy仍然会在过滤器之前执行,但是这个组件只将请求委托给链中的第一个过滤器,在本例中是CaptchaFilter,所以你真的会执行你的在Spring Security之前进行过滤.

但是如果您仍然希望在之前执行验证码过滤器DelegatingFilterProxy,则无法在Spring Security配置中执行此操作,您需要在web.xml文件中声明它.


更新:如果您不希望在其他配置中包含验证码过滤器,您可以随时添加第三个配置,配置类如下:

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig {

    @Configuration
    @Order(1)
    public static class CaptchaApiConfigurerAdatper extends WebSecurityConfigurerAdapter {

        @Autowired
        private CaptchaFilter captchaFilter;

        public CaptchaApiConfigurerAdatper() {
            super(true);
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/public/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .requestMatchers()
                        .antMatcher("/iapi/captcha**")
                        .antMatcher("/external/captcha**")
                        .and()
                    .addFilterBefore(captchaFilter, (Class) ChannelProcessingFilter.class)
                    .authorizeRequests()
                        .anyRequest().authenticated();
        }
    }            

    @Configuration
    @Order(2)
    public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

        // ommiting code for the sake of clarity
    }

    @Configuration
    @Order(3)
    public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

         // ommiting code for the sake of clarity
    }

顺便说一句,另一个提示,你可以将特定配置之外的所有常见配置重构为主类,如@EnableGlobalMethodSecurity(securedEnabled = true)AuthenticationManager,WebSecurity以跳过公众的安全性,但对于那些因为主类没有扩展任何你应该@Autowire的方法声明.

虽然会有一个问题了WebSecurity,如果你是忽略/public/**了的匹配HttpSecurity/public/captcha**将被忽略,所以我想,你不应该重构出来的WebSecurity,并有在CaptchaConfig类不同的模式,以便它不重叠.



1> saljuama..:

您已经有一个工作配置,之前插入了过滤器A和B,UsernamePasswordAuthenticationFilter因此应该很容易添加另一个自定义过滤器.

首先,创建过滤器,并将其声明为bean,或者使用@Component或者作为类的@Bean内部注释@Configuration类,以便可以注入它@Autowired.

现在您可以将其作为过滤器A和B注入,并使用它.根据Spring Security参考文档中的Filter Ordering部分,链中的第一个Filter是ChannelProcessingFilter,所以为了在Spring Security过滤器链中的任何其他内容之前插入过滤器,您可以这样做:

@Autowired
private CaptchaFilter captchaFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .antMatcher("/iapi/**")
            .addFilterBefore(captchaFilter, (Class) ChannelProcessingFilter.class)
            .addFilterBefore(filterA, (Class) UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .anyRequest().authenticated();
    }

顺便说一句,exceptionHandling() anonymous()并且servletApi()不需要,因为在扩展时WebSecurityConfigurerAdapter,这些已经包含在内,除非anonymous()您实际指定了更多配置详细信息,因为它声明了HttpSecurityjavadoc

请记住Spring Security"入口点",DelegatingFilterProxy仍然会在过滤器之前执行,但是这个组件只将请求委托给链中的第一个过滤器,在本例中是CaptchaFilter,所以你真的会执行你的在Spring Security之前进行过滤.

但是如果您仍然希望在之前执行验证码过滤器DelegatingFilterProxy,则无法在Spring Security配置中执行此操作,您需要在web.xml文件中声明它.


更新:如果您不希望在其他配置中包含验证码过滤器,您可以随时添加第三个配置,配置类如下:

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig {

    @Configuration
    @Order(1)
    public static class CaptchaApiConfigurerAdatper extends WebSecurityConfigurerAdapter {

        @Autowired
        private CaptchaFilter captchaFilter;

        public CaptchaApiConfigurerAdatper() {
            super(true);
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/public/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .requestMatchers()
                        .antMatcher("/iapi/captcha**")
                        .antMatcher("/external/captcha**")
                        .and()
                    .addFilterBefore(captchaFilter, (Class) ChannelProcessingFilter.class)
                    .authorizeRequests()
                        .anyRequest().authenticated();
        }
    }            

    @Configuration
    @Order(2)
    public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

        // ommiting code for the sake of clarity
    }

    @Configuration
    @Order(3)
    public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {

         // ommiting code for the sake of clarity
    }

顺便说一句,另一个提示,你可以将特定配置之外的所有常见配置重构为主类,如@EnableGlobalMethodSecurity(securedEnabled = true)AuthenticationManager,WebSecurity以跳过公众的安全性,但对于那些因为主类没有扩展任何你应该@Autowire的方法声明.

虽然会有一个问题了WebSecurity,如果你是忽略/public/**了的匹配HttpSecurity/public/captcha**将被忽略,所以我想,你不应该重构出来的WebSecurity,并有在CaptchaConfig类不同的模式,以便它不重叠.

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有