【问题标题】:How to write a custom filter in spring security?如何在 Spring Security 中编写自定义过滤器?
【发布时间】:2012-08-09 08:20:57
【问题描述】:

我想为每个请求接收一些信息,所以我认为不是为每个请求提供一个函数并分别从请求中获取这些信息,最好有一个过滤器。
所以每个请求都应该通过那个过滤器,我得到我想要的。


问题是:如何编写自定义过滤器?
假设它不像任何预定义的 spring 安全过滤器,它是全新的。

【问题讨论】:

    标签: spring filter spring-security


    【解决方案1】:

    您可以使用标准的 Java 过滤器。只需将它放在 web.xml 中的身份验证过滤器之后(这意味着它将在过滤器链中稍后并在安全过滤器链之后调用)。

    public class CustomFilter implements Filter{
    
        @Override
        public void destroy() {
            // Do nothing
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res,
                FilterChain chain) throws IOException, ServletException {
    
                HttpServletRequest request = (HttpServletRequest) req;
    
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    
                Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
                if (roles.contains("ROLE_USER")) {
                    request.getSession().setAttribute("myVale", "myvalue");
                }
    
                chain.doFilter(req, res);
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
            // Do nothing
        }
    
    }
    

    web.xml 片段:

    <!-- The Spring Security Filter Chain -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- Your filter definition -->
    <filter>
        <filter-name>customFilter</filter-name>
        <filter-class>com.yourcompany.test.CustomFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>customFilter</filter-name>
        <url-pattern>/VacationsManager.jsp</url-pattern>
    </filter-mapping>
    

    您还可以添加成功登录后将调用的处理程序(您需要扩展SavedRequestAwareAuthenticationSuccessHandler)。 Look here 怎么做。我认为这是一个更好的主意。


    更新:
    或者,您可以在安全过滤器的末尾添加此过滤器,如下所示:

    <security:filter-chain-map>
        <sec:filter-chain pattern="/**"
                filters="
            ConcurrentSessionFilterAdmin, 
            securityContextPersistenceFilter, 
            logoutFilterAdmin, 
            usernamePasswordAuthenticationFilterAdmin, 
            basicAuthenticationFilterAdmin, 
            requestCacheAwareFilter, 
            securityContextHolderAwareRequestFilter, 
            anonymousAuthenticationFilter, 
            sessionManagementFilterAdmin, 
            exceptionTranslationFilter, 
            filterSecurityInterceptorAdmin,
            MonitoringFilter"/> <!-- Your Filter at the End -->
    </security:filter-chain-map>
    

    要拥有你的过滤器,你可以使用这个:

    public class MonitoringFilter extends GenericFilterBean{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //Implement this Function to have your filter working
    }
    

    【讨论】:

    • 在等待答案的过程中,我想出了一个解决方案。我在我的安全过滤器末尾添加了我的过滤器(扩展 GenericFilterBean)。它工作得很好。但是现在,当我看到您的回答时,对我来说听起来更好。我正在尝试您的解决方案。希望它也有效。我会让你知道结果。谢谢。
    • 一般你的答案是正确的,但我必须稍微修改一下。感谢您的帮助。
    • 好的。修改我的答案,我将接受您的更改。知道我错在哪里对我来说会很有趣。
    • 你没有错。你的答案是正确的。我希望将我的解决方案(与您的解决方案非常相似)包含在此处以供以后使用。
    • 是的,您的解决方案也很好。但是在这种情况下,我们需要定义所有过滤器(甚至是默认过滤器),如果我们错过了一个,那么它将不会被调用。我说的对吗?
    【解决方案2】:

    只是把这个混在一起;在http 元素中使用custom-filter 怎么样:

    <security:http auto-config="false" ...>
      ...
      <security:custom-filter position="FORM_LOGIN_FILTER" ref="MyCustomFilter" />
    </security:http>
    

    【讨论】:

    • 这是迄今为止最好的解决方案。我想先运行我自己的过滤器:
    • 我可以在 中添加模式吗
    猜你喜欢
    • 2011-08-23
    • 2014-07-28
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多