Shiro 学习笔记(1)—— Hello World
什么是 Shiro?
百度百科上对 Shiro 的概括是非常准确的:
Apache Shiro是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码学和会话管理。
在这里,我就直接拿来使用了。Shiro 是一个安全框架,可以保护你的应用,替你完成身份验证、权限设置、加密、解密、与会话相关的操作。
两个重要的概念:认证、授权
学习 Shiro 之前,我们要明确两个非常重要的概念:1、身份认证;2、授权。
说明:认证(Authentication)和授权(Authorization)这两个单词刚开始学习的时候会常常看错,请大家注意。
认证简单的说,就是登录的时候判断你的用户名和密码是否完全匹配,就是证明你是你。
授权,是在认证的基础之上,进行角色和权限的授予。权限决定了一个用户可以进行怎样的操作。就像你到学校去,你出示了你的学生证以后,学校这个机构要授权给你进学生食堂、宿舍的权力。
由于你的角色是学生,你不能随意进教师办公室,说明你没有进入教师办公区域的权力。
另外两个重要的概念:角色、权限
权限定义了一个用户是否可以执行某个操作。角色就是一组权限的集合。我们通常是把一组权限绑定到一种角色上,再把一个或者多个角色赋给一个用户,这样就实现了权限的控制。即权限通过角色定义到用户上。角色作为权限的集合,方便了我们对权限的管理。
这一节,我们使用 Shiro 帮助我们实现一个小小的登录功能。这个登录的功能没有界面,就是通过简单的用户名密码匹配来实现的。但是我们须要借助 Shiro 来完成。
在以前的项目中,我们做登录的时候,总是把用户名和密码数据放在数据库的数据表对应的字段中。当然 Shiro 也提供了这样的功能,只不过不须要我们自己编写从数据库查询数据,然后进行字符串匹配的代码编写(这个例子我们下一节讲)。
当然,将用户名和密码写在配置文件里、使用 Shiro 提供的 JDBC Realm 不是我们在生产环境下的做法,这两种安全数据源的配置,仅供我们理解、研究和测试 Shiro 这个框架而使用。
测试代码的思路:
将用户登录的用户名和密码信息(以键值对方式)存放在一个配置文件里,然后我们在一个 Main 方法中输入待登录的用户名和密码,使用某个登录的方法,进行登录。
实现步骤:
1、引入 Gradle 依赖
dependencies {
testCompile(
group: "junit", name: "junit", version: "4.11"
)
compile(
"org.apache.shiro:shiro-core:1.2.4",
"org.slf4j:slf4j-log4j12:1.7.13"
)
}
2、核心配置文件 shiro.ini 配置
[users]
liwei=123456
wudi=wudi
huzhenyu=huzhenyu
yuanlian=yuanlian
3、编写代码
public class HelloWorld {
public static void main(String[] args) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject currentSubject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("liwei", "123456");
try {
currentSubject.login(token);
} catch (UnknownAccountException e) {
System.out.println("无效的用户名");
e.printStackTrace();
} catch (IncorrectCredentialsException e) {
System.out.println("密码错误");
e.printStackTrace();
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("登录成功");
currentSubject.logout();
// 最后别忘了退出登录(shiro还会做很多操作,从控制台就可以看出)
currentUser.logout();
System.out.println("退出登录成功");
}
}
说明:我们可以把前台在表单中输入用户名和密码传入 UsernamePasswordToken 的构造函数中,Shiro 就会把 UsernamePasswordToken 和配置文件 shiro.ini 中 [usrs] 节点下的键值对进行比对,如果不能匹配则抛出响应的异常。
我们简单介绍一下 Shiro 在其中发挥的作用:
1、Subject 就是我们登录的主体,这里相当于一个桥梁,我们所有的操作其实都要通过 Subject 来帮助我们完成。
2、SecurityManager 类似于 Spring MVC 中的 DispatcherServlet ,起到类似前端控制器的作用;
3、在 Shiro 中还有一个非常重要的模块,那就是 Realm ,Realm 是安全数据源,我们要把类似于用户名和密码的信息存放到 Realm 中,Shiro 就可以帮助我们完成认证和授权等一系列操作。
在这个例子中的 Realm 叫 IniRealm ,我们把正确的用户名和密码信息存放在一个以 ini 结尾的文件中,Shiro 来帮助我们去做最最简单的字符串匹配,我们只须要通过捕获 Shiro 抛出的响应的异常,做一些后续的处理。将来我们还可以使用 JdbcRealm 和自定义的 Realm。
下一节我们介绍如何使用 JdbcRealm 让 Shiro 通过存放在数据库中的用户信息实现用户登录匹配。