Apache shiro 笔记整理之自定义Realm

以下内容是在看了涛哥的《跟我一起学shiro》 和 视频《一头扎入进shiro》 后整理出来备忘和方便自己和其他人学习。


之前是在shiro.ini文件中配置用户和权限,现在要从数据库中读取,采用的是jdbc读取mysql数据库。

了解jdbc是如何读取mysql数据库:http://blog.csdn.net/qq_19558705/article/details/49947317

配合上一章内容Servlet代码:http://blog.csdn.net/qq_19558705/article/details/50775223

第一步:创建表

DROP TABLE IF EXISTS `t_permission`;
CREATE TABLE `t_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `permissionName` varchar(50) DEFAULT NULL,
  `roleId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `roleId` (`roleId`),
  CONSTRAINT `t_permission_ibfk_1` FOREIGN KEY (`roleId`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `t_permission` VALUES ('1', 'user:*', '1');
INSERT INTO `t_permission` VALUES ('2', 'student:*', '2');

DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `roleName` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `t_role` VALUES ('1', 'admin');
INSERT INTO `t_role` VALUES ('2', 'teacher');

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userName` varchar(20) DEFAULT NULL,
  `password` varchar(20) DEFAULT NULL,
  `roleId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `roleId` (`roleId`),
  CONSTRAINT `t_user_ibfk_1` FOREIGN KEY (`roleId`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO `t_user` VALUES ('1', 'ITDragon', '123456', '1');
INSERT INTO `t_user` VALUES ('2', 'blog', '123456', '2');

第二步:连接数据库

添加java-mysql驱动:

<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.17</version>
	</dependency>

连接数据库代码:

package com.shiro.utils;
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.Statement;  
/** 
 * 数据库连接类 
 * @author ITDragon 
 * 
 */  
public class ConnectionUtil {     
    /** 
     * 第一步:加载驱动 
     * 第二步:链接数据库 
     * 第三步:一定要关闭流 
     * 第四步:测试是否连接成功 
     */     
    private static String DRIVER = "com.mysql.jdbc.Driver";         // 数据库驱动  
    private static String URL = "jdbc:mysql://localhost:3306/db_shiro"; // 访问数据库路径  
    private static String NAME = "root";                            // 数据库用户名  
    private static String PASSWORD = "root";                        // 数据库密码  
  
    public static Connection getConnection() {  
        Connection connection = null;  
        try {  
            // 加载驱动  
            Class.forName(DRIVER);  
            // 连接数据库  
            connection = DriverManager.getConnection(URL, NAME, PASSWORD);  
            return connection;  
        } catch (Exception e) {  
        	e.printStackTrace();
            return null;  
        }  
    }  
  
    // 关闭流  
    public static void closeConnection(Connection connection) {  
        try {  
            connection.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    public static void closeStatement(Statement statement) {  
        try {  
            statement.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    public static void closePreparedStatement(PreparedStatement pStatement) {  
        try {  
            pStatement.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    public static void closeResultSet(ResultSet rs) {  
        try {  
            rs.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    // 测试数据库是否链接成功  
    public static void main(String[] args) {  
        System.out.println(getConnection());  
    }  
}  

第三步:自定义realm

首先准备一个用户的实体类

package com.shiro.entity;
public class User {

	private Integer id;
	private String userName;
	private String password;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

准备一个查询用户信息,角色,权限的Dao

package com.shiro.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import com.shiro.entity.User;

public class UserDao {

	// 通过用户名获取用户信息
	public User getByUserName(Connection connection, String userName) {
		User resultUser = null;
		String sql = "select * from t_user where userName = ?";
		PreparedStatement pstmt;
		try {
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, userName);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next()) {
				resultUser = new User();
				resultUser.setId(rs.getInt("id"));
				resultUser.setUserName(rs.getString("userName"));
				resultUser.setPassword(rs.getString("password"));
			}
			return resultUser;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 通过用户名查询用户角色
	public Set<String> getUserRoles(Connection connection, String userName) {
		Set<String> roles = new HashSet<String>();
		String sql = "select * from t_user u,t_role r where u.roleId=r.id and u.userName = ?";
		PreparedStatement pstmt;
		try {
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, userName);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next()) {
				roles.add(rs.getString("roleName"));
			}
			return roles;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 通过用户名查询用户权限
	public Set<String> getUserPermissions(Connection connection, String userName) {
		Set<String> permissions = new HashSet<String>();
		String sql = "select * from t_user u,t_role r,t_permission p "
				+ "where u.roleId = r.id and p.roleId = r.id and u.userName = ?";
		PreparedStatement pstmt;
		try {
			pstmt = connection.prepareStatement(sql);
			pstmt.setString(1, userName);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next()) {
				permissions.add(rs.getString("permissionName"));
			}
			return permissions;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

}

自定义realm:

package com.shiro.realm;

import java.sql.Connection;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import com.shiro.dao.UserDao;
import com.shiro.entity.User;
import com.shiro.utils.ConnectionUtil;

/**
 * 自定义realm
 * 步骤:
 * s1:继承 AuthorizingRealm 并实现其方法
 * s2:验证当前用户
 * s3:给当前登录成功的用户授予角色和权限
 * @author ITDragon
 *
 */
public class MyRealm extends AuthorizingRealm{
	
	private UserDao userDao = new UserDao();
	
	// 给当前登录成功的用户授予角色和权限
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// 获取用户名
		String userName = (String) principals.getPrimaryPrincipal();
		// 认证信息
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		Connection connection = null;
		try{
			connection = ConnectionUtil.getConnection();
			// 设置角色
			simpleAuthorizationInfo.setRoles(userDao.getUserRoles(connection , userName));
			// 设置权限
			simpleAuthorizationInfo.setStringPermissions(userDao.getUserPermissions(connection , userName));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				ConnectionUtil.closeConnection(connection);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	// 验证当前用户
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		// 获取用户信息
		String userName = (String) token.getPrincipal();
		Connection connection = null;
		try{
			connection = ConnectionUtil.getConnection();
			// 通过用户名找到用户
			User user = userDao.getByUserName(connection, userName);
			if(null != user){
				// 三个参数分别是: 用户名 , 密码 , rememberMe
				AuthenticationInfo authcInfo =
						new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"false");
				return authcInfo;
			}else{
				return null;
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				ConnectionUtil.closeConnection(connection);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

第四步:配置shiro.ini

[main]
#用户登入路径
authc.loginUrl=/login
#角色验证
roles.unauthorizedUrl=/unauthorized.jsp
#权限验证
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.shiro.realm.MyRealm
securityManager.realms=$myRealm
[urls]
#该路径为匿名登入
/login=anon
#身份验证后才能登入
/admin=authc
#该路径验证是否拥有teacher角色
/student=roles[teacher]
#该路径验证该角色是否拥有权限
/teacher=perms["student:delete"]

第五步:loginServlet:和上一章一样


源码下载路径:http://download.csdn.net/detail/qq_19558705/9451248

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值