如何在spring security中编写自定义过滤器?

Mat*_* Kh 47 spring filter spring-security

我希望每个请求都能收到一些信息,所以我认为不是每个请求都有一个函数,而是单独从请求中获取这些信息,最好有一个过滤器.
因此,每个请求都应通过该过滤器,并获得我想要的.


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

dim*_*mas 46

您可以使用标准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
    }

}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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


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

<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>
Run Code Online (Sandbox Code Playgroud)

要拥有您的过滤器,您可以使用:

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
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,你的解决方案也很好.但在这种情况下,我们需要定义所有过滤器(即使是默认值),如果我们错过了一个,那么它就不会被调用.我对吗? (4认同)

Ith*_*har 15

把它扔进混合物中; 如何使用custom-filter内部http元素:

<security:http auto-config="false" ...>
  ...
  <security:custom-filter position="FORM_LOGIN_FILTER" ref="MyCustomFilter" />
</security:http>
Run Code Online (Sandbox Code Playgroud)