目录结构:

 数据库结构:

一·web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  3. <display-name>shiro_web</display-name>
  4. <listener>
  5. <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
  6. </listener>
  7. <context-param>
  8. <param-name>shiroEnvironmentClass</param-name>
  9. <param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value>
  10. </context-param>
  11. <context-param>
  12. <param-name>shiroConfigLocations</param-name>
  13. <param-value>classpath:shiro.ini</param-value>
  14. </context-param>
  15. <filter>
  16. <filter-name>shiroFilter</filter-name>
  17. <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
  18. </filter>
  19. <filter-mapping>
  20. <filter-name>shiroFilter</filter-name>
  21. <url-pattern>/*</url-pattern>
  22. </filter-mapping>
  23. </web-app>

二·shiro.ini

  1. [main]
  2. #使用数据库验证授权
  3. databaseRealm=com.yuanbo.DatabaseRealm
  4. securityManager.realms=$databaseRealm
  5. #配置一个url拥有多个role
  6. roles=com.yuanbo.CustomRolesAuthorizationFilter
  7. #没有验证的情况
  8. authc.loginUrl=/login.jsp
  9. #没有角色的情况
  10. roles.unauthorizedUrl=/noRoles.jsp
  11. #没有权限的情况
  12. perms.unauthorizedUrl=/noPerms.jsp
  13. #数据库中取得,不需要配置
  14. [users]
  15. [urls]
  16. /doLogout=logout
  17. #可以匿名访问
  18. /login.jsp=anon
  19. /noRoles.jsp=anon
  20. /noPerms.jsp=anon
  21. #登录后才能查看
  22. /listProduct.jsp=authc
  23. /deleteProduct.jsp=authc,roles[admin,productManager]
  24. /deleteOrder.jsp=authc,perms["deleteOrder"]

三·实体类

  1. package com.yuanbo;
  2.  
  3. public class User {
  4. private int id;
  5. private String name;
  6. private String password;
  7.  
  8. public int getId() {
  9. return id;
  10. }
  11.  
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15.  
  16. public String getName() {
  17. return name;
  18. }
  19.  
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23.  
  24. public String getPassword() {
  25. return password;
  26. }
  27.  
  28. public void setPassword(String password) {
  29. this.password = password;
  30. }
  31.  
  32. }

四·DB

  1. package com.yuanbo;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.util.HashSet;
  9. import java.util.Set;
  10.  
  11. public class Dao {
  12. public Dao() {
  13. try {
  14. Class.forName("com.mysql.jdbc.Driver");
  15. } catch (ClassNotFoundException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19.  
  20. public Connection getConnection() throws SQLException {
  21. return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/shiro?serverTimezone=UTC", "root",
  22. "123456");
  23. }
  24.  
  25. public String getPassword(String userName) {
  26. String sql = "select password from user where name = ?";
  27. try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
  28.  
  29. ps.setString(1, userName);
  30.  
  31. ResultSet rs = ps.executeQuery();
  32.  
  33. if (rs.next())
  34. return rs.getString("password");
  35.  
  36. } catch (SQLException e) {
  37.  
  38. e.printStackTrace();
  39. }
  40. return null;
  41. }
  42.  
  43. public Set<String> listRoles(String userName) {
  44.  
  45. Set<String> roles = new HashSet<>();
  46. String sql = "select r.name from user u " + "left join user_role ur on u.id = ur.uid "
  47. + "left join Role r on r.id = ur.rid " + "where u.name = ?";
  48. try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
  49. ps.setString(1, userName);
  50. ResultSet rs = ps.executeQuery();
  51.  
  52. while (rs.next()) {
  53. roles.add(rs.getString(1));
  54. }
  55.  
  56. } catch (SQLException e) {
  57.  
  58. e.printStackTrace();
  59. }
  60. return roles;
  61. }
  62.  
  63. public Set<String> listPermissions(String userName) {
  64. Set<String> permissions = new HashSet<>();
  65. String sql = "select p.name from user u " + "left join user_role ru on u.id = ru.uid "
  66. + "left join role r on r.id = ru.rid " + "left join role_permission rp on r.id = rp.rid "
  67. + "left join permission p on p.id = rp.pid " + "where u.name =?";
  68.  
  69. try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
  70.  
  71. ps.setString(1, userName);
  72.  
  73. ResultSet rs = ps.executeQuery();
  74.  
  75. while (rs.next()) {
  76. permissions.add(rs.getString(1));
  77. }
  78.  
  79. } catch (SQLException e) {
  80.  
  81. e.printStackTrace();
  82. }
  83. return permissions;
  84. }
  85.  
  86. public static void main(String[] args) {
  87. System.out.println(new Dao().listRoles("zhang3"));
  88. System.out.println(new Dao().listRoles("li4"));
  89. System.out.println(new Dao().listPermissions("zhang3"));
  90. System.out.println(new Dao().listPermissions("li4"));
  91. }
  92. }

五·realm

  1. package com.yuanbo;
  2.  
  3. import java.util.Set;
  4.  
  5. import org.apache.shiro.authc.AuthenticationException;
  6. import org.apache.shiro.authc.AuthenticationInfo;
  7. import org.apache.shiro.authc.AuthenticationToken;
  8. import org.apache.shiro.authc.SimpleAuthenticationInfo;
  9. import org.apache.shiro.authc.UsernamePasswordToken;
  10. import org.apache.shiro.authz.AuthorizationInfo;
  11. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  12. import org.apache.shiro.realm.AuthorizingRealm;
  13. import org.apache.shiro.subject.PrincipalCollection;
  14.  
  15. public class DatabaseRealm extends AuthorizingRealm {
  16.  
  17. @Override
  18. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  19. String userName = (String) principalCollection.getPrimaryPrincipal();
  20. Set<String> permissions = new Dao().listPermissions(userName);
  21. Set<String> roles = new Dao().listRoles(userName);
  22. SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
  23. s.setStringPermissions(permissions);
  24. s.setRoles(roles);
  25. return s;
  26. }
  27.  
  28. @Override
  29. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  30. UsernamePasswordToken t = (UsernamePasswordToken) token;
  31. //String userName = token.getPrincipal().toString();
  32. String userName =new String(t.getUsername());
  33. String password = new String(t.getPassword());
  34.  
  35. String passwordInDB = new Dao().getPassword(userName);
  36.  
  37. if(passwordInDB == null || !passwordInDB.equals(password))
  38. throw new AuthenticationException();
  39.  
  40. SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName,password,getName());
  41. return info;
  42. }
  43.  
  44. }

六·过滤器(一个url多个roles访问)

  1. package com.yuanbo;
  2.  
  3. import javax.servlet.ServletRequest;
  4. import javax.servlet.ServletResponse;
  5.  
  6. import org.apache.shiro.subject.Subject;
  7. import org.apache.shiro.web.filter.authz.AuthorizationFilter;
  8.  
  9. public class CustomRolesAuthorizationFilter extends AuthorizationFilter {
  10.  
  11. @Override
  12. protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception {
  13. Subject subject = getSubject(req, resp);
  14. String[] rolesArray = (String[]) mappedValue;
  15.  
  16. if (rolesArray == null || rolesArray.length == 0) { //没有角色限制,有权限访问
  17. return true;
  18. }
  19. for (int i = 0; i < rolesArray.length; i++) {
  20. if (subject.hasRole(rolesArray[i])) { //若当前用户是rolesArray中的任何一个,则有权限访问
  21. return true;
  22. }
  23. }
  24.  
  25. return false;
  26. }
  27.  
  28. }

七·servlet

  1. package com.yuanbo;
  2.  
  3. import java.io.IOException;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9.  
  10. import org.apache.shiro.SecurityUtils;
  11. import org.apache.shiro.authc.AuthenticationException;
  12. import org.apache.shiro.authc.UsernamePasswordToken;
  13. import org.apache.shiro.session.Session;
  14. import org.apache.shiro.subject.Subject;
  15.  
  16. /**
  17. * Servlet implementation class LoginServlet
  18. */
  19. @WebServlet(name = "loginServlet", urlPatterns = "/login")
  20. public class LoginServlet extends HttpServlet {
  21. private static final long serialVersionUID = 1L;
  22.  
  23. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  24. throws ServletException, IOException {
  25. String userName = request.getParameter("userName");
  26. String password = request.getParameter("password");
  27. Subject subject = SecurityUtils.getSubject();
  28. UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
  29.  
  30. try {
  31. subject.login(token);
  32. Session session = subject.getSession();
  33. session.setAttribute("subject", subject);
  34.  
  35. response.sendRedirect("index.jsp");
  36. } catch (AuthenticationException e) {
  37. request.setAttribute("error","验证失败");
  38. request.getRequestDispatcher("login.jsp").forward(request, response);
  39. }
  40. }
  41.  
  42. }

