Shiro入门学习一
2017-10-10 22:02
447 查看
Shiro入门学习一
Shiro官网推荐教程:
跟我学Shiro
shiro介绍以及推荐视频教程
Apache Shiro是Java的一个安全框架。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等
Authentication-身份认证/登录
Authorization-授权,即权限验证,验证某个已认证的用户是否拥有某个权限
首先,我们从外部来看Shiro吧,即从应用程序角度的来观察如何使用Shiro完成工作。如下图:
可以看到:应用代码直接交互的对象是
Subject,也就是说Shiro的对外API核心就是
Subject;其每个API的含义:
Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是
Subject,如网络爬虫,机器人等;即一个抽象概念;所有
Subject都绑定到
SecurityManager,与
Subject的所有交互都会委托给
SecurityManager;可以把
Subject认为是一个门面;
SecurityManager才是实际的执行者;
SecurityManager:安全管理器;即所有与安全有关的操作都会与
SecurityManager交互;且它管理着所有
Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成
DispatcherServlet前端控制器;
Realm:域,Shiro从从
Realm获取安全数据(如用户、角色、权限),就是说
SecurityManager要验证用户身份,那么它需要从
Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从
Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把
Realm看成DataSource,即安全数据源。
也就是说对于我们而言,最简单的一个Shiro应用:
1、应用代码通过
Subject来进行认证和授权,而
Subject又委托给
SecurityManager;
2、我们需要给
Shiro的
SecurityManager注入
Realm,从而让
SecurityManager能得到合法的用户及其权限进行判断。
Shiro HelloWorld
使用Maven创建项目,在
pom.xml导入shiro的包,log4j的包,如下的
pom.xml
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.0</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.5.0</version> </dependency> </dependencies>
在项目的
src/main/resources下,创建log4j的配置文件和一个
shiro.ini文件,项目结构如下:
在
shiro.ini中配置2个用户,内容如下:
[users] wz=123456 jack=123
此处使用
ini配置文件,通过
[users]指定了两个主体:
wz=123456和
jack=123
HelloWorld.java测试文件的内容如下,具体的步骤见注释,如下:
package com.wz.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class HelloWorld { public static void main(String[] args) { //读取配置文件 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //获取SecurityManager实例 SecurityManager securityManager = factory.getInstance(); //绑定给SecurityUtils SecurityUtils.setSecurityManager(securityManager); //得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); //创建token令牌 UsernamePasswordToken token = new UsernamePasswordToken("wz", "123456"); try { //身份验证 currentUser.login(token); System.out.println("身份认证成功"); } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("身份认证失败"); } //退出 currentUser.logout(); System.out.println("logout"); } }
测试运行,控制台会输出
身份认证成功
上面的例子大致演示了一个身份认证的过程。
身份验证,即在应用中谁能证明他就是他本人。一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。
在shiro中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能验证用户身份:
principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/邮件/手机号。
credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
最常见的principals和credentials组合就是用户名/密码了。
详细的说明可参考教程第二章 身份验证——《跟我学Shiro》
从如上代码可总结出身份验证的步骤:
1.收集用户身份/凭证,即如用户名/密码;
2.调用
Subject.login进行登录,如果失败将得到相应的
AuthenticationException异常,根据异常提示用户错误信息;否则登录成功;
3.最后调用
Subject.logout进行退出操作。
身份认证流程
流程如下:
1.首先调用
Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过
SecurityUtils.setSecurityManager()设置;
2.SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3.Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;
4.Authenticator可能会委托给相应的
AuthenticationStrategy进行多Realm身份验证,默认
ModularRealmAuthenticator会调用
AuthenticationStrategy进行多Realm身份验证;
5.Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。
Realm
Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。如我们之前的ini配置方式将使用org.apache.shiro.realm.text.IniRealm。
Shiro默认提供的Realm
以后一般继承AuthorizingRealm(授权)即可;其继承了AuthenticatingRealm(即身份验证),而且也间接继承了CachingRealm(带有缓存实现)。其中主要默认实现如下:
org.apache.shiro.realm.text.IniRealm:
[users]部分指定用户名/密码及其角色;
[roles]部分指定角色即权限信息;
org.apache.shiro.realm.text.PropertiesRealm:
user.username=password,role1,role2指定用户名/密码及其角色;
role.role1=permission1,permission2指定角色及权限信息;
org.apache.shiro.realm.jdbc.JdbcRealm:通过sql查询相应的信息,如“
select password from users where username = ?”获取用户密码,“
select password, password_salt from users where username = ?”获取用户密码及盐;“
select role_name from user_roles where username = ?”获取用户角色;“
select permission from roles_permissions where role_name = ?”获取角色对应的权限信息;也可以调用相应的api进行自定义sql;
JDBC Realm使用
参考【一头扎进Shiro】视频教程第二讲先创建数据库
shiro,创建一个
users表
CREATE DATABASE /*!32312 IF NOT EXISTS*/`db_shiro` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `shiro`; /*Table structure for table `users` */ DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userName` varchar(20) DEFAULT NULL, `password` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*Data for the table `users` */ insert into `users`(`id`,`userName`,`password`) values (1,'wz','123');
创建一个
jdbc_realm.ini文件,内容如下,设置数据源和realm
[main] jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm dataSource=com.mchange.v2.c3p0.ComboPooledDataSource dataSource.driverClass=com.mysql.jdbc.Driver dataSource.jdbcUrl=jdbc:mysql://localhost:3306/shiro dataSource.user=root dataSource.password="" jdbcRealm.dataSource=$dataSource securityManager.realms=$jdbcRealm
注意,我这里密码为空,需设置为
dataSource.password="",需要添加上
"",否则可能会提示错误
java.lang.IllegalArgumentException: Line argument must contain a key and a value. Only one
测试用例,与上面基本差不多,把配置文件设置为
jdbc_realm.ini,如下:
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini");
相关文章推荐
- Shiro系列学习 -- 入门篇
- apache shiro学习笔记--02(入门案例)
- 18.03.09,web学习第七十天,bos第十天,shiro框架入门
- Shiro学习总结(二)--Shiro的入门小例子
- shiro入门学习四
- 权限学习--Shiro入门学习
- Shiro 学习记录 Shiro 入门程序
- Shiro入门学习三
- Shiro入门学习六
- java安全框架-Shiro学习笔记(一)-入门小案例
- Shiro入门学习二
- shiro学习(一)---认证入门程序
- Shiro入门学习四
- Shiro入门学习五
- 4000 Shiro入门学习二
- Shiro入门学习一
- Shiro入门学习三
- shiro入门学习
- Python学习入门基础教程(learning Python)--2.3 Python自定义函数传参
- Python入门学习(三)GUI程序