(十)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 ...
随机推荐
- ArcGIS中国工具3.2新功能
ArcGIS中国工具3.2新功能 1. 增加属性格式刷, 2. 编辑自动保存,每5分钟保存一次
- Angular 执行 css3 简单的动画
<div class="content"> 内容区域 <button (click)="showAside()">弹出侧边栏</b ...
- angular 中的dom操作(原生JS)
<h2>这是一个home组件--DOM操作演示</h2> <div id="box"> this is box </div> < ...
- mac安装 bcolz出现错误
使用的是命令pip install bcolz c-blosc//snappy-stubs-:: fatal error: 'algorithm' file not found #include &l ...
- HTML5Audio/Video全解(疑难杂症)
1.mp4格式视频无法在chrome中播放 Chrome浏览器支持HTML5,它支持原生播放部分的MP4格式(不用通过Flash等插件).为 什么是部分MP4呢?MP4有非常复杂的含义(见http:/ ...
- IDEA新建本地项目关联远程git仓库
现在远程git仓库创建一个repository,然后本地创建项目,最后进行关联.三板斧,打完收工. 第一步.第二步地球人都知道,略过不表,第三步比较关键,举个例子: 0.创建本地Git仓库:VCS - ...
- Java高并发程序设计
一.并行世界 摩尔定律的失效,2004年秋季,Intel宣布彻底取消4GHz计划,CPU向多核心的发展,顶级计算机科学家唐纳德丶尔文丶克努斯评价:在我看来,这种现象(并发)或多或少是由于硬件设计者已经 ...
- 安装git和关联gitlab拉取代码步骤
1.双击 “Git-2.9.2-64-bit.exe”文件,一路next安装git程序 2.为github帐号添加SSH keys 3.使用git clone命令从GitLab上同步代码库时,如果使用 ...
- delphi TClientDatset资料
第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...
- node.js使用superagent实现模拟登陆功能(包含下载验证码功能)
superagent版本:3.8.3 样例代码: var process = require('process'); var superagent = require('superagent'); v ...