shiro入门实战笔记(10)--自定义Realm
来源:互联网 发布:mysql strcmp 编辑:程序博客网 时间:2024/04/30 12:46
[本系列文章是博主的学习笔记,而非经典教程,特此说明]
首先,我们先来回顾下面这张图:
接着,我们在来回顾一下Realm的概念:Realm可以有1个或多个,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC 实现,也可以是LDAP 实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;这个概念通俗的将,就是我们对于权限配置的保存方式是那一种形式。在我们前面的一系列举例中都是使用shiro.ini配置文件的方式。本文我们来介绍使用数据库的方式来存储用户,角色,权限等信息。好了,现在我们回顾了这些基本概念之后,开始我们的正文部分吧。
准备工作:
a.操作系统:win7 x64
b.开发工具:myeclipse 2014,jdk1.7,maven3.3.3,mysql5.0,jsp基础
-----------------------------------------------------------------------------------------------------------------------------------------------------
正文开始:
一.创建数据库,表及配置信息
1.创建数据库,博主这里使用图形化的mysql管理工具创建名称为shiro的数据库,读者可以按照自己的实际情况选择。
2.创建角色表,我们将角色表命名为t_role,表格数据是将shiro.ini中的[roles]部分转换而来,具体内容如下图所示
CREATE TABLE `t_role` ( `Id` int(11) NOT NULL auto_increment, `roleName` varchar(255) default NULL, PRIMARY KEY (`Id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
3.创建用户表,我们将用户表命名为t_user,表格数据是将shiro.ini中的[user]部分转换而来,具体内容如下图所示:
CREATE TABLE `t_user` ( `Id` int(11) NOT NULL auto_increment, `userName` varchar(255) default NULL, `password` varchar(255) 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 DEFAULT CHARSET=utf8
4.创建权限表,我们将权限表命名为t_permission,表格数据是讲shiro.ini中的[roles]部分转换而来,具体内容如下图所示:
CREATE TABLE `t_permission` ( `Id` int(11) NOT NULL auto_increment, `permissionName` varchar(255) 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 DEFAULT CHARSET=utf8
5.注意,上面的3张表之间是存在主外键关系的,具体内容如下图:
t_permission表中的roldId与t_role表中的Id建立主外键关系。
t_user表中的roleId与t_role表中的Id建立主外键关系。
二.创建我们本文示例工程shiro07
1.创建工程我们可以直接将shiro05工程复制过来,然后修改为shiro07工程目录,具体内容如下图所示:
2.修改pom文件,具体内容如下:
<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.java.shiro</groupId><artifactId>shiro06</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>shiro05 Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.2.4</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.4</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.13</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.22</version></dependency></dependencies><build><finalName>shiro05</finalName></build></project>写入上面的依赖,保存,maven会帮助我们自动的下载相关的包。下载号之后,我们在工程的maven dependencies下就可以看到如下内容,如果有遗漏,请读者认真检查。
3.创建DbUtil.java文件,具体内容如下:
package com.java.util;import java.sql.Connection;import java.sql.DriverManager;/** * 数据库工具类 */public class DbUtil {/** * 获取数据库连接 * @return * @throws Exception */public Connection getCon() throws Exception{Class.forName("com.mysql.jdbc.Driver");Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/shiro", "root", "1234");return con;}/** * 关闭数据库连接 * @param con * @throws Exception */public void closeCon(Connection con)throws Exception{if(con!=null){con.close();}}public static void main(String[] args) {DbUtil dbUtil=new DbUtil();try {dbUtil.getCon();System.out.println("数据库连接成功");} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("数据库连接失败");}}}为方便介绍后面的内容,这里请大家先进行单元测试,如果有问题,请先按照错误提示进行解决。
4.创建com.java.realm包,创建MyRealm.java文件,具体内容如下:
package com.java.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.java.dao.UserDao;import com.java.entity.User;import com.java.util.DbUtil;/** *@author 作者 E-mail: *@version 创建时间:2016年2月15日下午6:59:38 *类说明 */public class MyRealm extends AuthorizingRealm{private UserDao userDao = new UserDao();private DbUtil dbUtil = new DbUtil();/* (non-Javadoc) * @see 为当前用户授予角色与权限 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) {String userName = (String) principals.getPrimaryPrincipal();SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();Connection con = null;try{con=dbUtil.getCon();authorizationInfo.setRoles(userDao.getRoles(con,userName));authorizationInfo.setStringPermissions(userDao.getPermission(con,userName));}catch(Exception e){//自行处理}return authorizationInfo;}/* (non-Javadoc) * @see 获取认证信息,验证当前登陆的用户 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String userName = (String) token.getPrincipal();Connection con = null;try{con = dbUtil.getCon();User user = userDao.getByUserName(con, userName);if(user!=null){AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");return authcInfo;}else{return null;}}catch(Exception e){//自行处理}finally{try {dbUtil.closeCon(con);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}}5.创建com.java.dao包,创建UserDao.java文件,具体内容如下:
package com.java.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.HashSet;import java.util.Set;import javax.swing.text.html.HTMLDocument.HTMLReader.ParagraphAction;import com.java.entity.User;/** *@author 作者 E-mail: *@version 创建时间:2016年2月15日下午8:20: *类说明 */public class UserDao {public User getByUserName(Connection con,String userName)throws Exception{User resultUser = null;String sql = "select * from t_user where userName=?";PreparedStatement pstment = con.prepareStatement(sql);pstment.setString(1,userName);ResultSet rs = pstment.executeQuery();if(rs.next()){resultUser = new User();resultUser.setId(rs.getInt("id"));resultUser.setUserName(rs.getString("userName"));resultUser.setPassword(rs.getString("password"));}return resultUser;}public Set<String> getRoles(Connection con, String userName)throws Exception {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 pstment = con.prepareStatement(sql);pstment.setString(1,userName);ResultSet rs = pstment.executeQuery();while(rs.next()){roles.add(rs.getString("roleName"));}return roles;}public Set<String> getPermission(Connection con, String userName) throws Exception {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 pstment = con.prepareStatement(sql);pstment.setString(1,userName);ResultSet rs = pstment.executeQuery();while(rs.next()){permissions.add(rs.getString("permissionName"));}return null;}}
6.创建com.java.entity包,创建User.java文件,具体内容如下:
package com.java.entity;/** *@author 作者 E-mail: *@version 创建时间:2016年2月15日下午8:21:45 *类说明 */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;}}
7.最后我们来创建新的shiro.ini配置文件,具体内容如下:
[main]authc.loginUrl=/loginroles.unauthorizedUrl=/unauthorized.jspperms.unauthorizedUrl=/unauthorized.jspmyRealm=com.java.realm.MyRealmsecurityManager.realms=$myRealm[urls]/login=anon/admin*/**=authc/student=roles[teacher]/teacher=perms["user:create"]8.最后,我们部署,启动tomcat,在浏览器中观察在输入正确的用户名密码,错误的用户名密码。控制台如何输出,以及请读者在debug模式下观察程序执行流程。
--------------------------------------------------------------------------------------------------------------------------------------------------
至此,shiro入门实战笔记(10)--自定义Realm结束
备注:
本节所示的内容非常非常非常重要,请各位看官一定亲自动手实践一次,并且在debug模式下跟踪程序执行流程。
参考资料:
官方文档:http://shiro.apache.org/documentation.html
其他博文:http://jinnianshilongnian.iteye.com/blog/2018936
- shiro入门实战笔记(10)--自定义Realm
- Shiro入门-自定义realm
- Shiro入门10:自定义Realm进行授权
- shiro笔记3《自定义Realm》
- 【shiro】shiro学习笔记2-自定义realm
- (六)shiro自定义realm
- java安全框架-Shiro学习笔记(七)-自定义realm
- Shiro 学习笔记(3)—— 自定义 Realm
- Apache shiro 笔记整理之自定义Realm
- shiro入门实战笔记(2)--helloworld
- shiro自定义Realm
- Shiro自定义Realm
- shiro自定义Realm实现
- Shiro 自定义realm认证
- 【shiro】--- 自定义realm
- Shiro(四) 自定义Realm
- Shiro入门6:自定义realm查询数据库进行认证
- DUBBO出错笔记(三)shiro 自定义realm注入失败解决办法
- Windows简易静态库制作方式
- 装饰者模式
- android FM手动调频流程
- margin-top 失效的问题
- jQuery元素的追加和删除
- shiro入门实战笔记(10)--自定义Realm
- 《转》详解Spring中bean的scope singleton prototype request...
- .config、kconfig和Makefile的关系
- 毛泽东23岁时写何文章震动全校?
- Javascript、Jquery获取浏览器和屏幕各种高度宽度
- 周期字串
- Android Post Json数据乱码问题
- 三维体数据分割算法及实现
- caffe运行错误 target_blobs.blobs_size()与 source_layer.blobs_size() 不一致