• 数据库设计

  • 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);
}
}
}
  • 目录结构

  • 结果:

(十)shiro之自定义Realm以及自定义Realm在web的应用demo的更多相关文章

  1. Apache Shiro 使用手册(四)Realm 实现

    在认证.授权内部实现机制中都有提到,最终处理都将交给Real进行处理.因为在Shiro中,最终是通过Realm来获取应用程序中的用户.角色及权限信息的.通常情况下,在Realm中会直接从我们的数据源中 ...

  2. shiro多realm验证之——shiro实现不同身份使用不同Realm进行验证(转)

    转自: http://blog.csdn.net/xiangwanpeng/article/details/54802509 (使用特定的realm实现特定的验证) 假设现在有这样一种需求:存在两张表 ...

  3. Apache Shiro 使用手册(四)Realm 实现(转发:http://kdboy.iteye.com/blog/1169631)

    在认证.授权内部实现机制中都有提到,最终处理都将交给Real进行处理.因为在Shiro中,最终是通过Realm来获取应用程序中的用户.角色及权限信息的.通常情况下,在Realm中会直接从我们的数据源中 ...

  4. shiro实现不同身份使用不同Realm进行验证

    转载:https://blog.csdn.net/xiangwanpeng/article/details/54802509 假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和 ...

  5. 30、shiro框架入门2,关于Realm

    1.Jdbc的Realm链接,并且获取权限 首先创建shiro-jdbc.ini的配置文件,主要配置链接数据库的信息 配置文件中的内容如下所示 1.变量名=全限定类名会自动创建一个类实例 2.变量名. ...

  6. Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

    Dialog详解(包括进度条.PopupWindow.自定义view.自定义样式的对话框)   Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发, ...

  7. asp.net MVC 自定义@helper 和自定义函数@functions小结

    asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...

  8. activiti自定义流程之自定义表单(三):表单列表及预览和删除

    注:(1)环境配置:activiti自定义流程之自定义表单(一):环境配置 (2)创建表单:activiti自定义流程之自定义表单(二):创建表单 自定义表单创建成功,要拿到activiti中使用,自 ...

  9. activiti自定义流程之自定义表单(二):创建表单

    注:环境配置:activiti自定义流程之自定义表单(一):环境配置 在上一节自定义表单环境搭建好以后,我就正式开始尝试自己创建表单,在后台的处理就比较常规,主要是针对ueditor插件的功能在前端进 ...

  10. MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...

随机推荐

  1. React 高阶组件浅析

    高阶组件的这种写法的诞生来自于社区的实践,目的是解决一些交叉问题(Cross-Cutting Concerns).而最早时候 React 官方给出的解决方案是使用 mixin .而 React 也在官 ...

  2. [webpack]深入理解proxy代理

    1.一个基本的代理 module.exports = { //... devServer: { proxy: { '/api': 'http://localhost:3000' } } }; /api ...

  3. 18Flutter中的路由、路由替换、返回到根路由:

    路由: 正常跳转: Navigator.pushNamed(context,'/product');   路由替换: Navigator.pushReplacementNamed(context, ' ...

  4. poi导出excel2007版本

    /** * 导出excel2007版本 * * @param titles * 表头集合 * @param sheetNames * sheet名称 * @param datas * 数据集合 * @ ...

  5. CentOS7下搭建zabbix监控(二)——Zabbix被监控端配置

    Zabbix监控端配置请查看:CentOS7下搭建zabbix监控(一)——Zabbix监控端配置 (1).在CentOS7(被监控端)上部署Zabbix Agent 主机名:youxi2 IP地址: ...

  6. otepad++ 配置 支持jquery、html、css、javascript、php代码提示

    官网下载:http://notepad-plus-plus.org/ 获取插件的方法:打开软件,窗口工具栏有有一个问号,点获取插件. 我使用的插件(安装方法都是官方的方法): QuickText.v0 ...

  7. Javascript的原型链与继承

    目录 1. ES5最经典的寄生组合式继承图 2. ES5和ES6的继承 Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类 ...

  8. linux查看物理cpu的核数,个数,逻辑cpu的个数

    # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数 cat /proc/cpuinfo| ...

  9. (一)MVC项目

    一.整体架构: 注:取自其他文章,最后的NewFile.html纯用于测试错误,完全不用. 二.具体代码: 1.User.java package common; public class User ...

  10. NET Core 3.0中的WPF

    在.NET Core 3.0中的WPF中使用IOC图文教程   我们都知道.NET Core 3.0已经发布了第六个预览版,我们也知道.NET Core 3.0现在已经支持创建WPF项目了,刚好今天在 ...