Shiro入门学习一
来源:互联网 发布:家具软件管理 编辑:程序博客网 时间:2024/05/19 15:41
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=123456jack=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.JdbcRealmdataSource=com.mchange.v2.c3p0.ComboPooledDataSourcedataSource.driverClass=com.mysql.jdbc.DriverdataSource.jdbcUrl=jdbc:mysql://localhost:3306/shirodataSource.user=rootdataSource.password=""jdbcRealm.dataSource=$dataSourcesecurityManager.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入门学习一
- Shiro入门学习一
- shiro学习(一)---认证入门程序
- shiro 入门讲解(一)
- Shiro入门系列一
- Shiro入门学习二
- Shiro入门学习三
- Shiro入门学习四
- Shiro入门学习五
- Shiro入门学习二
- Shiro入门学习三
- shiro入门学习四
- Shiro入门学习六
- shiro学习(一)
- Shiro学习(一)
- shiro学习(一)
- shiro学习(一)
- shiro学习(一)
- 计蒜客 17116 Sum(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 C)
- Project Euler__problem 5
- hadoop简介和环境
- Sudo
- 非对称加密 秘钥登录
- Shiro入门学习一
- hadoop local、伪分布 模式
- 秒杀系统(感悟&待续)
- Cacti 邮件 报警
- 移动混合开发,国内镜像及局域网Ionic+Cordova配置
- 方法的重载与重写 区别 封装 继承 多态
- IntelliJ Idea 免费激活方法 2017
- Codeforces Round #438 B. Race Against Time 题解
- Android数据存储之ContentProvider