本文介绍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. linux-shell脚本命令之awk

    [ awk简单介绍: ] awk能够从一个文本中获取部分内容, 或者对这个文本进行排版, 使它按某种格式输出. [ awk工作流程: ] awk会把文件一行内容去到内存里, 然后对这行内容进行分段 ( ...

  2. PartialView中的页面重定向

    在MVC的每个action中,都可以指定一种返回页面的类型,可以是ActionResult,这表示返回的页面为view或者是一个PartialView,前台是一个全整页面,后台是页面的一部分. 在以A ...

  3. 2016/05/15 ThinkPHP3.2.2 表单自动验证实例 验证规则的数组 直接写在相应的控制器里

    使用TP 3.2框架 验证规则也可以写到模型里,但感觉有些麻烦, 一是有时候不同页面验证的方式会不一样, 二是看到这个   Add  事件里的代码,就清楚要接收什么数据,如何验证数据能够在第一眼有个大 ...

  4. linux 监控进程所消耗的资源(内存),达到阈值(绝对值、相对值)后,将其杀死

    监控某个python进程是否存在,如不存在则启动 #!/bin/bashwhile [ 1 ]do #打印出当前的jboss进程:grep jboss查询的jboss进程,grep -v " ...

  5. 设计模式-(15)责任链模式 (swift版)

    一,概念: 责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行 ...

  6. ACGAN 论文笔记

    <Conditional Image Synthesis With Auxiliary Classifier GANs> Odena A, Olah C, Shlens J. Condit ...

  7. window切换Java版本原因

    查找Path环境变量的变量指向的目录,有一个Oracle目录存放着几个 java,javac等可执行文件,删除这个路径或文件就可以执行你指定的JavaHome目录拉 详情参考: https://blo ...

  8. java翻译lua+c+openssl签名项目

    原来项目中用openresty nginx+lua实现server,lua调用c动态链接库,来使用openss做签名,并生成130字节(128签名+2位自定义字节)长度的文件. nginx: loca ...

  9. 扭曲效果 效率优化 GrapPass,CommandBuffer对比

    屏幕图像捕捉: Shader的GrabPass GrabPass可以很方便地捕获当前渲染时刻的FrameBuffer中的图像. 其原理就是从当前FrameBuffer中copy一份纹理,通过SetTe ...

  10. bzoj 1084: [SCOI2005]最大子矩阵【dp】

    分情况讨论,m=1的时候比较简单,设f[i][j]为到i选了j个矩形,前缀和转移一下就行了 m=2,设f[i][j][k]为1行前i个,2行前j个,一共选了k个,i!=j的时候各自转移同m=1,否则转 ...