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

引言

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.JdbcRealm
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.user=root
dataSource.password=123456
# 表示对 dataSource 这个变量设置属性值 jdbcUrl ,这个属性值是一个字符串。
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro?useUnicode=true&characterEncoding=UTF-8
# 表示对 jdbcRealm 这个变量设置属性值 dataSource , 这个 dataSource 属性是上面实例化的一个对象,所以表示这个对象要使用前缀 `$`。
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm

3、编写 SQL 初始化脚本

DROP DATABASE db_shiro;
# 创建数据库 db_shiro
CREATE DATABASE db_shiro DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# 使用数据库 db_shiro
USE 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 替我们完成了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值