Springboot 集成Shiro自定义Filter

来源:互联网 发布:ktv软件 编辑:程序博客网 时间:2024/06/07 23:08

网上自定义Filter的实现很多,这里我提供一种Springboot在代码中的实现。

Shiro提供的Filter我这里不一一介绍了,一般基于web会话的都是使用authc(这是FormAuthenticationFilter)。根据我无状态的登陆需求,选择了AccessControlFilter,网上也有说这个是最被广泛使用的,具体还是看自己需求吧。

Filter代码:

/** * @author Created by pangkunkun on 2017/11/18. */public class MyAccessControlFilter extends AccessControlFilter {    private static final Logger log= LoggerFactory.getLogger(MyAccessControlFilter.class);    /**     *     * 表示是否允许访问;mappedValue就是[urls]配置中拦截器参数部分,如果允许访问返回true,否则false;     * (感觉这里应该是对白名单(不需要登录的接口)放行的)     * 如果isAccessAllowed返回true则onAccessDenied方法不会继续执行     * 这里可以用来判断一些不被通过的链接(个人备注)     * * 表示是否允许访问 ,如果允许访问返回true,否则false;     * @param servletRequest     * @param servletResponse     * @param object 表示写在拦截器中括号里面的字符串 mappedValue 就是 [urls] 配置中拦截器参数部分     * @return     * @throws Exception     * */    @Override    public boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object object) throws Exception{//        Subject subject = getSubject(servletRequest,servletResponse);//        String url = getPathWithinApplication(servletRequest);//        log.info("当前用户正在访问的 url => " + url);//        log.info("subject.isPermitted(url);"+subject.isPermitted(url));        return false;    }    /**     * 表示当访问拒绝时是否已经处理了;如果返回true表示需要继续处理;如果返回false表示该拦截器实例已经处理了,将直接返回即可。     * onAccessDenied是否执行取决于isAccessAllowed的值,如果返回true则onAccessDenied不会执行;如果返回false,执行onAccessDenied     * 如果onAccessDenied也返回false,则直接返回,不会进入请求的方法(只有isAccessAllowed和onAccessDenied的情况下)     * */    @Override    public boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception{        System.out.println("onAccessDenied");        String username=request.getParameter(Constant.CRS_KEY);        String signature=request.getParameter(Constant.SIGNATURE);        String type=request.getParameter("type");        //TODO 通过其它参数验证signature的正确性        String digestValue=MD5Utils.MD5SendParame(signature);        MyUsernamePasswordToken token=new MyUsernamePasswordToken(username,type, digestValue);        Subject subject= SecurityUtils.getSubject();        try {            subject.login(token);        }catch (Exception e){            log.info("登陆失败");            log.info(e.getMessage());            onLoginFail(response);            return false;        }        log.info("登陆成功");        return true;    }

继承这个filter 要实现两个方法,每个方法我都有给出解释。

isAccessAllowed这里,根据从网上找的实现,我感觉这个是类似白名单被放行的。如果有些特殊的url不需要登录,可以直接在这里通过,或者做其它的判断。当然,这里也可以砸Shiro配置中直接把相应的方法对应的filter栏设置成none,同样不会经过这里。

onAccessDenied是我主要逻辑功能处理的模块。在这里主要是UsernamePasswordToken这块,生成token对象后使用subject进行登录,以便后边方法中权限/角色的验证。

将自定义filter集成进shiro配置:

@Bean    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){        log.info("ShiroConfiguration.shirFilter()");        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();        // 必须设置 SecurityManager        shiroFilterFactoryBean.setSecurityManager(securityManager);        //自定义拦截器        Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();        filtersMap.put("myAccessControlFilter", new MyAccessControlFilter());        shiroFilterFactoryBean.setFilters(filtersMap);        //拦截器.        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();        filterChainDefinitionMap.put("/createPermission", "anon");        filterChainDefinitionMap.put("/**", "myAccessControlFilter");        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return shiroFilterFactoryBean;    }
        //自定义拦截器        Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();        filtersMap.put("myAccessControlFilter", new MyAccessControlFilter());        shiroFilterFactoryBean.setFilters(filtersMap);

这块代码是将自定义的拦截器设置进shiro的filterchain中。

filterChainDefinitionMap.put("/**", "myAccessControlFilter");

这里是设置使用自定义拦截器的url。我这里设置的是,如果没有其他拦截器定义的,都有走这个自定义的拦截器。

完整代码可以参考我前面文章Spring Boot集成无状态Shiro–内容详细介绍。

原创粉丝点击