八·index.jsp

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <%
  6. String path = request.getContextPath();
  7. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  8. %>
  9. <html>
  10. <link rel="stylesheet" type="text/css" href="static/css/style.css"/>
  11. <head>
  12. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  13. <title>Insert title here</title>
  14. </head>
  15. <body>
  16. <div class="workingroom">
  17. <div class="loginDiv">
  18. <c:if test="${empty subject.principal }">
  19. <a href="login.jsp">login</a><br>
  20. </c:if>
  21. <c:if test="${!empty subject.principal }">
  22. <span class="desc">hello,${subject.principal }!</span><br>
  23. <a href="doLogout">logout</a>
  24. </c:if>
  25. <br>
  26. <a href="listProduct.jsp">query product</a><span class="desc">(登录后才能查看)</span><br>
  27. <a href="deleteProduct.jsp">delete product</a><span class="desc">(需要产品管理员角色)</span><br>
  28. <a href="deleteOrder.jsp">delete order</a><span class="desc">(需要删除订单权限)</span><br>
  29. </div>
  30. </div>
  31. </body>
  32. </html>

九·login.jsp

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
  7. + path + "/";
  8. %>
  9. <html>
  10. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  11. <head>
  12. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  13. <title>Insert title here</title>
  14. </head>
  15. <body>
  16. <div class="workingroom">
  17. <div class="errorInfo">${error }</div>
  18. <form action="login" method="post">
  19. account: <input type="text" name="userName" /><br>
  20. password: <input type="password" name="password"/><br>
  21. <br>
  22. <input type="submit" value="login">
  23. <div>
  24. <span class="desc">账号:zhang3 密码:12345 角色:admin</span><br>
  25. <span class="desc">账号:li4 密码:abcde 角色:productManager</span><br>
  26. </div>
  27. </form>
  28. </div>
  29. </body>
  30. </html>

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  7. %>
  8. <html>
  9. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  10. <head>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <title>Insert title here</title>
  13. </head>
  14. <body>
  15. <div class="workingroom">
  16. listProduct.jsp ,能进来,就表示已经登录成功了
  17. <br>
  18. <a href="#" onclick="javascript:history.back()">return</a>
  19. </div>
  20. </body>
  21. </html>

