SpringBoot:集成Shiro之拦截器配置


前言


前面的几篇博客都是说的用户如何认证,如何授权,那么用户认证授权之后,我们该如何使用这些信息呢?这里我们就需要使用到Shiro框架中的拦截器功能.通过拦截器功能实现用户权限和角色的应用,下面我们就来看一下我们如何使用拦截器实现用户权限认证的应用.


拦截器分类说明


在配置拦截器之前,我们需要先了解Shiro本身给我们提供的拦截器都有什么,都有着什么样的特点.下面我们就来用表格的形式来看一下各种拦截器的特点.

简写(加粗为常用) 名称 优先级(1为最高) 说明 对应Java类
anon 匿名拦截器 1 不需要登录就能访问,一般用于静态资源,或者移动端接口 org.apache.shiro.web.filter.authc.AnonymousFilter
authc 登录拦截器 2 需要登录认证才能访问的资源 org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic Http拦截器 3 Http身份验证拦截器,非常用类型,不太了解 org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logout 登出拦截器 4 用户登出拦截器,主要属性:redirectURL退出登录后重定向的地址 org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation 不创建会话拦截器 5 调用 subject.getSession(false) 不会有什么问题,但是如果 subject.getSession(true) 将抛出 DisabledSessionException 异常 org.apache.shiro.web.filter.authc.NoSessionCreationFilter
prems 权限拦截器 6 验证用户是否拥有资源权限 org.apache.shiro.web.filter.authc.PermissionsAuthorizationFilter
port 端口拦截器 7 其主要属性: port(80) 如果用户访问该页面是非 80,将自动将请求端口改为 80 并重定向到该 80 端口 org.apache.shiro.web.filter.authc.PortFilter
rest rest风格拦截器 8 rest 风格拦截器,自动根据请求方法构建权限字符串构建权限字符串;非常用类型拦截器 org.apache.shiro.web.filter.authc.HttpMethodPermissionFilter
roles 角色拦截器 9 验证用户是否拥有资源角色 org.apache.shiro.web.filter.authc.RolesAuthorizationFilter
ssl SSL拦截器 10 只有请求协议是https才能通过,否则你会自动跳转到https端口(443) org.apache.shiro.web.filter.authc.SslFilter
user 用户拦截器 11 用户拦截器,用户已经身份验证 / 记住我登录的都可; org.apache.shiro.web.filter.authc.UserFilter

我们通过上面的表格可以轻松的分别每一种拦截器的优先级,这样假设某个资源访问同时设置了两个或者多个拦截器,我们可以清楚的知道拦截器的执行顺序,从而方便我们进行一些操作.


INI文件配置拦截器


我曾经在SpringBoot:集成Shiro之INI配置篇说过[urls]模块.但是,说的不是太详细.在这个模块,我们就来详细的看一下如何使用INI文件的形式配置过滤器.

在配置之前,我们还需要重述一下 拦截器的通配符的写法,如下所示.

?:匹配一个字符
*:匹配零个或多个字符
**:匹配零个或多个路径

然后,我们看一下[urls]模块的示例.这里我只用到了一些常用的拦截器

