1

In my shiro application, I want to define a AuthenticationFilter for all paths except REST.

ie /rest/... doesnt go through it but everything else would.

I'm using Shiro-Guice so my filter setups are of the form

addFilterChain("/rest/**" ,restFilter)
addFilterChain("/**", filter)    //I want this one to work on everything except my rest filter

I looked at this question about Ant path pattern style but there doesnt seem to be support for regexes.

Community
  • 1
  • 1
user2573153
  • 254
  • 2
  • 14
  • What you're asking for works out of the box even with the default `AntPathMatcher`. Shiro uses [first match wins](http://shiro.apache.org/web.html#urls-) policy for filter chains as well as for filters inside a chain. – Pavel Mitrofanov Oct 10 '17 at 22:20

2 Answers2

3

You can't do it like that. The way shiro works is that it checks the filters in the order they are configured. It first checks the first filter, if it can't authenticate, it will move on to the next. There is no exclusion pattern for that.

You can write your own custom shiro filter that will deny authrorization on de rest url.

I don't know how it will work in guice, but in shiro.ini you can do something like:

[main]
myfilter = UrlBasedAuthzFilter
restFilter = YourRestFilterClass
[urls]
/rest/** = restFilter
/** = myfilter

And the filter class:

public class UrlBasedAuthzFilter extends AuthorizationFilter {

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        if (request.getServletContext().getContextPath().startsWith("/rest"){
            return false;
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }
}
Wouter
  • 3,976
  • 2
  • 31
  • 50
  • 1
    So it turns out you can do it. You can change the pattern matcher on the filter to a `RegexPatternMatcher` instead of the `Ant` matcher. Then you can just use java regexes. I still prefer your way though. – user2573153 Sep 18 '14 at 18:36
  • Ah, I hadn't thought of that. Good find! – Wouter Sep 18 '14 at 19:06
-1
@Bean("shiroFilter")
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) {
    ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

    Map<String, Filter> filterMap = new LinkedHashMap<>();
    filterMap.put("adminLoginFilter", new AdminLoginFilter());
    filterMap.put("jwtAdminAuthcFilter", new JwtAdminAuthcFilter());
    factoryBean.setFilters(filterMap);

    factoryBean.setSecurityManager(securityManager);
    factoryBean.setUnauthorizedUrl("/401");

    Map<String, String> filterRuleMap = new LinkedHashMap<>();
    filterRuleMap.put("/admin/auth/login","adminLoginFilter");
    filterRuleMap.put("/admin/**", "jwtAdminAuthcFilter");
    filterRuleMap.put("/401", "anon");

    factoryBean.setFilterChainDefinitionMap(filterRuleMap);
    return factoryBean;
}
  • 1
    Can you please add an explanation (some comments would do, too) to your answer? A code-only answer is not all that helpful since it does not further _understanding_ of the problem. Even if the code works, inexperienced programmers will have no idea why and would benefit from an explanation. – O.O.Balance Jun 27 '18 at 03:00