Shiro 集成 Spring 之过滤器

前言

在之前 Shiro 集成 Spring 这一章中我们简单使用了 shiroFilter 中的 filterChainDefinitions 来做 认证授权 的拦截,其实还有许多过滤器,可以做各种各样的拦截,并且 Shiro 还提供了接口来让我们自定义过滤器。

身份认证相关

anon

例:/admins/**=anon,没有参数,表示可以匿名使用。

authc

例:/admins/user/**=authc,没有参数,表示需要认证(登录)才能使用。

authcBasic

例:/admins/user/**=authcBasic,没有参数,表示 httpBasic 认证。

user

例:/admins/user/**=user ,没有参数,表示必须存在用户(不一定已通过认证),只要曾被 Shiro 记住过登录状态的用户就可以正常发起请求,比如 rememberMe)。

logout

例:/logout=logout,没有参数,注销当前登陆用户,成功后会重定向地址到 /

授权相关

roles

例:/admins/user/**=roles[admin],参数可以写多个,用逗号分割,当有多个参数时,例如 admins/user/**=roles[admin, guest],每个参数通过才算通过,相当于 hasAllRoles() 方法。

perms

例:/admins/user/**=perms[user:add:*],参数可以写多个,用逗号分割,如:/admins/user/**=perms[user:add:*, user:modify:*],当有多个参数时必须每个参数都通过才通过,想当于 isPermitedAll() 方法。

port

例: /admins/user/**=port[8081],单个参数,当请求的 url 的端口不是 8081 时重定向到 schemal://hostName:8081?queryString, 也就是说,除了端口,其他东西都会保留。

rest

例:/admins/user/**=rest[user],根据请求的方法,相当于 /admins/user/**=perms[user:method],其中method为post,get,delete等。

ssl

例:/admins/user/**=ssl 没有参数,表示安全的 url 请求,协议为 https,其实也等同于 /admin/user/**=port[443],即重定向到 443 端口。

自定义过滤器

roles 过滤器为例:/admin/page1= roles["admin, user"] ,表示 /admin/page1 这个页面必须需要用户同时具备 adminuser 角色才可访问。

我们开发一个自定义的过滤器,判定需要 adminuser 可访问。

package im.zhaojun.filter;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AnyRolesFilter extends AuthorizationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        Subject subject = this.getSubject(request, response);
        String[] rolesArray = (String[]) ((String[]) mappedValue);
        if (rolesArray != null && rolesArray.length != 0) {
            for (String role : rolesArray) {
                if (subject.hasRole(role)) {
                    return true;
                }
            }
        } else {
            return true;
        }
        return false;
    }
}

注:这里用到了 ServletRequestServletResponse 类,所以还需要导入相应的库:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

然后将其配置到 IOC 容器中:

<bean id="anyRolesFilter" class="im.zhaojun.filter.AnyRolesFilter"/>

最后为其分配别名,并添加到过滤器链中:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 略 -->
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = anon
                /login = anon
                /user.jsp = anyRoles[user, admin]
                /userList.jsp = perms[select:delete]
                /logout = logout
                /** = authc
            </value>
        </property>
        <property name="filters">
            <map>
                <entry key="anyRoles" value-ref="anyRolesFilter"/>
            </map>
        </property>
    </bean>

我们分别将 /user.jsp 设为 roles[user, admin]anyRoles[user, admin]

目前 Relam 中的用户 zhao - 123456 仅具备 user 角色,所以可以分别测试出,anyRoles 过滤的页面可以正常访问,而 roles 过滤器的内容因未同时具备 useradmin 角色而被拦截,跳转到未授权页面。

通配符

上面的示例中,我们还用到了 ** 做通配符,其实还有几个通配符:

?:匹配一个字符,如 /admin? 可以匹配 /admin1/admin2,但不能匹配 /admin

*:匹配零个或一个或多个字符,如 /admin* 可以匹配 /admin/admin1/admin123,但不能匹配 /admin/123

**:匹配零个或多个路径,如 /admin/** 可以匹配 /admin/admin/a/b/c

本章代码地址 : https://github.com/zhaojun1998/Premission-Study/tree/master/Permission-Shiro-07/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

分布式文件存储的数据库开源项目MongoDB

MongoDB是一个基于分布式文件存储的数据库开源项目。由C++语言编写。旨在为WEB应用提供可护展的高性能数据存储解决方案。 它的特点是高性能、易部署、易使用...

39190
来自专栏技术之路

go微服务框架go-micro深度学习(一) 整体架构介绍

      产品嘴里的一个小项目,从立项到开发上线,随着时间和需求的不断激增,会越来越复杂,变成一个大项目,如果前期项目架构没设计的不好,代码会越来越臃肿,难以...

2.3K30
来自专栏JetpropelledSnake

Python入门之logging日志模块以及多进程日志

本篇文章主要对 python logging 的介绍加深理解。更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件。 1. ...

1.2K70
来自专栏Android自学

解决wordpress搬家后,主题、插件升级时出现“无法创建目录”的问题

20930
来自专栏jeremy的技术点滴

处理一个NodeJS程序内存泄露的问题

42290
来自专栏nummy

巧妙使用Image对象将js错误记录到服务器端

如果我们想要将js的错误信息记录到服务器数据库库中,我们一般想到的是通过ajax来实现。 其实这样做有几个弊端:

8520
来自专栏大内老A

[WCF安全系列]谈谈WCF的客户端认证[用户名/密码认证]

对于基于Internet的应用,基于用户名和密码的认证方式是最为常用的,而WCF为你提供了不同模式的用户名认证方式。首先还是从用户凭证的表示说起。 一、用户名/...

23590
来自专栏我和PYTHON有个约会

06.python解释器及性能优化

上一节我们简单了解了python程序运行的过程,并且大家也都了解到开发环境中有一个python解释器(PVM)的存在,那在python中,这样的解释器主要都有哪...

11720
来自专栏Java3y

Shiro第二篇【授权、整合Spirng、过滤器】

前言 本文主要讲解的知识点有以下: Shiro授权的方式简单介绍 与Spring整合 初始Shiro过滤器 一、Shiro授权 上一篇我们已经讲解了Shiro的...

395100
来自专栏安恒网络空间安全讲武堂

Python编写渗透工具学习笔记二 | 0x02利用FTP与web批量抓肉鸡

0x02利用FTP与web批量抓肉鸡 脚本要实现的目标和思路: 先尝试匿名登录ftp,当匿名登录失败时再尝试用用户/密码爆破登录,登录成功后,脚本会搜索ftp中...

1.8K70

扫码关注云+社区

领取腾讯云代金券