如何以编程方式配置过滤器链?

Posted

技术标签:

【中文标题】如何以编程方式配置过滤器链?【英文标题】:How to configure the filter chain programmatically? 【发布时间】:2018-01-23 06:51:07 【问题描述】:

有没有办法根据上述users roleuser 访问特定[URL] 进行编程限制。 例如,在shiro.ini 文件中,您可以定义:

      [urls]
      ...
  1.  /app/**= user

可以在代码中定义filter chain,如下所示:

 .....

 UserFilter user = new UserFilter();//create user filter
 user.setLoginUrl("login.xhtml");


FilterChainManager fcMan = new DefaultFilterChainManager();
fcMan.addFilter("user", user);//add filter to filter chain
fcMan.createChain("/app/**", "user");//define url path expression for filterName

.....

我的问题是如何使用roles 实现这一点,就像我在shiro.ini 文件中所做的那样:

[urls]
...
/api/admin/**= user, roles[admin]
...

例如:

RolesAuthorizationFilter adminRole = new RolesAuthorizationFilter();//eg create role filter      
adminRole.setLoginUrl("login.xhtml");
UserFilter user = new UserFilter();//create user filter
user.setLoginUrl("login.xhtml");


FilterChainManager fcMan = new DefaultFilterChainManager();

fcMan.addFilter("user", user);
fcMan.addFilter("admin", adminRole);      
fcMan.createChain("/api/admin/**", "admin");

【问题讨论】:

我不确定我是否完全遵循,您是否希望直接针对当前主题检查访问权限?即 subject.hasRole("ADMIN") shiro.apache.org/subject.html 或者您是否尝试以编程方式配置过滤器链,如果是,您使用的是哪个框架,可能已经有更简单的方法(Spring、Guice 等?) 我正在尝试以编程方式配置过滤器链,并且我正在使用 javaee7 @Brain 我接受了一个回答,在浏览了filterChainManager#createChain 的文档之后,我得到了它。感谢您有兴趣提供帮助。 【参考方案1】:

我是《Pairing Apache Shiro and Java EE 7》一书的作者,您可以免费获取here。

在本书中,我以编程方式编写了所有 Shiro 组件,而无需 shiro.ini 文件。

我使用 CDI 事件来生成 FilterChainResolver

@Produces
public FilterChainResolver getFilterChainResolver() 
    FilterChainResolver filterChainResolver = null;
    if (filterChainResolver == null) 
        FormAuthenticationFilter authc = new FormAuthenticationFilter();
        AnonymousFilter anon = new AnonymousFilter();
        UserFilter user = new UserFilter();

        authc.setLoginUrl(WebPages.LOGIN_URL);
        user.setLoginUrl(WebPages.LOGIN_URL);

        FilterChainManager fcMan = new DefaultFilterChainManager();
        fcMan.addFilter("authc", authc);
        fcMan.addFilter("anon", anon);
        fcMan.addFilter("user", user);

        fcMan.createChain("/index.html", "anon");
        fcMan.createChain("/css/**", "anon");
        fcMan.createChain("/api/**", "anon");
        fcMan.createChain(WebPages.LOGIN_URL, "authc");
        fcMan.createChain("/**", "user");

        PathMatchingFilterChainResolver resolver = new PathMatchingFilterChainResolver();
        resolver.setFilterChainManager(fcMan);
        filterChainResolver = resolver;
    
    return filterChainResolver;

接下来,我们将 FilterChainResolver 注入:

@WebListener
public class ShiroListener extends EnvironmentLoaderListener 

    @Inject
    WebSecurityManager securityManager;

    @Inject
    FilterChainResolver filterChainResolver;

    @Override
    protected WebEnvironment createEnvironment(ServletContext sc) 
        DefaultWebEnvironment webEnvironment = (DefaultWebEnvironment) super.createEnvironment(sc);

        webEnvironment.setSecurityManager(securityManager);
        webEnvironment.setFilterChainResolver(filterChainResolver);

        return webEnvironment;
    
    ...

现在,FilterChainResolver 被应用,一切都会如愿以偿。

【讨论】:

谢谢你,先生,你救了我的命:D 我为你感到高兴@Kaizen ;-)

以上是关于如何以编程方式配置过滤器链?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式添加 servlet 过滤器?

WCF路由如何以编程方式添加备份列表

执行自定义过滤器 UsernamePasswordAuthenticationFilter 后如何以编程方式返回 json 响应?

struts2入门之拦截器

如何以编程/动态方式将组件添加到 p:dataTable facet

使用 NSFetchedResultsController 如何以编程方式设置 5 个部分以显示以及过滤它们以获取适当的行