十一

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  7. %>
  8. <html>
  9. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  10. <head>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <title>Insert title here</title>
  13. </head>
  14. <body>
  15. <div class="workingroom">
  16.  
  17. deleteProduct.jsp,能进来<br>就表示拥有 productManager 角色
  18. <br>
  19. <a href="#" onClick="javascript:history.back()">返回</a>
  20. </div>
  21. </body>
  22. </html>

十二

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  7. %>
  8. <html>
  9. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  10. <head>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <title>Insert title here</title>
  13. </head>
  14. <body>
  15. <div class="workingroom">
  16.  
  17. deleteOrder.jsp ,能进来,就表示有deleteOrder权限
  18. <br>
  19. <a href="#" onClick="javascript:history.back()">返回</a>
  20. </div>
  21. </body>
  22. </html>

十三

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  7. %>
  8. <html>
  9. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  10. <head>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <title>Insert title here</title>
  13. </head>
  14. <body>
  15. <div class="workingroom">
  16.  
  17. 权限不足
  18. <br>
  19. <a href="#" onClick="javascript:history.back()">返回</a>
  20. </div>
  21. </body>
  22. </html>

十四

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <%
  5. String path = request.getContextPath();
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  7. %>
  8. <html>
  9. <link rel="stylesheet" type="text/css" href="static/css/style.css" />
  10. <head>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <title>Insert title here</title>
  13. </head>
  14. <body>
  15. <div class="workingroom">
  16.  
  17. 角色不匹配
  18. <br>
  19. <a href="#" onClick="javascript:history.back()">返回</a>
  20. </div>
  21. </body>
  22. </html>

最后,推荐一个java学习平台吧,感觉挺不错的,写得挺细的,还有问答,可以解疑

