有没有办法读取Spring Security元数据?

时间:2018-10-31 13:25:32

标签: spring-mvc spring-boot spring-security

我正在使用Spring安全性,我有一个自定义授权过滤器,没有显式的URL映射。我在UsernamePasswordAuthenticationFilter.class之后添加了我的授权过滤器。

这种方法的问题是,即使允许或通过身份验证允许的URL模式都通过我的授权过滤器。我不想在授权过滤器上显式配置过滤器映射,因为我觉得这是多余的(已经存在于WebSecurityConfigurerAdapter中)。无论如何,我是否可以访问Spring Security元数据或以其他任何方式跳过标记为allowAll()或authenticated()的URL的授权过滤器?

public class AuthorizationFilter implements Filter {

    public void destroy() {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
        throws IOException, ServletException {

        //Calls a webservice to fetch the authorities based on the URL pattern.
        //Adds the authentication principal with Authorities to SecurityContextHolder.
    }

    public void init(FilterConfig config) throws ServletException {

    }
}

1 个答案:

答案 0 :(得分:0)

我通过扩展WebExpressionVoter来解决此问题,如下所示:

public class CustomAuthoritiesVoter extends WebExpressionVoter {

    private static final String SUPPORTED_CLASS = "org.springframework.security.web.access.expression.WebExpressionConfigAttribute";


    @Override
    public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
        String exp = getExpressionString(attributes);

        if (null != exp && !StringUtils.equalsAny(exp, "authenticated", "permitAll")) {
            //Call service to fetch the authorities based on the userID and URL
            //Set Authentication principal along with fetched Authorities using SecurityContextHolder
        }

        return super.vote(authentication, fi, attributes);
    }

    private String getExpressionString(Collection<ConfigAttribute> attributes) {
        try {
            for (ConfigAttribute attribute : attributes) {
                if (attribute.getClass().isAssignableFrom(Class.forName(SUPPORTED_CLASS))) {
                    return attribute.toString();
                }
            }
        } catch (ClassNotFoundException e) {
            log.warn(e.getMessage(), e);
        }

        return null;
    }
}