本文介绍shiro通过jdbc连接数据库,连接池采用阿里巴巴的druid的连接池

参考文档:https://www.w3cschool.cn/shiro/xgj31if4.html

     https://www.w3cschool.cn/shiro/h5it1if8.html

pom.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>shiro-example-chapter2</artifactId>
<groupId>com.github.zhangkaitao</groupId>
<version>SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.16</version>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency> </dependencies> </project>

shiro.ini 文件的配置

[main]
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=123456
jdbcRealm.dataSource=$dataSource
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
securityManager.realms=$jdbcRealm
jdbcRealm  shiro框架已经集成的安全域,安全域的作用是将资源(数据库,缓存,磁盘文件等)中用户身份的集合和需要匹配的集合进行验证,决定登录用户的身份是否能验证成功的功能。如果要自定义安全域,只要继承
AuthorizingRealm 这个接口。实现doGetAuthenticationInfo() 身份验证这个方法即可。

测试类的方法
public class TestJdbcLogin{ 
@Test
public void testJDBCRealm() {
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory =
new IniSecurityManagerFactory("classpath: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("zhang", "123"); try {
//4、登录,即身份验证
subject.login(token);
} catch (IncorrectCredentialsException e) {
//5、身份验证失败
e.printStackTrace();
System.out.println("密码错误");
}catch (DisabledAccountException e){
System.out.println("禁用的账户");
} Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出
subject.logout();
}
}

JdbcRealm 类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.shiro.realm.jdbc; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.JdbcUtils;
import org.apache.shiro.util.ByteSource.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class JdbcRealm extends AuthorizingRealm {
protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class);
protected DataSource dataSource;
protected String authenticationQuery = "select password from users where username = ?";
protected String userRolesQuery = "select role_name from user_roles where username = ?";
protected String permissionsQuery = "select permission from roles_permissions where role_name = ?";
protected boolean permissionsLookupEnabled = false;
protected JdbcRealm.SaltStyle saltStyle; public JdbcRealm() {
this.saltStyle = JdbcRealm.SaltStyle.NO_SALT;
} public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} public void setAuthenticationQuery(String authenticationQuery) {
this.authenticationQuery = authenticationQuery;
} public void setUserRolesQuery(String userRolesQuery) {
this.userRolesQuery = userRolesQuery;
} public void setPermissionsQuery(String permissionsQuery) {
this.permissionsQuery = permissionsQuery;
} public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) {
this.permissionsLookupEnabled = permissionsLookupEnabled;
} public void setSaltStyle(JdbcRealm.SaltStyle saltStyle) {
this.saltStyle = saltStyle;
if (saltStyle == JdbcRealm.SaltStyle.COLUMN && this.authenticationQuery.equals("select password from users where username = ?")) {
this.authenticationQuery = "select password, password_salt from users where username = ?";
} } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
String username = upToken.getUsername();
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm.");
} else {
Connection conn = null;
SimpleAuthenticationInfo info = null; try {
String salt;
try {
conn = this.dataSource.getConnection();
String password = null;
salt = null;
switch(this.saltStyle) {
case NO_SALT:
password = this.getPasswordForUser(conn, username)[0];
break;
case CRYPT:
throw new ConfigurationException("Not implemented yet");
case COLUMN:
String[] queryResults = this.getPasswordForUser(conn, username);
password = queryResults[0];
salt = queryResults[1];
break;
case EXTERNAL:
password = this.getPasswordForUser(conn, username)[0];
salt = this.getSaltForUser(username);
} if (password == null) {
throw new UnknownAccountException("No account found for user [" + username + "]");
} info = new SimpleAuthenticationInfo(username, password.toCharArray(), this.getName());
if (salt != null) {
info.setCredentialsSalt(Util.bytes(salt));
}
} catch (SQLException var12) {
salt = "There was a SQL error while authenticating user [" + username + "]";
if (log.isErrorEnabled()) {
log.error(salt, var12);
} throw new AuthenticationException(salt, var12);
}
} finally {
JdbcUtils.closeConnection(conn);
} return info;
}
} private String[] getPasswordForUser(Connection conn, String username) throws SQLException {
boolean returningSeparatedSalt = false;
String[] result;
switch(this.saltStyle) {
case NO_SALT:
case CRYPT:
case EXTERNAL:
result = new String[1];
break;
case COLUMN:
default:
result = new String[2];
returningSeparatedSalt = true;
} PreparedStatement ps = null;
ResultSet rs = null; try {
ps = conn.prepareStatement(this.authenticationQuery);
ps.setString(1, username);
rs = ps.executeQuery(); for(boolean foundResult = false; rs.next(); foundResult = true) {
if (foundResult) {
throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
} result[0] = rs.getString(1);
if (returningSeparatedSalt) {
result[1] = rs.getString(2);
}
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
} return result;
} protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
} else {
String username = (String)this.getAvailablePrincipal(principals);
Connection conn = null;
Set<String> roleNames = null;
Set permissions = null; try {
conn = this.dataSource.getConnection();
roleNames = this.getRoleNamesForUser(conn, username);
if (this.permissionsLookupEnabled) {
permissions = this.getPermissions(conn, username, roleNames);
}
} catch (SQLException var11) {
String message = "There was a SQL error while authorizing user [" + username + "]";
if (log.isErrorEnabled()) {
log.error(message, var11);
} throw new AuthorizationException(message, var11);
} finally {
JdbcUtils.closeConnection(conn);
} SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
} protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
LinkedHashSet roleNames = new LinkedHashSet(); try {
ps = conn.prepareStatement(this.userRolesQuery);
ps.setString(1, username);
rs = ps.executeQuery(); while(rs.next()) {
String roleName = rs.getString(1);
if (roleName != null) {
roleNames.add(roleName);
} else if (log.isWarnEnabled()) {
log.warn("Null role name found while retrieving role names for user [" + username + "]");
}
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
} return roleNames;
} protected Set<String> getPermissions(Connection conn, String username, Collection<String> roleNames) throws SQLException {
PreparedStatement ps = null;
LinkedHashSet permissions = new LinkedHashSet(); try {
ps = conn.prepareStatement(this.permissionsQuery);
Iterator i$ = roleNames.iterator(); while(i$.hasNext()) {
String roleName = (String)i$.next();
ps.setString(1, roleName);
ResultSet rs = null; try {
rs = ps.executeQuery(); while(rs.next()) {
String permissionString = rs.getString(1);
permissions.add(permissionString);
}
} finally {
JdbcUtils.closeResultSet(rs);
}
}
} finally {
JdbcUtils.closeStatement(ps);
} return permissions;
} protected String getSaltForUser(String username) {
return username;
} public static enum SaltStyle {
NO_SALT,
CRYPT,
COLUMN,
EXTERNAL; private SaltStyle() {
}
}
}

