在一头扎进Shiro-集成Web之前的博客,我们都是用shiro.ini保存用户、角色、权限信息,本篇文章我们将这些信息保存到数据库,通过自定义Realm完成身份验证和权限验证。

去掉用户、角色、权限信息,添加Realm信息的shiro.ini文件信息如下:

[main]
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized.jsp
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.tgb.realm.MyRealm
securityManager.realms=$myRealm
[urls]
/login=anon
/admin=authc
/student=roles[teacher]
/teacher=perms["user:create"]

首先和大家展示下LoginServlet和MyRealm的代码实现,然后结合代码讲解下面的三种验证过程。

LoginServlet:

package com.tgb.servlet;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {System.out.println("login doget");req.getRequestDispatcher("login.jsp").forward(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {System.out.println("login dopost");String userName = req.getParameter("userName");String password = req.getParameter("password");Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(userName,password);try {subject.login(token);resp.sendRedirect("success.jsp");} catch (Exception e) {e.printStackTrace();req.setAttribute("errorInfo", "用户名或密码错误");req.getRequestDispatcher("login.jsp").forward(req, resp);}}}

MyRealm:

package com.tgb.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.tgb.dao.UserDao;
import com.tgb.entity.User;
import com.tgb.util.DbUtil;public class MyRealm extends AuthorizingRealm {private UserDao userDao = new UserDao();private DbUtil dbUtil = new DbUtil();/*** 为当前登录的用户授予权限*/@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.getPermissions(con,userName));} catch (Exception e) {e.printStackTrace();} finally {try {dbUtil.closeCon(con);} catch (Exception e) {}}return authorizationInfo;}/*** 验证当前登录的用户*/@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) {e.printStackTrace();} finally {try {dbUtil.closeCon(con);} catch (Exception e) {e.printStackTrace();}}return null;}
}

success.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"pageEncoding="UTF-8"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>welcome!<shiro:hasRole name="admin">welcome admin user!</shiro:hasRole><shiro:hasPermission name="student:create">welcome student:create user!<shiro:principal/></shiro:hasPermission>
</body>
</html>

用户名不存在验证

   当我们在浏览器输入“http://localhost:8080/ShiroWeb/login”,使用不存在的用户名进行登录后,程序会进入到LoginServlet的subject.login(token)方法,F8执行过,会跳转到MyRealm的doGetAuthenticationInfo(AuthenticationToken token)方法进行身份验证,如果用户名不存在,则通过userDao.getByUserName返回的User实体为空,直接返回到login登录页。

用户名存在、密码不正确验证

  如果我们在登录页输入的用户名正确、密码不正确,则在MyRealm的doGetAuthenticationInfo(AuthenticationToken token)方法中使用AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), "xx")方法,将用户输入保存在token中的用户名、密码和从数据库中查询出的用户名、密码进行比对,比对后发现密码不正确,直接返回到login登录页。

用户名、密码正确验证

  如果我们在登录页输入的用户名、密码都正确,则在MyRealm中的doGetAuthenticationInfo(AuthenticationToken token)身份验证通过,继续在MyRealm的doGetAuthorizationInfo(PrincipalCollection principals)进行权限验证。
  通过authorizationInfo.setRoles(userDao.getRoles(con, userName))和authorizationInfo.setStringPermissions(userDao.getPermissions(con,userName))把根据当前用户名查询出当前用户的角色和权限信息保存到SimpleAuthorizationInfo对象中。
  这样shiro框架便可以根据SimpleAuthorizationInfo对象中的信息判断success.jsp页面中的哪些shiro标签内容可以显示。
  通过上述验证过程我们可以发现,shiro更多的是帮助我们完成验证过程。我们需要从数据库查询当前用户的角色、权限,把这些信息告诉shiro框架,同时在jsp页面定义好哪些内容哪些角色哪些权限可以访问,剩下的就是shiro框架的事儿了。
  shiro是不是很简单?

