2019独角兽企业重金招聘Python工程师标准>>>
目前jfinal使用shiro进行身份验证和授权的后台实现已完成,现在我再来总结下学习过程及代码实现过程。最近半年多项目开发都用.net,但又不甘心用了一年多的java,jfinal就这样被废弃,所以就准备业余时间自己用jfinal搭个框架,做点什么,具体做什么,还没想好,先搭好框架再说。用jfinal实现增删改查很简单,从官网下个demo来改改就好了,但是要做个包括有身份验证及授权完善的系统,就要稍微花点功夫了。
一、做一些简单的jfinal的配置(如数据库配置,路由配置)后,要学习一下java比较流行且成熟的身份验证授权框架shiro,shiro这个东西乍眼一看觉得挺简单的,可深入去研究一下,发现他使用挺简单,但它的实现原理并没有那么简单,个人觉得学习shiro的过程,不只是学习它的使用,更多的是学习它的思想,它用的各种模式,我也说不上来,目前大概也就知道个单例模式和工厂模式,总之,就是高大上和不明觉厉。学习shiro还在路上,由此也激发了我想了解设计模式的欲望。下面再来总结下这两周学习的shiro吧,不梳理下把他放在脑子里过一久又当垃圾丢了,学了东西总要在脑子了刻下点什么东西,对不对?
二、shiro API理解
1、Shiro能帮我们完成认证、授权、加密、会话管理、与Web集成、缓存等功能。目前我主要学习了认证,授权和web继承。
2、Shiro的对外API主要有:Subject,SecurityManager,Realm,三者关系如下:
(1)Subject(api核心):主体,代表当前用户,所有Subject都会被绑定到SecurityManager。
(2)SecurityManager(shiro核心):管理所有Subject,并且与Subjec的t所有交互,都是委托SecurityManager来实现的。
(3)realm:用于获取用户身份和拥有权限,即如判断用户名和密码是否匹配,判断用户是否拥有某些权限。
三、shiro身份认证和授权流程步骤大体如下:
1、先收集用户身份和凭证,如用户名和密码,并将其转换为token,传递给Subject进行认证和授权,而Subject又委托给SecurityManager。
2、在realm进行身份认证和授权,认证是判断输入用户名和密码是否正确的过程,认证成功后才能授权,在这里会通过用户id获取该用户拥有的所有角色和所有权限,以供后面判断该用户是否有权限访问特定资源。
以上步骤做好用户认证和授权的准备工作,接下来就是怎么给资源(如方法)加访问控制权限,比如用户列表只有拥有“用户管理”权限的人才能看见,那么怎么加这个限制呢?
3、shiro提供jsp标签和java注解,用来判断用户是否拥有某些资源的权限,这里我用java注解。shiro提供了五种注解,只需将这些注解定义在想要安全控制的方法上即可。
(1)RequiresGuest:加此注解的方法可被匿名用户访问
(2)RequiresUser:加此注解的方法只能被已登录的用户访问(包括:已认证或已记住)
(3)RequiresAuthentication:加此注解的方法只能被已认证的用户访问(不包括已记住)
(4)RequiresRoles:加此注解的方法仅被指定角色的用户访问
(5)RequiresPermissions:加此注解的方法仅被指定权限的用户访问
4、接下来j要做的事情就是,怎么在访问一个方法时获取这个方法的注解里的角色/权限,并与第2步获得的用户拥有的角色/权限做比较,如果用户拥有的角色/权限包含了此方法上注解里的角色/权限,那么,用户就可以调用该方法,如果不包含,则用户将不能调用该方法,并返回到一个提示未授权的页面。现在问题来了,像jfinal这样的web框架怎么使用shiro拦截所有请求,判断是否已认证或有权限呢?
(1)在web.xml中配置如下节点
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"><listener><listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class></listener> <filter><filter-name>ShiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class></filter><filter-mapping><filter-name>ShiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>
通过上面的配置,EnvironmentLoaderListener在容器启动时初始化SecurityManager,通过ShiroFilter拦截请求并完成认证与授权。
(2)具体获取每个方法上的注解,并判断用户是否有权限调用该方法,大飞已经实现了,用他的就可以。