Shiro 学习笔记(2)—— Jdbc Realm

来源:互联网 发布:表情呆滞面部僵硬知乎 编辑:程序博客网 时间:2024/05/22 04:50

引言

Realm 是安全数据源的意思,配置在 Realm 中的数据,我们可以等同于放置在数据库中的数据一样来看待,因为它们都是“绝对正确”的,我们通过“绝对正确”的数据,去完成对登录用户的数据的判定。
在第 1 节中,我们把“正确的”用户名和密码,放在了一个配置文件中,用于校验用户填写的用户名和密码是否正确。这个“校验”的操作是 Shiro 帮助我们完成的,校验不正确,Shiro 通过抛出异常的方式告诉我们。
这一节,我们来看看,我们把“正确的”数据放在数据库中,又怎样操作呢?

强调:本节内容,只用于测试,不适合在生产环境中使用

步骤:

1、引入依赖

// 上一节 Hello World 部分的依赖testCompile group: 'junit', name: 'junit', version: '4.12'compile group: 'org.apache.shiro', name: 'shiro-core', version: '1.3.0'compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.21'// 这一节使用 JdbcRealm 添加的依赖compile 'mysql:mysql-connector-java:5.1.38'compile 'c3p0:c3p0:0.9.1.2'compile 'commons-logging:commons-logging:1.2'

2、编写配置文件

[main]# 表示实例化右边字符串表示的类,赋给左边字符串表示的变量。jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealmdataSource=com.mchange.v2.c3p0.ComboPooledDataSourcedataSource.driverClass=com.mysql.jdbc.DriverdataSource.user=rootdataSource.password=123456# 表示对 dataSource 这个变量设置属性值 jdbcUrl ,这个属性值是一个字符串。dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro?useUnicode=true&characterEncoding=UTF-8# 表示对 jdbcRealm 这个变量设置属性值 dataSource , 这个 dataSource 属性是上面实例化的一个对象,所以表示这个对象要使用前缀 `$`。jdbcRealm.dataSource=$dataSourcesecurityManager.realms=$jdbcRealm

3、编写 SQL 初始化脚本

DROP DATABASE db_shiro;# 创建数据库 db_shiroCREATE DATABASE db_shiro DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;# 使用数据库 db_shiroUSE db_shiro;drop table if exists users;create table users(  id int(11) not null auto_increment comment '主键',  username varchar(20) default null comment '用户名',  password varchar(20) default null comment '密码',  PRIMARY KEY (id))engine=innodb auto_increment=1 default charset=utf8 comment '用户表';insert into users(username,password) values('liwei','123456');insert into users(username,password) values('zhouguang','666666');

下面,我们解释一下,为什么表名设置成 users。
答案很简单,是因为表名 users 是写死在代码中的。我们打开 JdbcRealm 的源代码就很容易发现这一点。

4、编写测试代码

package com.liwei.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;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import sun.jvm.hotspot.HelloWorld;/** * Created by liwei on 16/8/11. */public class JdbcRealmTest {    /**     * 模拟登录界面,把用户尝试登录的信息填写在下面的静态常量中,去体验 Shiro 的 Hello World     */    private static String loginUserName = "liwei"; // 登录界面的用户名填写    private static String loginPassword = "123456"; // 登录界面的密码填写    /**     * 此时关于 Shiro 的配置,采用的是 classpath 的 jdbc_realm.ini 文件中     * 我们须要关注 [main] 节点的配置     * Shiro 通过依赖注入的方式,找到了存放用户名和密码的 user 表     */    private static String iniResourcePath = "classpath:jdbc_realm.ini";    private static Logger LOGGER = LoggerFactory.getLogger(HelloWorld.class);    public static void main(String[] args) {        // 前 4 步和上一节是一样的,是模板代码        Factory<SecurityManager> factory = new IniSecurityManagerFactory(iniResourcePath);        SecurityManager securityManager = factory.getInstance();        SecurityUtils.setSecurityManager(securityManager);        Subject currentUser = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(loginUserName, loginPassword);        try {            currentUser.login(token);            LOGGER.info("登录验证通过,即用户名和密码与 user 表中的 userName 和 password 字段值完全匹配。");        } catch (AuthenticationException e) {            // UnknownAccountException 和 IncorrectCredentialsException            // 这两个异常都是 AuthenticationException 的子类,所以可以通过这个异常类同一捕获            LOGGER.error("登录验证失败!");            e.printStackTrace();        }        currentUser.logout();    }}

第 1、2 节,是简单的 Shiro 的 Hello World。让我们对 Shiro 有了一个直观的感觉。Shiro 让我们不用写“如果用户名不存在,就提示用户名不存在”;“在用户名存在的情况下,去检验用户输入的密码是否和数据库中输入的密码相符”这样的逻辑。这是关于身份认证的操作,Shiro 替我们完成了。

0 0