[urls]
#不需要登录
/login=anon
/static/**=anon
#需要登录
/home=authc
#需要角色
/deleteUser = roles["superAdmin"]
#需要用户权限
/addUser = perms["user:create"]

但是,我们发现一个问题,假设用户没有该权限和没有该角色,或者没有登录的时候,还有登出的时候,我们都需要给他们配置对应的重定向路径.这时候,我们就不能在[urls]模块中使用了,我们需要在[main]模块中进行各个情况路径的重定向设置了.示例代码如下所示.

[main]
#用户登录的地址
authc.loginUrl = /login
#用户没有对应角色的跳转重指向
roles.unauthorizedUrl = /login
#用户没有对应权限的跳转重指向
perms.unauthorizedUrl = /login
#用户登出的跳转重指向
logout.redirectUrl = /login
注意:INI文件中 [urls] 模块拦截顺序是从上往下依次执行.


代码形式配置拦截器


使用INI文件配置拦截器是较为简洁的配置形式,其实质就是通过Bean注入的形式配置拦截器 接下来我们看一下我们如何通过代码形式配置拦截器.

由于是使用的SpringBoot:集成Shiro之自定义Realm实现认证授权项目中的代码配置,那么,我们就看一下上一节都配置了什么吧,我们配置了核心安全事务管理器 和自定义的权限登录器.代码如下所示.

@Configuration
public class ShiroConfiguration {
    //配置核心安全事务管理器
    @Bean(name="securityManager")
    public DefaultWebSecurityManager securityManager(@Qualifier("myShiroRealm") MyShiroRealm myShiroRealm) {
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
        manager.setRealm(myShiroRealm);
        return manager;
    }
    //配置自定义的权限登录器
    @Bean(name="myShiroRealm")
    public MyRealm authRealm() {
        MyRealm myShiroRealm=new MyRealm();
        return myShiroRealm;
    }
}

我们继续配置拦截器模块的代码.整体代码如下所示.

    @Bean(name="shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        //配置登录的url和登录成功的url以及验证失败的url
        bean.setLoginUrl("/login");
        bean.setSuccessUrl("/home");
        bean.setUnauthorizedUrl("/login");
        //配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/loginUser", "anon");
        filterChainDefinitionMap.put("/static/*", "anon");
        filterChainDefinitionMap.put("/logout*","anon");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

比较过来,依然发现,使用INI文件形式配置拦截器要比代码形式更加简洁.


拦截器的简单使用


现在我们来拿/html/login = anon/html/home = authc以及设置重定向的authc.loginUrl = /html/login来简单说明一下,具体应该如何使用.

我们想让SpringBoot项目支持Html格式的访问,那么我们需要在pom.xml文件中加入如下的Maven依赖.

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

同时,我们要在application.properties文件中配置如下信息.设置HTML的存放路径,

spring.thymeleaf.prefix=classpath:/templates/
spring.mvc.view.suffix=.html

目录结构如下所示.

然后,我们把ShiroConfiguration配置文件进行如下的配置.

@Configuration
public class ShiroConfiguration {

    @Bean(name="shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        //配置登录的url和登录成功的url以及验证失败的url
        bean.setLoginUrl("/index");
        bean.setSuccessUrl("/home");
        bean.setUnauthorizedUrl("/index");
        //配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/index", "anon");
        filterChainDefinitionMap.put("/home", "authc");
        filterChainDefinitionMap.put("/**","anon");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

    //配置核心安全事务管理器
    @Bean(name="securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
        return manager;
    }

}

我们在resources目录下创建两个html页面,一个login.html,一个home.html,其中代码如下所示.

login

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>

<div style="text-align: center;margin-top: 100px; font-size: 20px;">用户登录界面</div>

</body>
</html>

home

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页面</title>
</head>
<body>

<div style="text-align: center;margin-top: 100px; font-size: 20px;">Home界面</div>

</body>
</html>

然后我们需要编写两个接口来访问login.html和home.html.这里我创建了一个名为HtmlController的控制器.整体代码较为简单,这里就直接黏贴出所有代码了.如下所示.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

@Controller
public class HtmlController {

    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public String userLoginHtmlAction (){
        return "index";
    }

    @RequestMapping(value = "/home",method = RequestMethod.GET)
    public String userHomeHtmlAction (){
        return "home";
    }

}

然后我们就会猜想有如下情况出现,假设我们可以直接通过浏览器访问/html/login,那么我们会直接访问到login.html ,但是当我们访问/html/home的时候,由于我们没有进行用户登录认证(根本就没有做登录接口.😁),所以我们不可能通过认证,通过登录重指向,浏览器仍然会展示login.html 页面,下面我们就启动项目来验证一下.如下所示,拦截成功.


结语(未完待续)


Shiro的拦截器已经配置完成了,下一篇博客我们将来说一下如何在网页中使用权限管理标签,欢迎继续关注骚栋.

Demo传送门


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,626评论 18 139
  • 前言 前面的两篇博客使用了INI的形式完成了用户的认证授权操作.我曾经多次在博客中提到过INI文件形式进行认证授权...
    神经骚栋阅读 27,870评论 5 28
  • 白色的、小团小团的柳絮刚刚从我眼前飘过,这温暖季节的产物正在四面八方游荡。阳光下,行人的脚步匆匆,踩散了许多团。如...
    江葆和阅读 252评论 2 3
  • 人生就是这样,有所得必有所失,不因得到而沾沾自喜,不因失去而郁郁寡欢。 得到了工作,失去了陪伴 很多人纠结是工作还...
    风中蓝荷阅读 385评论 0 2
  • 今天没干什么,因为都在西安上特训 看了水浒传电视剧 认识了我们的潜能 7:00到10:00都在特训
    霍奕含阅读 120评论 0 0