如何在 Spring Security 中编写自定义过滤器?

Posted

技术标签:

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

我想为每个请求接收一些信息,所以我认为不是为每个请求提供一个函数并分别从请求中获取这些信息,最好有一个过滤器。 所以每个请求都应该通过那个过滤器,我得到我想要的。 问题是:如何编写自定义过滤器?假设它不像任何预定义的 spring 安全过滤器,它是全新的。

【问题讨论】:

【参考方案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>

【讨论】:

这是迄今为止最好的解决方案。我想先运行我自己的过滤器: 我可以在 中添加模式吗

以上是关于如何在 Spring Security 中编写自定义过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 入门 我们在篇中已经谈到了默认的登录页面以及默认的登录账号和密码。 在这一篇中我们将自己定义登录页面及账号密码。 我们先从简单的开始吧:设置自定

使用 Spring Security 和 Grails 注销后如何将用户重定向到不同的页面

不推荐使用属性“security.basic.enabled”:不再可自定义安全自动配置

spring security相关认证类详解

Spring Security应用开发(05)自定义表单认证

如何从 Spring Security 中的 java 代码登录用户?