(十)shiro之自定义Realm以及自定义Realm在web的应用demo
- 数据库设计






- pom.xml
<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.shyroke</groupId>
<artifactId>shiro_web</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>shiro_web Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies> <dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency> <dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>servlet-api</artifactId>
<version>6.0.53</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency> </dependencies>
<build>
<finalName>shiro_web</finalName> <plugins> <plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<!-- 每2秒的间隔扫描一次,实现热部署 -->
<scanIntervalSeconds>2</scanIntervalSeconds>
<!-- 设置为手动部署,即在Console中回车即部署 -->
<reload>manual</reload>
<contextPath>/</contextPath>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>3033</port>
</connector>
</connectors>
</configuration> </plugin>
</plugins> </build>
</project>
- shiro.ini
[main]
authc.loginUrl= /login
roles.unauthorizedUrl= /unauthorized.jsp
perms.unauthorizedUrl= /unauthorized.jsp
myRealm=com.shyroke.realms.MyRealm
securityManager.realms=$myRealm [urls]
/index.jsp = authc
/ = authc
/admin.jsp = authc,perms[admin:query]
/jsp/user.jsp = authc,perms[user:*]
/jsp/user_add.jsp = authc,perms[user:add]
/login = anon
/logout = logout
myRealm=com.shyroke.realms.MyRealm 表示创建com.shyroke.realms.MyRealm对象,对象名为myRealm。
- login.jsp
<body>
<form action="<%=path%>/login" method="post">
userName:<input type="text" name="username" /><br /> passWord:<input
type="password" name="password" /><br /> <input type="submit"
value="登录">
${requestScope.emsg}
</form>
</body>
- LoginServlet.java(url-pattern=" /login ")
public class LoginServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 如果用户没有登录就即没有在index.jsp页面登录就会跳转到这个方法
*/
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("username");
String passWord = request.getParameter("password");
String emsg = null;
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord);
try {
subject.login(token);
} catch (UnknownAccountException e) {
emsg = "用户名错误";
} catch (IncorrectCredentialsException e) {
emsg = "密码错误";
}
if (emsg != null) {
// 说明认证错误
request.setAttribute("emsg", emsg);
request.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
}
- MyRealm.java
public class MyRealm extends AuthorizingRealm {
UserDao userDao = new UserDao();
/**
* 为当前登录的用户授予角色和权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName=principals.getPrimaryPrincipal().toString();
/**
* 根据用户名获取当前用户的角色和权限集合
*/
Set<String> roles=userDao.getRolesByName(userName);
Set<String> objectPermissions=userDao.getPermissionsByName(userName);
/**
* 为该用户设置角色和权限
*/
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
authorizationInfo.addRoles(roles);
authorizationInfo.setStringPermissions(objectPermissions);
return authorizationInfo;
}
/**
* 验证当前登录的用户
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = token.getPrincipal().toString();
User user = userDao.getUserByName(userName);
if (user != null) {
/*
* 说明用户登录成功
*/
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassWord(),
getName());
return authenticationInfo;
}
return null;
}
}
- UserDao.java
package com.shyroke.dao; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set; import com.shyroke.entity.User;
import com.shyroke.util.DBUtil; public class UserDao { /**
* 根据用户名查询用户
*
* @param userName
* @return User
*/
public User getUserByName(String userName) {
User user = null;
Connection conn = null;
PreparedStatement ps = null;
String sql = "";
ResultSet rs = null;
try {
sql = "select * from user where user_name='" + userName + "'";
conn = DBUtil.getConn();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery(); if (rs.next()) {
user=new User();
user.setId(rs.getInt("user_id"));
user.setUserName(rs.getString("user_name"));
user.setPassWord(rs.getString("user_password"));
} } catch (Exception e) {
e.printStackTrace();
} finally {
try {
DBUtil.close(conn, ps, rs);
} catch (Exception e) {
e.printStackTrace();
}
} return user;
} public Set<String> getRolesByName(String userName) {
Set<String> roles = new HashSet<String>(); Connection conn = null;
PreparedStatement ps = null;
StringBuffer sb = new StringBuffer();
ResultSet rs = null;
try {
sb.append("select role_name from role where role_id in");
sb.append("(");
sb.append("select role_id from user_role where user_id in(");
sb.append("select user_id from user where user_name='" + userName + "')");
sb.append(")");
conn = DBUtil.getConn();
ps = conn.prepareStatement(sb.toString());
rs = ps.executeQuery(); while (rs.next()) {
roles.add(rs.getString("role_name"));
} } catch (Exception e) {
e.printStackTrace();
} finally {
try {
DBUtil.close(conn, ps, rs);
} catch (Exception e) {
e.printStackTrace();
}
} return roles;
} public Set<String> getPermissionsByName(String userName) {
Set<String> perms = new HashSet<String>(); Connection conn = null;
PreparedStatement ps = null;
StringBuffer sb = new StringBuffer();
ResultSet rs = null;
try {
sb.append("select permission_name from permission where permission_id in(");
sb.append("select permission_id from permission_role where role_id in");
sb.append("(");
sb.append("select role_id from user_role where user_id in");
sb.append(" (");
sb.append(" select user_id from user where user_name='"+userName+"'");
sb.append(" )");
sb.append(" )");
sb.append(" )");
conn = DBUtil.getConn();
ps = conn.prepareStatement(sb.toString());
rs = ps.executeQuery(); while (rs.next()) {
perms.add(rs.getString("permission_name"));
} } catch (Exception e) {
e.printStackTrace();
} finally {
try {
DBUtil.close(conn, ps, rs);
} catch (Exception e) {
e.printStackTrace();
}
} return perms;
} }
- user.java
public class User {
private Integer id;
private String userName;
private String passWord;
//省略getset方法
}
- DBUtil.java
public class DBUtil {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USER = "root";
private static final String PASSWD = "";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/shiro?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
private static ComboPooledDataSource dataSource = null;
static {
try {
Class.forName(DRIVER);
Context context = new InitialContext();
dataSource = new ComboPooledDataSource();
dataSource.setMaxPoolSize(50);
dataSource.setInitialPoolSize(20);
dataSource.setJdbcUrl(URL);
dataSource.setDriverClass(DRIVER);
dataSource.setUser(USER);
dataSource.setPassword(PASSWD);
} catch (Exception e) {
throw new RuntimeException("驱动包加载故障");
}
}
public static Connection getConn() {
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static void close(Connection con,PreparedStatement ps,ResultSet rs)throws Exception{
if(con!=null){
con.close();
}
if(ps!=null){
ps.close();
}
if(rs!=null){
rs.close();
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(DBUtil.getConn() + "\t " + i);
}
}
}
- 目录结构

- 结果:








- 本例代码:here
(十)shiro之自定义Realm以及自定义Realm在web的应用demo的更多相关文章
- Apache Shiro 使用手册(四)Realm 实现
在认证.授权内部实现机制中都有提到,最终处理都将交给Real进行处理.因为在Shiro中,最终是通过Realm来获取应用程序中的用户.角色及权限信息的.通常情况下,在Realm中会直接从我们的数据源中 ...
- shiro多realm验证之——shiro实现不同身份使用不同Realm进行验证(转)
转自: http://blog.csdn.net/xiangwanpeng/article/details/54802509 (使用特定的realm实现特定的验证) 假设现在有这样一种需求:存在两张表 ...
- Apache Shiro 使用手册(四)Realm 实现(转发:http://kdboy.iteye.com/blog/1169631)
在认证.授权内部实现机制中都有提到,最终处理都将交给Real进行处理.因为在Shiro中,最终是通过Realm来获取应用程序中的用户.角色及权限信息的.通常情况下,在Realm中会直接从我们的数据源中 ...
- shiro实现不同身份使用不同Realm进行验证
转载:https://blog.csdn.net/xiangwanpeng/article/details/54802509 假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和 ...
- 30、shiro框架入门2,关于Realm
1.Jdbc的Realm链接,并且获取权限 首先创建shiro-jdbc.ini的配置文件,主要配置链接数据库的信息 配置文件中的内容如下所示 1.变量名=全限定类名会自动创建一个类实例 2.变量名. ...
- Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)
Dialog详解(包括进度条.PopupWindow.自定义view.自定义样式的对话框) Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发, ...
- asp.net MVC 自定义@helper 和自定义函数@functions小结
asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...
- activiti自定义流程之自定义表单(三):表单列表及预览和删除
注:(1)环境配置:activiti自定义流程之自定义表单(一):环境配置 (2)创建表单:activiti自定义流程之自定义表单(二):创建表单 自定义表单创建成功,要拿到activiti中使用,自 ...
- activiti自定义流程之自定义表单(二):创建表单
注:环境配置:activiti自定义流程之自定义表单(一):环境配置 在上一节自定义表单环境搭建好以后,我就正式开始尝试自己创建表单,在后台的处理就比较常规,主要是针对ueditor插件的功能在前端进 ...
- MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...
随机推荐
- docker-compose 布署应用nginx中的create-react-app应用获取环境变量
文章来源:https://www.freecodecamp.org/news/how-to-implement-runtime-environment-variables-with-create-re ...
- 腾讯基于 Flink 的实时流计算平台演进之路
https://mp.weixin.qq.com/s/MGnG_Mpf6CUQWLJHvmWqLA
- python方法未绑定错误
相信 Python 程序员多多少少都和我一样遇到过 Method Unbound Error,直译过来就是 “方法未绑定错误”,虽然搜索之后知道了使用 @classmethod 这样的装饰起后就可以解 ...
- java接口如何有效防止恶意请求
java接口如何有效防止恶意请求?已解决 解决方法: 1.在redis数据库db0中新建一个名为rd_sms_request_count表,表结构: Ip:客户请求的ip Success_coun ...
- Qt编写控件属性设计器7-串口采集
一.前言 数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口.网络.数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示. ...
- PAT 甲级 1055 The World's Richest (25 分)(简单题,要用printf和scanf,否则超时,string 的输入输出要注意)
1055 The World's Richest (25 分) Forbes magazine publishes every year its list of billionaires base ...
- (十二)class文件结构:魔数和版本
一.java体系结构 二.class格式文件概述 class文件是一种8位字节的二进制流文件, 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积 ...
- Vue-cli安装,创建Vue项目
1.安装脚手架: npm install -g vue-cli 2.查看vue: vue 3.查看可以使用的模板: vue list 4.创建项目sell: vue init webpack sell ...
- js 如何让两个等长的数组产生键值对关系
问题的准确描述:js 将两个长度一样的一维数组 合成一个一维数组,A为键值,B为key值 js 将两个长度一样的一维数组 合成一个一维数组,A为键值,B为key值 如 var arr1=['a','b ...
- iOS-OC的MRC和ARC内存管理机制
1. Objective-c语言中的MRC(MannulReference Counting) 在MRC的内存管理模式下,对变量的管理相关的方法有:retain,release和autorelease ...