项目结构:
创建 maven 项目。
1、引入 gav 依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
如果使用 gradle 构建,则坐标为
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'org.apache.shiro:shiro-core:1.2.4'
compile 'org.slf4j:slf4j-log4j12:1.7.13'
}
2、编写 shiro 核心配置文件 shiro.ini
[users]
liwei=123456
wudi=wudi
huzhenyu=huzhenyu
3、编写 HelloWorld 代码
这里要特别注意:SecurityManager
所在的包名应该是org.apache.shiro.mgt
。
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 sun.org.mozilla.javascript.internal.SecurityUtilities;
/** * Created by Liwei on 2015/12/15. */
public class HelloWorld {
public static void main(String[] args) {
// 读取配置文件,初始化 SecurityManager 工厂
// 注意:这里 SecurityManager 所在的包名
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 获取 SecurityManager 的实例
SecurityManager securityManager = factory.getInstance();
// 把 securityManager 的实例绑定到 SecurityUtils 上
SecurityUtils.setSecurityManager(securityManager);
// 得到当前执行的用户
Subject currentUser = SecurityUtils.getSubject();
// 自己创建一个令牌,输入用户名和密码
// UsernamePasswordToken token = new UsernamePasswordToken("liwei","123456");
UsernamePasswordToken token = new UsernamePasswordToken("huzhenyu","huzhenyu");
try {
// 身份认证(该方法会抛出异常)
currentUser.login(token);
System.out.println("身份认证成功!");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("身份认证失败!");
}
// 退出
currentUser.logout();
}
}
4、引入 slf4j 的 log4j 实现配置文件:log4j.properties
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
# General Apache libraries
log4j.logger.org.apache=WARN
# Spring
log4j.logger.org.springframework=WARN
# Default Shiro logging
log4j.logger.org.apache.shiro=TRACE
# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
Subject 认证主体包含两个信息:
Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;(我们可以理解成用户名)
Credentials:凭证,常见有密码,数字证书等等;(我们可以理解成密码)
下面我们介绍使用 jdbcRealm。
那么什么是 Realm 呢?
(Realm 可以理解为主体的数据源)
Realm 的意思是域,Shiro 从 Realm 中获取验证数据。Realm 有很多种类,例如常见的 jdbc realm,jndi realm,text realm。
只须要对上面的代码稍稍作修改就可以实现。既然使用的是 jdbcRealm,就会使用到 jdbc 数据源的相关技术。
首先我们引入依赖:
compile 'mysql:mysql-connector-java:5.1.38'
compile 'c3p0:c3p0:0.9.1.2'
compile 'commons-logging:commons-logging:1.2'
再向数据库里写入数据:
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=1 DEFAULT CHARSET=utf8;
insert into users(userName,password) values ('liwei','123456');
insert into users(userName,password) values ('zhouguang','123456');
重点是配置文件 jdbc_realm.ini:
[main]
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro
dataSource.password=123456
dataSource.user=root
dataSource.driverClass=com.mysql.jdbc.Driver
jdbcRealm.dataSource=$dataSource
securityManager.realm=$jdbcRealm
实现代码(和上一节没有什么不同,只是配置文件不一样而已):
public class JdbeReamlTest {
/** * 这一节的内容是 身份认证 * @param args */
public static void main(String[] args) {
// 注意:这里 SecurityManager 所在的包名
// 读取配置文件,初始化SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini");
SecurityManager securityManager = factory.getInstance();
// 把 securityManager 的实例绑定到 SecurityUtils 上
SecurityUtils.setSecurityManager(securityManager);
// 得到当前执行的用户
Subject currentUser = SecurityUtils.getSubject();
// 自己创建一个令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhouguang","123456");
try {
// 身份认证
currentUser.login(token);
System.out.println("身份认证成功");
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("退出登录");
// 最后别忘了退出登录(shiro还会做很多操作,从控制台就可以看出)
currentUser.logout();
System.out.println("退出登录成功");
}
}