一、JDBC Realm使用
1、导入jar包:c3p0-0.9.1.2.jar、junit-4.10.jar、log4j-1.2.17.jar、mysql-connector-java-5.1.37-bin.jar、shiro-core-1.4.0.jar、slf4j-api-1.6.1.jar、slf4j-log4j12-1.6.1.jar
我这里使用的是c3p0连接池
2、查看org.apache.shiro.realm.jdbc.JdbcRealm可以看到类中定义的SQL,如下图:
3、我这里是自定义SQL,新建的表结构为:
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password_salt` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_users_username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', 'admin', 'admin');
CREATE TABLE `user_roles` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`role_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_user_roles`(`username`, `role_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
CREATE TABLE `roles_permissions` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`appid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单ID',
`optionid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '功能按钮ID',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_roles_permissions`(`role_name`, `appid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
2、新建自定义的Realm类MyJdbcRealm,继承org.apache.shiro.realm.jdbc.JdbcRealm,主要是为了自定义sql,代码如下:
package com.ssm.framework.shiro.jdbcrealm;
import org.apache.shiro.realm.jdbc.JdbcRealm;
public class MyJdbcRealm extends JdbcRealm{
public MyJdbcRealm() {
super.setAuthenticationQuery("select password from user where username = ?");
super.setUserRolesQuery("select role_name from user_roles where username = ?");
super.setPermissionsQuery("select appid, optionid from roles_permissions where role_name = ?");
}
}
3、、新建ini配置文件shiro-jdbc-realm.ini,在这里设置Realm及数据源,代码如下:
[main]
jdbcRealm=com.ssm.framework.shiro.jdbcrealm.MyJdbcRealm
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://127.0.0.1:3306/paperanalyse
dataSource.user=root
dataSource.password=root
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm
4、新建测试类,测试代码如下:
@Test
public void testJDBCRealm() {
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory =
new IniSecurityManagerFactory("WebContent/WEB-INF/conf/shiro-jdbc-realm.ini");
//2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin");
try {
//4、登录,即身份验证
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
} catch (AuthenticationException e) {
//5、身份验证失败
e.printStackTrace();
}
Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
}
5、测试结果,查看控制台打印
二、返回身份验证信息
1、shiro-jdbc-realm.ini新增配置项,代码如下:
#指定securityManager的authenticator实现
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator
#指定securityManager.authenticator的authenticationStrategy
allSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy
2、测试代码如下:
@Test
public void testAllSuccessfulStrategyWithSuccess() {
LoginLogoutTest llt = new LoginLogoutTest();
llt.testJDBCRealm();
Subject subject = SecurityUtils.getSubject();
//得到一个身份集合,其包含了Realm验证成功的身份信息
PrincipalCollection principalCollection = subject.getPrincipals();
System.out.println(principalCollection.asList());
Assert.assertEquals(1, principalCollection.asList().size());
}
LoginLogoutTest为上文测试JDBC Realm的类
3、控制台打印