一头扎进Shiro-自定义Realm相关推荐

  1. 一头扎进Shiro 笔记 实现role permission验证

    maven配置:添加shiro相关的包,以及jdbc相关的包,junit包 <dependency><groupId>junit</groupId><arti ...

  2. 一头扎进Shiro 笔记 Shiro 支持特性

    Web支持   缓存支持   并发支持   测试支持 "RunAs"支持 "Remember Me"支持

  3. 一头扎进Shiro-身份认证

    在<一头扎进Shiro-HelloWorld>中介绍了将用户信息保存在Subject认证主体,用shiro.ini模拟数据库记录用户名.密码信息完成验证的过程,这篇文章我们将讲解如何通过R ...

  4. 曹锋老师《一头扎进EasyUI视频教程》学习笔记(1)

    介绍了一本书<深入浅出设计模式>,来说明"一头扎进"这个系列名字的由来. 参考资料: 1.Easyui中文示例文档 http://www.java1234.com/ea ...

  5. 从实例入手学习Shiro自定义Realm实现查询数据进行验证

    场景 从实例入手学习Shiro与Web的整合: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/90140802 在上面已经实现整合 ...

  6. python自动化框架2019_《一头扎进》系列之Python+Selenium自动化测试框架实战篇6 - 价值好几K的框架,呦!这个框架还真牛叉哦!!!...

    1. 简介 本文开始介绍如何通过unittest来管理和执行测试用例,这一篇主要是介绍unittest下addTest()方法来加载测试用例到测试套件中去.用addTest()方法来加载我们测试用例到 ...

  7. 一头扎进Node系列 - 目录

    前言 本系列是属于初级教程.博主我也还只是一个node的新兵蛋子,想通过学习官网的API文档,慢慢的打好Node基础.当然后期这系列文档会慢慢完善,并且会添加一些项目实战中遇到的一些问题以及解决方案! ...

  8. 一头扎进Mysql视频教程 + 源码

    [@2015-4-8] 记录一下自己的脚印:看到一个一头扎进Mysql视频教程 + 源码果断下载下来,看了看比较到位, 下载地址:http://www.xiaomengku.com/topic?id= ...

  9. 一头扎进SpringBoot视频教程(附源码与文档)

    目录:/099 一头扎进SpringBoot视频教程(附源码与文档) ┣━━<一头扎进SpringBoot>第八讲.mp4 ┣━━<一头扎进SpringBoot>第八讲源码及文 ...

最新文章

  1. Qt安装及配置_很详细(附下载网址)
  2. Django 中ORM 的使用
  3. mac 安装 nodeJsnpm 配置
  4. 超详细百家大厂面试资料,免费送!
  5. android 字符串对齐,android – 使用Spanable String对齐ImageSpan
  6. 手把手教你用tensorflow2.3训练自己的分类数据集
  7. pandas 行列转换
  8. mapreduce推测执行算法及原理
  9. 混合现实手术规划模拟系统——阿里云资源+MR技术在医疗行业的典型应用
  10. 平面的投影变换(1)——什么是投影变换?
  11. node搭建web服务器时,图片显示不出来
  12. Java 提供给第三方使用接口方法
  13. 培训班出来的java程序员,怎么成为真正的技术大牛?
  14. ASP.NET搭建企业微信公众平台源码
  15. 11 万金油 String,为什么不好用了?
  16. 变革中的思索之重读《孙子兵法》
  17. WebGoatV8.1(challenges)详细过关教程
  18. 网站SEO优化的一些知识分享
  19. linux mint 让安卓手机投屏到电脑
  20. oracle增删改查操作

热门文章

  1. 央视炮轰信用卡全额罚息:透支11万5年后还44万
  2. 计算机科学与技术考研双非,这几所双非院校,考研难度堪比985,211!
  3. dell灵越笔记本后盖怎么拆_戴尔inspiron15 5547笔记本怎么拆机清灰?
  4. android音乐播放器开发 SweetMusicPlayer 实现思路
  5. python写新年快乐程序_python turtle 书写新年快乐
  6. 2016April Python学习笔记(pandasecharts)
  7. Vue+nodejs开发的一个处理闲置物品的校园线上交易平台
  8. 基于c#开发的汉诺塔游戏
  9. bjui的validate表单验证的使用
  10. Android M5 新特性