https://how2j.cn/k/shiro/shiro-web/1722.html?p=81485

shiro实战(1)--web的更多相关文章

  1. Shiro实战教程-刘志敏-专题视频课程

    Shiro实战教程-62人已学习 课程介绍        本教程只介绍基本的 Shiro 使用,不会过多分析源码等,重在使用. 适用人群: 1.了解基于Servlet进行Web应用开发 2.了解Spr ...

  2. 自学Zabbix4.3 zabbix实战监控Web网站性能

    自学Zabbix4.3 zabbix实战监控Web网站性能 用zabbix如何监控web性能和可用性呢?一般分为四个步骤:打开网站.登陆.登陆验证.退出,看实例. 1. 检测流程 1. 打开网站:如果 ...

  3. Apache Shiro:【1】Shiro基础及Web集成

    Apache Shiro:[1]Shiro基础及Web集成 Apache Shiro是什么 Apache Shiro是一个强大且易于使用的Java安全框架,提供了认证.授权.加密.会话管理,与spri ...

  4. Spring Boot集成Shiro实战

    Spring Boot集成Shiro权限验证框架,可参考: https://shiro.apache.org/spring-boot.html 引入依赖 <dependency> < ...

  5. 从0到1实战移动Web App开发

    从0到1实战移动Web App开发   教程介绍 从0到1 实战webapp,通过热门的web前端技术实现移动端app应用,先基础.后实战,在讲解的同时引导思考,会抛出自己独特的观点,一行一行写代码讲 ...

  6. shiro实战系列(九)之Web

    一.Configuration(配置) 将 Shiro 集成到任何 Web 应用程序的最简单的方法是在 web.xml 中配置 ContextListener 和 Filter,理解如何读取 Shir ...

  7. shiro实战系列(二)之入门实战续

    下面讲解基于实战系列一,所以相关的java文件获取pom.xml及其log4j文件同样适用于本次讲解. 一.Using Shiro Using Shiro 现在我们的 SecurityManager ...

  8. shiro实战系列(一)之入门实战

    一.什么是shiro? Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密.   Apache Shiro 的首要目标是易于使用和理解.安全有 ...

  9. Springmvc+Shiro实战

    原文链接:http://blog.csdn.net/qq_37936542/article/details/79010449 springmvc+shiro实现系统粗细粒度的权限管理步骤: 1:表格设 ...

随机推荐

  1. python_tornado

    1.创建Tornado服务器    1.创建Application对象        Application是Torando最核心的类        所有关于服务器的配置信息都写在Applicatio ...

  2. C# MVC 过滤器

    APS.NET MVC中(以下简称“MVC”)的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. MVC支持的过滤器 ...

  3. 带着canvas去流浪系列之三 绘制饼图

    [摘要] 用canvas原生API绘制Echarts图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...

  4. YUM平台的搭建

    网络安全学习内容 三.挂载yum仓库 3.1连接映像文件 步骤如下: 1.右击映像文件,单击设置,选择CentOS映像文件 2.右击映像文件,单击连接 3.2挂载本地yum 打开终端,输入vim /e ...

  5. MySQL必知必会(Select, Where子句)

    SELECT prod_name, prod_price FROM products WHERE prod_price = 2.5; SELECT prod_name, prod_price FROM ...

  6. kafka - java.nio.file.FileSystemException

    在启动Kafka时报错无法启动 E:\kafka_2.12-2.3.1\kafka-logs\__consumer_offsets-48\00000000000000000000.timeindex. ...

  7. Spring AOP简介与底层实现机制——动态代理

    AOP简介 AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想.AOP 是 OOP(面向对象编程 Object Oriented Programmi ...

  8. Unknown class XXViewController in Interface Builder file.”问题处理

    “Unknown class XXViewController in Interface Builder file.”问题处理   在静态库中写了一个XXViewController类,然后在主工程的 ...

  9. Mac 中环境变量的配置

    1. 基本了解 1.1. 查看当前path 在讲解Mac环境变量配置之前,大家可以打开dos框,输入 echo $PATH 查看当前的path. 本机结果: /usr/local/bin:/usr/l ...

  10. Linq 常用操作(增删改)

    增加 using(var db = new Entities()) { //数据操作 UserInfo user = new UserInfo() { UserName = "zhangsa ...