标红的查询语句正是shiro框架已经集成的查询语句,所以建表的时候要根据相应的表名建表

另外可以参考这篇文章:http://blog.51cto.com/luchunli/1828080


shiro 通过jdbc连接数据库的更多相关文章

  1. JDBC连接数据库

    JDBC连接数据库 1.加载JDBC驱动程序. Class.forName("com.mysql.jdbc.Driver"); 建立连接,. Connection conn = D ...

  2. java开发中JDBC连接数据库代码和步骤

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...

  3. java开发JDBC连接数据库详解

    JDBC连接数据库 好文一定要让大家看见 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机) ...

  4. 【转】Java开发中JDBC连接数据库代码和步骤总结

    (转自:http://www.cnblogs.com/hongten/archive/2011/03/29/1998311.html) JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个 ...

  5. 使用配置文件来配置JDBC连接数据库

    1.管理数据库连接的Class 代码如下: package jdbcTest;import java.sql.Connection;import java.sql.DriverManager;impo ...

  6. Java中JDBC连接数据库代码和步骤详解总结

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤:         1.加载JDBC驱动程序:         在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Jav ...

  7. 完整java开发中JDBC连接数据库代码和步骤

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...

  8. JDBC连接数据库(PreparedStatement)

    PreparedStatement是在数据库端防止SQL注入漏洞的SQL方法这里演示了一些基本使用方法同样使用Oracle数据库,之前已经手动建立了一张t_account表数据库代码参见上一篇< ...

  9. JDBC连接数据库演示

    今天重新学习了JDBC连接数据库,使用的数据库是Oracle,在运行前已经手动建立了一张t_user表,建表信息如下: create table t_user( card_id ) primary k ...

随机推荐

  1. 2016/3/26 weixin 头像 昵称 网页优化显示 缺表中数据 只有代码 无显示效果

    weixin.php <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  2. 滑动窗体的最大值(STL的应用+剑指offer)

    滑动窗体的最大值 參与人数:767时间限制:1秒空间限制:32768K 通过比例:21.61% 最佳记录:0 ms|8552K(来自 ) 题目描写叙述 给定一个数组和滑动窗体的大小.找出全部滑动窗体里 ...

  3. handsontable整理

    hansontable简介 hansontable是一个在线类似Excel的表格编辑器,支持丰富的展现和交互,有多样的单元格类型供配置. 核心是由原生JavaScript构建,充分模块化,支持自定义b ...

  4. (17)会话之Cookie的使用详解

    Cooke技术 1,特点 Cookie技术:会话数据保存在浏览器客户端. 2,Cookie技术核心 Cookie类:用于存储会话数据  1)构造Cookie对象 Cookie(java.lang.St ...

  5. Magic Grid ComboBox JQuery 版

    在MagicCombo组件中嵌入Grid,以支持分页查找和跨页选取 ​ 1. ​2. [代码][JavaScript]单选示例代码     <script type="text/jav ...

  6. android 自定义View开发实战(六) 可拖动的GridView

    1前言 由于项目需求,需要把项目的主界面采用GridView显示,并且需要根据模块优先级支持拖动图标(砍死产品狗).为此,自定义了一个支持拖拽图标的GridView.效果如下: 具体效果如上图 2 可 ...

  7. sphinx是支持结果聚类的——WHERE、ORDER BY和GROUP BY

    原生API提供的匹配筛选.排序和分组配置和SQL语法提供的WHERE.ORDER BY和GROUP BY语句的效果是一样的,你可以对匹配结果进行你需要的筛选.排序和分组匹配.例如,如果你要搜索MySQ ...

  8. 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法

    1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...

  9. choice() 函数

    描述 choice() 方法返回一个列表,元组或字符串的随机项. 语法 以下是 choice() 方法的语法: import random random.choice( seq ) 注意:choice ...

  10. Html.PartialView(),html.Renderpartial,html.action.html.RenderAction 辅助方法

    Html.Partial(), 返回HTML字符串 .参数为部分视图 html.RenderPartial(),不返回返回HTML字符串 ,直接输出响应流.参数为部分视图 一般用于主视图中已经存在了这 ...