在java配置中添加http安全过滤器

jen*_*gar 28 java spring spring-security

我试图在春季添加网络安全性,但我不希望过滤器适用于某些事情.怎么在java中完成?

也许还有更好的方法,因为我创建了一个自定义过滤器,但这是我认为实例化它的唯一方法,因为它的依赖性.

总的来说,我想做的是:

/resources/**不应该通过过滤器, /login(POST)不应该通过过滤器,其他一切都应该通过过滤器

通过我在春天发现的各种例子我能够想出一个开始,但它显然不起作用:

@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    public void configure(WebSecurity webSecurity) throws Exception
    {
        webSecurity.ignoring().antMatchers("/resources/**");
    }

    @Override
    public void configure(HttpSecurity httpSecurity) throws Exception
    {
        httpSecurity
                .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .antMatchers("/login").permitAll();

        httpSecurity.httpBasic();
        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    @Autowired
    public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor(MyTokenUserInfoCache userInfoCache, ServerStatusService serverStatusService, HttpSecurity httpSecurity) throws Exception
    {
        TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
        TokenFilterSecurityInterceptor<TokenInfo> tokenFilter = new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");
        httpSecurity.addFilter(tokenFilter);
        return tokenFilter;
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*nch 27

您是否对所有Spring Security忽略URL感兴趣,或者您是否只希望该特定过滤器忽略该请求?如果您希望所有Spring Security都忽略该请求,可以使用以下命令完成:

@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyTokenUserInfoCache userInfoCache;
    @Autowired
    private ServerStatusService serverStatusService;

    @Override
    public void configure(WebSecurity webSecurity) throws Exception
    {
        webSecurity
            .ignoring()
                // All of Spring Security will ignore the requests
                .antMatchers("/resources/**")
                .antMatchers(HttpMethod.POST, "/login");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .addFilter(tokenInfoTokenFilterSecurityInterceptor())
            .authorizeRequests()
                // this will grant access to GET /login too do you really want that?
                .antMatchers("/login").permitAll()
                .and()
            .httpBasic().and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor() throws Exception
    {
        TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
        return new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您只想让特定的Filter忽略特定请求,您可以执行以下操作:

@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyTokenUserInfoCache userInfoCache;
    @Autowired
    private ServerStatusService serverStatusService;

    @Override
    public void configure(WebSecurity webSecurity) throws Exception
    {
        webSecurity
            .ignoring()
                // ... whatever is here is ignored by All of Spring Security
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .addFilter(tokenInfoTokenFilterSecurityInterceptor())
            .authorizeRequests()
                // this will grant access to GET /login too do you really want that?
                .antMatchers("/login").permitAll()
                .and()
            .httpBasic().and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor() throws Exception
    {
        TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
        TokenFilterSecurityInterceptor tokenFilter new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");


        RequestMatcher resourcesMatcher = new AntPathRequestMatcher("/resources/**");
        RequestMatcher posLoginMatcher = new AntPathRequestMatcher("/login", "POST");
        RequestMatcher ignored = new OrRequestMatcher(resourcesMatcher, postLoginMatcher);
        return new DelegateRequestMatchingFilter(ignored, tokenService);
    }
}


public class DelegateRequestMatchingFilter implements Filter {
    private Filter delegate;
    private RequestMatcher ignoredRequests;

    public DelegateRequestMatchingFilter(RequestMatcher matcher, Filter delegate) {
        this.ignoredRequests = matcher;
        this.delegate = delegate;
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
         HttpServletRequest request = (HttpServletRequest) req;
         if(ignoredRequests.matches(request)) {
             chain.doFilter(req,resp,chain);
         } else {
             delegate.doFilter(req,resp,chain);
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我知道每个人都在使用它,但我看不到 `configure(HttpSecurity http)` 中长方法链的优势,尤其是考虑到类型会随之变化。如果我们删除那些 `and()` 并编写一个新的 `http.something()` 语句,不是更清楚吗?我在这里缺少什么? (2认同)

mvb*_*b13 1

1 在 spring-security 的 xml 配置中我使用

<http pattern="/resources/**" security="none"/> 

<http use-expressions="true">
<intercept-url pattern="/login" access="permitAll"/> 
</http>    
Run Code Online (Sandbox Code Playgroud)

从安全检查中检索它。

2 之后mvc:resource在你的 spring 配置中添加标签

<mvc:resources mapping="/resource/**" location="/resource/"/>
Run Code Online (Sandbox Code Playgroud)

重要提示:此配置仅在 url 由调度程序 servlet 处理时才有效。这意味着在 web.xml 中你必须有

   <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping> 
Run Code Online (Sandbox Code Playgroud)