第七节 shiro自带的拦截器分析
一、Shiro框架携带的拦截器
首先来温故一下最常见的shiro拦截器。anon表示不拦截,authc表示需要认证,roles表示需要某种角色,perms就更狠了,直接表明需要某种权限。ssl是https相关的拦截器,上次项目中客户要求以https方式启动项目,当时是项目经理配置的,我暂时还没有掌握这种拦截器。
anon:匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤;示例“/static/**=anon”
authc:认证拦截器,用户需要认证,如果没有认证,将会重定向到的登录页面。
roles:角色授权拦截器,验证用户是否拥有所有角色;示例 /actions/**=roles[admin],发送任何以actions开头的请求,都需 要admin角色。
perms:权限授权拦截器,验证用户是否拥有所有权限;示例 /user/**=perms["user:create"]”
logout:退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址。示例 /logout=logout
----------------------------------------下面的我没有实践过-----------------------------------------------
port:示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口
ssl :SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样;
二、shiro.ini配置文件分析
好,为了快速上手,我们直接编写例子,省去一些令人打瞌睡的理论阐述。 下面已经编写好了一个简单的shiro.ini配置文件。让我们来逐行分析吧。
main目录下配置了拦截器的相关属性。
authc拦截器是认证拦截器,如果某个请求经过配置了authc拦截器,那么authc拦截器先验证用户是否已经认证成功。如果没有认证成功,它就会将此请求重定向到 loginUrl属性中规定的路径。查看当前配置文件的配置authc.loginUrl = /login,如果用户没有认证,那么用户发送的请求就会被重定向为: /login。
roles.unauthorized 与 perms.unauthorizedUrl 配置的是 角色拦截器与权限拦截器的属性。用户发送的请求中,如果使用了roles与perms拦截器,那么shiro将会先检查当前用户是否有相关的角色信息或者权限信息。如果没有,则重定向用户请求。本配置文件中roles.unauthorizedUrl = /403.jsp将用户请求重定向到 根目录下的403.jsp页面。
logout是退出拦截器。它的redirectUrl属性规定了用户退出后跳转的路径。
例如有如下的配置,logout.redirectUrl = /login,则退出系统后让它直接跳转到登录页。
users目录下配置了用户、角色、权限的相关属性。
系统中有一个合法的帐号密码:jay/123。它的角色是coder,拥有权限 code:insert 与 code:update。
url目录下配置了哪些请求需要使用哪些拦截器。/sys/home = authc 的意思是当用户发送/sys/home请求时,需要先被authc认证拦截器拦截。authc拦截器先查看当前用户是否已经登录,如果没有登录,则根据 [ main ] 下的配置 authc.loginUrl = / login ,将/sys/home请求重定向为 /login 请求。
#shiro.ini配置文件
[main]
#认证页面
authc.loginUrl = /login
#若没有相关角色或者权限信息则跳转403.jsp页面
roles.unauthorizedUrl = /403.jsp
perms.unauthorizedUrl = /403.jsp
#退出后跳转系统的登录页面
logout.redirectUrl = /login
[users]
#帐号jay,密码123。此人是一个coder角色
#所以拥有code:insert、code:update两种权限
jay = 123,coder
[roles]
coder = code:insert,code:update
[url]
#发送/sys/home请求需要先登录
/sys/home = authc
#提交代码需要code:insert权限
/code/submit = perms["code:insert"]
#更新代码需要code:update权限
/code/update = perms["code:update"]
#发送退出请求则用退出拦截器
/logout = logout
三、如何在web项目中使用拦截器
本来想把如何在WEB中使用拦截器写清楚了,但是发现会贴上非常多的代码,与其贴上大量的代码,不如先用文字来描述。由于代码较多,所以将代码放到了下一小节。现在,先让我们了解一下Shiro在WEB中的常见的使用方式。
authc拦截器在登录时的使用
就我个人经历过的使用Shiro的项目而言,一般用户的登录请求都是通过 $ajax 异步调用。先通过 JQuery 获取到用户输入的用户名、密码,然后向后台发送请求。后台SpringMVC捕获到此请求,将帐号密码解析成一个token对象,再交付给Shiro的Subject对象去认证。你可能会有点好奇应该怎么做。我贴一下核心代码,你可能就明白了。
前台在收到后台登录成功的JSON数据后,一般会跳转系统主页。而进入系统主页的路径也是需要经过authc拦截器拦截的。但是在刚才的登录操作中,subject.login(token);已经验证成功,所以authc拦截器直接放行进入系统主页的请求。
如何使用权限拦截器
一般来说,不会直接使用shiro自带的perms拦截器。常见的使用方法是,用户自定义一个权限拦截器。
权限判断的前提条件是用户已经登录。最常见的方式是,用户在自定义Realm中,重写doGetAuthorizationInfo方法时,会将当前用户的所有权限查询出来,并存放到主凭证对象的map集合中。当用户登录成功后,在访问某种资源的时候,我们自定义的权限拦截器就要发挥作用了。
首先从Subject中获取到用户的主凭证,主凭证是一个对象,不再是以前的username。主凭证对象中很可能拥有一个map集合,它可能映射的是 权限名称----资源路径。在拦截器中,先从请求头中获取即将访问的URL的链接。判断要访问的链接是不是在我们允许的权限范围之内。如果不在的话,则驳回此次请求。
return subject.isPermitted( principal.getResourceMap.getPermissionByURL( requestHeaderURL ) );
----------------------------------------------------分割线-------------------------------------------------------
下一篇: 第八节 与WEB集成实例分析
阅读更多:跟着大宇学Shiro目录贴