• Shiro与web的整合


    pom文件添加依赖

    
    
       4.0.0
    ​
       com.qfedu
       Days62Shiro02Web
       1.0-SNAPSHOT
       war
    ​
       
           8
           8
       
    ​
       
           
               junit
               junit
               4.12
               test
           
    ​
           
               org.apache.shiro
               shiro-web
               1.3.2
           
    ​
           
               mysql
               mysql-connector-java
               8.0.24
           
    ​
           
               com.mchange
               c3p0
               0.9.5.2
           
    ​
           
               commons-logging
               commons-logging
               1.2
           
    ​
           
               javax.servlet
               javax.servlet-api
               3.1.0
               provided
           
    ​
           
               javax.servlet.jsp
               jsp-api
               2.2
               provided
           
    ​
           
               jstl
               jstl
               1.2
           
    ​
           
               org.projectlombok
               lombok
               1.18.16
               provided
           
       
    ​
       
           
               
               
                   org.apache.maven.plugins
                   maven-compiler-plugin
                   3.6.1
                   
                       1.8
                       1.8
                   
               
    ​
               
               
                   org.apache.tomcat.maven
                   tomcat7-maven-plugin
                   2.2
                   
                       /
                       8080
                   
               
           
       
    

    web.xml配置shiro

    
    
       
           org.apache.shiro.web.env.EnvironmentLoaderListener
       
    ​
       
           ShiroFilter
           org.apache.shiro.web.servlet.ShiroFilter
       
    ​
       
           ShiroFilter
           /*
       
    ​
       
           401
           /errorpage.jsp
       
    

    说明:EnvironmentLoaderListener里面包含了SecurityManager对象和ServletContext当中注册shiro, ShiroFilter让所有的请求都经过ShiroFilter过滤器

    1. classpath下的shiro.ini文件

      [main]
      mr=com.qfedu.shiro.MyRealm
      ​
      authc=org.apache.shiro.web.filter.authc.FormAuthenticationFilter
      authc.loginUrl=/login.jsp
      ​
      securityManager.realm=$mr
      [urls]
      ​
      /index.html = anon
      #/user/create = anon
      #/user/** = authc
      #/admin/** = authc, roles[administrator]
      #/rest/** = authc, rest
      #/remoting/rpc/** = authc, perms["remote:invoke"]
      /superManager.jsp=authc, roles[super manager]
      /manager.jsp=authc, roles[manager]
      /guest.jsp=authc, roles[guest]
      /select.jsp=authc, perms[select]
      /save.jsp=authc, perms[save]
      /delete.jsp=authc, perms[delete]
      /update.jsp=authc, perms[update]

      authc代表认证用户, roles[xxx]代表拥有xxx角色的用户, perms[xxx]代表拥有xxx权限的用户, anon匿名用户

    2. UserServlet

      package com.qfedu.controller;
      ​
      import com.qfedu.pojo.Users;
      import com.qfedu.service.IUserService;
      import com.qfedu.service.impl.UserServiceImpl;
      import org.apache.shiro.SecurityUtils;
      import org.apache.shiro.authc.AuthenticationException;
      import org.apache.shiro.authc.UsernamePasswordToken;
      import org.apache.shiro.config.IniSecurityManagerFactory;
      import org.apache.shiro.mgt.SecurityManager;
      import org.apache.shiro.subject.Subject;
      ​
      import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      ​
      @WebServlet(name = "UserServlet", value = "/UserServlet")
      public class UserServlet extends HttpServlet {
      ​
         private IUserService ius = new UserServiceImpl();
      ​
         @Override
         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             String username = request.getParameter("username");
             String password = request.getParameter("password");
      ​
             //
             /shiro的调用/
             // IniSecurityManagerFactory()默认加载shiro.ini文件
             IniSecurityManagerFactory factory = new IniSecurityManagerFactory();
      ​
             SecurityManager securityManager = factory.getInstance();
      ​
             SecurityUtils.setSecurityManager(securityManager);
      ​
             Subject subject = SecurityUtils.getSubject();
      ​
             UsernamePasswordToken token = new UsernamePasswordToken(username, password);
      ​
             try {
      ​
                 // 登录功能,真正实现用户的认证功能
                 subject.login(token);
      ​
                 System.out.println(subject.isAuthenticated());
      ​
      //           System.out.println(subject.hasRole("manager"));
      //
      //           subject.checkPermissions("select", "update");
      ​
                 response.sendRedirect("success.jsp");
            } catch (AuthenticationException e) {
                 e.printStackTrace();
            }
             //
      ​
      //       Users u = ius.login(username, password);
      //
      //       if(u != null){
      //           request.getRequestDispatcher("success.jsp").forward(request,response);
      //       }
        }
      ​
         @Override
         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             doGet(request,response);
        }
      }
      ​

    3. MyRealm

      package com.qfedu.shiro;
      ​
      import com.qfedu.pojo.Perms;
      import com.qfedu.pojo.Roles;
      import com.qfedu.pojo.Users;
      import com.qfedu.service.IUserService;
      import com.qfedu.service.impl.UserServiceImpl;
      import org.apache.shiro.authc.*;
      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 java.util.List;
      ​
      public class MyRealm extends AuthorizingRealm {
      ​
         private IUserService ius = new UserServiceImpl();
      ​
         /**
          * 授权方法,含有的参数是身份集合,使用身份集合就可以获取用户账户信息
          *
          * @param principalCollection
          * @return AuthorizationInfo接口对象
          * 剩余的事情就交给了shiro的会话管理器来自动完成
          */
         @Override
         protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
      ​
             String username = getAvailablePrincipal(principalCollection).toString();
      ​
             System.out.println(username + "---------------");
      ​
             List roles = ius.getRolesByUserName(username);
      ​
             SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      ​
             for (Roles r : roles) {
                 info.addRole(r.getRname());
            }
      ​
             List perms = ius.getPermsByUserName(username);
      ​
             for (Perms p : perms) {
                 info.addStringPermission(p.getPname());
            }
      ​
             return info;
        }
      ​
         /**
          * 认证方法,用户在输入了自己的用户名和密码信息之后,点击提交按钮,即通过subject的login(token)方法,
          * 将请求传递给当前方法,进行认证的处理
          * @param authenticationToken,含有用户名和密码参数的token对象,可以获取到用户名(身份)和密码(凭证)信息
          * @return AuthenticationInfo接口对象
          * @throws AuthenticationException
          */
         @Override
         protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throwsAuthenticationException {
             UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
      ​
             String username = token.getUsername();
             char[] passchar = token.getPassword();     //   为了保证密码的安全性,java几乎将密码都设置成立字符数组
             String password = new String(passchar);
      ​
             System.out.println(username + "\t" + password);
      ​
             Users u = ius.login(username, password);
      ​
             if(u != null){
                 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName());
                 return info;
            }
      ​
             return null;
        }
      }

      以前传统方式是controller->service->dao,dao与数据库交互完成crud功能,返回给dao,返回给service,返回给controller

      shiro与web的整合,则是controller->shiro->service->dao

    4. IUserService.java

      package com.qfedu.service;
      ​
      import com.qfedu.pojo.Perms;
      import com.qfedu.pojo.Roles;
      import com.qfedu.pojo.Users;
      ​
      import java.util.List;
      ​
      public interface IUserService {
      ​
         Users login(String username, String password);
      ​
         List getRolesByUserName(String username);
      ​
         List getPermsByUserName(String username);
      }

    5. UserServiceImpl.java

      package com.qfedu.service.impl;
      ​
      import com.qfedu.dao.IUserDao;
      import com.qfedu.dao.impl.UserDaoImpl;
      import com.qfedu.pojo.Perms;
      import com.qfedu.pojo.Roles;
      import com.qfedu.pojo.Users;
      import com.qfedu.service.IUserService;
      ​
      import java.util.List;
      ​
      public class UserServiceImpl implements IUserService {
      ​
         private IUserDao iud = new UserDaoImpl();
      ​
         @Override
         public Users login(String username, String password) {
             return iud.login(username, password);
        }
      ​
         @Override
         public List getRolesByUserName(String username) {
             return iud.getRolesByUsername(username);
        }
      ​
         @Override
         public List getPermsByUserName(String username) {
             return iud.getPermsByUsername(username);
        }
      }

    6. IUserDao.java

      package com.qfedu.dao;
      ​
      import com.qfedu.pojo.Perms;
      import com.qfedu.pojo.Roles;
      import com.qfedu.pojo.Users;
      ​
      import java.util.List;
      ​
      public interface IUserDao {
      ​
         Users login(String username, String password);
      ​
         List getRolesByUsername(String username);
      ​
         List getPermsByUsername(String username);
      }

    7. UserDaoImpl.java

      package com.qfedu.dao.impl;
      
      import com.qfedu.dao.IUserDao;
      import com.qfedu.pojo.Perms;
      import com.qfedu.pojo.Roles;
      import com.qfedu.pojo.Users;
      import com.qfedu.util.C3P0Util;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.util.ArrayList;
      import java.util.List;
      
      public class UserDaoImpl implements IUserDao {
      
          private Connection conn = null;
          private PreparedStatement ptst = null;
          private ResultSet rs = null;
      
          @Override
          public Users login(String username, String password) {
      
              conn = C3P0Util.getConn();
      
              String sql = "select * from users where username = ? and password =?";
      
              try {
                  ptst = conn.prepareStatement(sql);
      
                  ptst.setString(1, username);
                  ptst.setString(2, password);
      
                  rs = ptst.executeQuery();
      
                  if (rs.next()){
                      int uid = rs.getInt(1);
                      String name = rs.getString(2);
                      String pass = rs.getString(3);
                      String tel = rs.getString(4);
                      String addr = rs.getString(5);
      
                      Users u = new Users();
      
                      u.setUid(uid);
                      u.setUsername(name);
                      u.setPassword(pass);
                      u.setAddr(addr);
                      u.setTel(tel);
      
                      return u;
                  }
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }
      
              return null;
          }
      
          @Override
          public List getRolesByUsername(String username) {
      
              conn = C3P0Util.getConn();
      
              String sql = "select r.* from users u ,\n" +
                      "              user_role ur,\n" +
                      "              roles r\n" +
                      "    where u.uid = ur.uid and ur.rid = r.rid\n" +
                      "    and username = ?";
      
              try {
                  ptst = conn.prepareStatement(sql);
      
                  ptst.setString(1, username);
      
                  rs = ptst.executeQuery();
      
                  List roles = new ArrayList<>();
      
                  while (rs.next()){
                      int rid = rs.getInt(1);
                      String rname = rs.getString(2);
                      String rdesc = rs.getString(3);
      
                      Roles r = new Roles();
      
                      r.setRid(rid);
                      r.setRname(rname);
                      r.setRdesc(rdesc);
      
                      roles.add(r);
      
                  }
                  return roles;
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }
      
              return null;
          }
      
          @Override
          public List getPermsByUsername(String username) {
      
              conn = C3P0Util.getConn();
      
              String sql = "select distinct p.* from users u ,\n" +
                      "                user_role ur,\n" +
                      "                roles r,\n" +
                      "                role_perm rp,\n" +
                      "                perms p\n" +
                      "where u.uid = ur.uid and ur.rid = r.rid\n" +
                      "    and r.rid = rp.rid and rp.pid = p.pid\n" +
                      "  and username = ?";
      
              try {
                  ptst = conn.prepareStatement(sql);
      
                  ptst.setString(1, username);
      
                  rs = ptst.executeQuery();
      
                  List roles = new ArrayList<>();
      
                  while (rs.next()){
                      int rid = rs.getInt(1);
                      String rname = rs.getString(2);
                      String rdesc = rs.getString(3);
      
                      Perms r = new Perms();
      
                      r.setPid(rid);
                      r.setPname(rname);
                      r.setPdesc(rdesc);
      
                      roles.add(r);
                  }
      
                  return roles;
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }
      
              return null;
          }
      }

    8. C3P0Util.java

      package com.qfedu.util;
      
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      
      import java.beans.PropertyVetoException;
      import java.sql.*;
      
      public class C3P0Util {
      
          private final static String DB_URL = Env.getInstance().getProperty("url");
          private final static String DB_DRIVER = Env.getInstance().getProperty("driver");
          private final static String DB_USER = Env.getInstance().getProperty("user");
          private final static String DB_PASS = Env.getInstance().getProperty("pass");
      
          private static Connection conn = null;
      
          public static Connection getConn(){
              try {
      
                  ComboPooledDataSource ds = new ComboPooledDataSource();
      
                  ds.setJdbcUrl(DB_URL);
                  ds.setDriverClass(DB_DRIVER);
                  ds.setUser(DB_USER);
                  ds.setPassword(DB_PASS);
      
                  conn = ds.getConnection();
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              } catch (PropertyVetoException e) {
                  e.printStackTrace();
              }
      
              return conn;
          }
      
          public static void closeAll(Connection conn, PreparedStatement ptst, ResultSet rs){
              try {
                  if(rs != null){
                      rs.close();
                      rs = null;
                  }
                  if(ptst != null){
                      ptst.close();
                      ptst = null;
                  }
                  if(conn != null){
                      conn.close();
                      conn = null;
                  }
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }
          }
      }

    9. Env.java

      package com.qfedu.util;
      
      import java.io.IOException;
      import java.util.Properties;
      
      public class Env extends Properties {
      
          private static Env instance = null;
      
          private Env(){
              try {
                  load(getClass().getResourceAsStream("/db.properties"));
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          public static Env getInstance(){
              if (instance == null){
                  instance = new Env();
              }
              return instance;
          }
      }

    10. db.properties

      driver=com.mysql.cj.jdbc.Driver
      url=jdbc:mysql://localhost:3306/rbac2206?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
      user=java2206
      pass=123456

    11. rbac设计

      create database rbac2206;
      
      use rbac2206;
      
      create table users(
          uid int primary key auto_increment,
          username varchar(20) not null unique,
          password varchar(20) not null,
          tel varchar(11),
          addr varchar(30)
      );
      
      create table roles(
          rid int primary key auto_increment,
          rname varchar(20) not null unique ,
          rdesc varchar(20)
      );
      
      create table perms(
          pid int primary key auto_increment,
          pname varchar(20) not null unique,
          pdesc varchar(20)
      );
      
      insert into users values(null, 'wukong', '888888', '188888888', 'huaguoshan');
      insert into users values(null, 'wuneng', '777777', '177777777', 'gaolaozhuang');
      insert into users values(null, 'wujing', '666666', '166666666', 'liushahe');
      insert into users values(null, 'tangtang', '000000', '100000', 'changan');
      
      insert into roles values(null, 'manager', 'manager desc');
      insert into roles values(null, 'super manager', 'super manager desc');
      insert into roles values(null, 'guest', 'guest desc');
      
      insert into perms values(null, 'select', 'select desc');
      insert into perms values(null, 'save', 'save desc');
      insert into perms values(null, 'delete', 'delete desc');
      insert into perms values(null, 'update', 'update desc');
      
      create table user_role(
          uid int,
          rid int,
          primary key(uid, rid)
      );
      
      create table role_perm(
          rid int,
          pid int,
          primary key(rid, pid)
      );
      
      insert into user_role values(4, 1);
      insert into user_role values(4, 2);
      insert into user_role values(4, 3);
      insert into user_role values(1, 1);
      insert into user_role values(1, 3);
      insert into user_role values(2, 3);
      insert into user_role values(3, 3);
      
      insert into role_perm values(2, 1);
      insert into role_perm values(2, 2);
      insert into role_perm values(2, 3);
      insert into role_perm values(2, 4);
      insert into role_perm values(1, 1);
      insert into role_perm values(1, 4);
      insert into role_perm values(3, 1);
      
      select username, password, addr, tel,
             rname, rdesc, pname, pdesc
          from users u, roles r, perms p,
          user_role ur, role_perm rp
          where u.uid = ur.uid and r.rid = ur.rid
              and p.pid = rp.pid and ur.rid = rp.rid
              order by username;
      
      select r.* from users u ,
                    user_role ur,
                    roles r
          where u.uid = ur.uid and ur.rid = r.rid
          and username = 'tangtang';
      
      
      
      select distinct p.* from users u ,
                      user_role ur,
                      roles r,
                      role_perm rp,
                      perms p
      where u.uid = ur.uid and ur.rid = r.rid
          and r.rid = rp.rid and rp.pid = p.pid
        and username = 'wuneng';

    12. 调用流程

    13. 完成

  • 相关阅读:
    2023-09-16 CSP-J 第一轮初赛真题解析
    信息化、数字化时代的变局,商业智能BI未来发展前景如何?
    阿里妈妈牟娜:定向广告新一代点击率预估主模型——深度兴趣演化网络
    面试百问:项目上线后才发现bug怎么办?
    一幅长文细学Spring(二)——IOC
    Swin Transformer目标检测实验——环境配置的步骤和避坑
    如何编写一个投票功能的智能合约
    [晕事]今天做了件晕事22;寻找99-sysctl.conf; systemd
    云时代【1】—— 云时代的前夜:虚拟化
    「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现
  • 原文地址:https://blog.csdn.net/zpz2001/article/details/127110418