shiro----------------3.过滤器

/**
 * anon(匿名)、logout(登出)、authc(认证)
 */
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager, ShiroService shiroService) {
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setSecurityManager(securityManager);
    shiroFilter.setLoginUrl("/user/no/login");
    shiroFilter.setSuccessUrl("/user/success");
    shiroFilter.setUnauthorizedUrl("/user/fail");
    Map<String, Filter> filterMap = new LinkedHashMap<>(1);
    //自定义角色过滤器
    filterMap.put("roles", rolesAuthorizationFilter());
    shiroFilter.setFilters(filterMap);
    // 过滤链可以使用注解形式实现
    shiroFilter.setFilterChainDefinitionMap(shiroService.loadFilterChainDefinitions());
    return shiroFilter;
}

/**
 * 自定义角色过滤器
 */
@Bean
public CustomRolesAuthorizationFilter rolesAuthorizationFilter() {
    return new CustomRolesAuthorizationFilter();
}

1.创建了一个过滤器管理类FilterChainManager,该类主要管理shiro里的过滤器,里面有2个重要的属性 
1.1 filters:管理全部过滤器,包括默认的关于身份验证和权限验证的过滤器,这些过滤器分为两组,一组是认证过滤器,有anon,authcBasic,auchc,user,一组是授权过滤器,有perms,roles,ssl,rest,port。同时也包含在xml里filters配置的自定义过滤器。在其它地方使用时都是从过滤器管理类里filters里拿的。且过滤器是单例的,整个Shiro框架只维护每种类型过滤器的单例,可以自己实现过滤器,只需配置对应的过滤链来匹配。 
1.2 filterChains:过滤链。shiroService.loadFilterChainDefinitions()这里单独实现过滤链

2.将过滤器管理类设置到PathMatchingFilterChainResolver类里,该类负责路径和过滤器链的解析与匹配。根据url找到过滤器链。

重写一个角色过滤器

/**
 * 自定义角色授权过滤器
 */
public class CustomRolesAuthorizationFilter extends RolesAuthorizationFilter {

    @Override
    public boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) {
        Subject subject = getSubject(req, resp);
        String[] rolesArray = (String[]) mappedValue;
        //如果没有角色限制,直接放行
        if (rolesArray == null || rolesArray.length == 0) {
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++) {
            //若当前用户是rolesArray中的任何一个,则有权限访问
            if (subject.hasRole(rolesArray[i])) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        boolean isAccess = isAccessAllowed(request, response, mappedValue);
        if (isAccess) {
            return true;
        }
        servletResponse.setCharacterEncoding("UTF-8");
        Subject subject = getSubject(request, response);
        PrintWriter printWriter = servletResponse.getWriter();
        servletResponse.setContentType("application/json;charset=UTF-8");
        servletResponse.setHeader("Access-Control-Allow-Origin", servletRequest.getHeader("Origin"));
        servletResponse.setHeader("Access-Control-Allow-Credentials", "true");
        servletResponse.setHeader("Vary", "Origin");
        String respStr;
        if (subject.getPrincipal() == null) {
            respStr =JSONObject.toJSONString(KeyValue.forbidden("您还未登录,请先登录"));
        } else {
            respStr =JSONObject.toJSONString(KeyValue.forbidden("您没有此权限,请联系管理员"));
        }
        printWriter.write(respStr);
        printWriter.flush();
        servletResponse.setHeader("content-Length", respStr.getBytes().length + "");
        return false;
    }

}

采用编码式配置过滤链

/**
 * 初始化权限 anon(匿名)、logout(登出)、authc(认证)
 */
@Override
public Map<String, String> loadFilterChainDefinitions() {
    List<Authority> authorities = authorityMapper.selectAll();
    // 权限控制map.从数据库获取
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    if (!CollectionUtils.isEmpty(authorities)){
        for (Authority authority : authorities) {
            if (StringUtils.isEmpty(authority.getPermission())) {
                continue;
            }
            String uris = authority.getUri();
            List<String> uriList = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(uris));
            uriList.forEach(x-> filterChainDefinitionMap.put(x, authority.getPermission()));
        }
    }
    filterChainDefinitionMap.put("/user/no/login", "anon");
    filterChainDefinitionMap.put("/user/login", "anon");
    filterChainDefinitionMap.put("/user/logout", "anon");
    filterChainDefinitionMap.put("/test/*", "anon");
    filterChainDefinitionMap.put("/redis/*", "roles[admin]");
    filterChainDefinitionMap.put("/**", "authc");
    return filterChainDefinitionMap;
}

权限存储的格式:roles[admin,普通用户] 

 

 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值