• SpringBoot-Shiro普通登录与MD5加密


    RBAC 是当下权限系统的设计基础,同时有两种解释:
    一: Role-Based Access Control,基于角色的访问控制
    即,你要能够删除产品,那么当前用户就必须拥有产品经理这个角色
    二:Resource-Based Access Control,基于资源的访问控制
    即,你要能够删除产品,那么当前用户就必须拥有删除产品这样的权限

    Shrio

    shrio两种登录方式:1、读取shrio.ini配置文件 2、使用 DatabaseRealm(数据库连接比较)

    MD5加密的时候:使用传入密码需要加密、插入语句需要加密,DatabaseRealm需要加密.

    package com.company;
    
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    
    import java.util.Set;
    
    public class DatabaseRealm extends AuthorizingRealm {
    
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    
            //能进入到这里,表示账号已经通过验证了
            String userName =(String) principalCollection.getPrimaryPrincipal();
            //通过DAO获取角色和权限
            Set<String> permissions = new UserDao().listPermissions(userName);
            Set<String> roles = new UserDao().listRoles(userName);
    
            //授权对象
            SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
            //把通过DAO获取到的角色和权限放进去
            s.setStringPermissions(permissions);
            s.setRoles(roles);
            return s;
        }
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //获取账号密码
            UsernamePasswordToken t = (UsernamePasswordToken) token;
            String userName= token.getPrincipal().toString();
            String password =new String(t.getPassword());
            //获取数据库中的密码
    
            User user = new UserDao().getUser(userName);
            String passwordInDB = user.getPassword();
            String salt = user.getSalt();
            String passwordEncoded = new SimpleHash("md5",password,salt,2).toString();
    
            if(null==user || !passwordEncoded.equals(passwordInDB))
                throw new AuthenticationException();
    
            //认证信息里存放账号密码, getName() 是当前Realm的继承方法,通常返回当前类名 :databaseRealm
            SimpleAuthenticationInfo a = new SimpleAuthenticationInfo(userName,password,getName());
            return a;
        }
    
    }
    
    

    UserDao.java

    package com.company;
    
    import org.apache.shiro.crypto.SecureRandomNumberGenerator;
    import org.apache.shiro.crypto.hash.SimpleHash;
    
    import java.sql.*;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @ProjectName: UserDao
     * @Package: com.company
     * @Description:
     * @Author: huyuqiao
     * @CreateDate: 2020/9/25 10:16
     */
    public class UserDao {
        public UserDao(){
            try{
                Class.forName("com.mysql.cj.jdbc.Driver");
            } catch (ClassNotFoundException e){
                e.printStackTrace();
            }
        }
        public Connection getConnection() throws SQLException {
            return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/shiro?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false", "root", "root");
        }
    
        public String createUser(String name, String password) {
    
            String sql = "insert into user values(null,?,?,?)";
    
            String salt = new SecureRandomNumberGenerator().nextBytes().toString(); //盐量随机
            String encodedPassword= new SimpleHash("md5",password,salt,2).toString();
    
            try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
    
                ps.setString(1, name);
                ps.setString(2, encodedPassword);
                ps.setString(3, salt);
                ps.execute();
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return null;
    
        }
    
        public String getPassword(String userName) {
            String sql = "select password from user where name = ?";
            try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
    
                ps.setString(1, userName);
    
                ResultSet rs = ps.executeQuery();
    
                if (rs.next())
                    return rs.getString("password");
    
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return null;
        }
        public User getUser(String userName) {
            User user = null;
            String sql = "select * from user where name = ?";
            try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
    
                ps.setString(1, userName);
    
                ResultSet rs = ps.executeQuery();
    
                if (rs.next()) {
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setName(rs.getString("name"));
                    user.setPassword(rs.getString("password"));
                    user.setSalt(rs.getString("salt"));
                }
    
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return user;
        }
    
        public Set<String> listRoles(String userName) {
    
            Set<String> roles = new HashSet<>();
            String sql = "select r.name from user u "
                    + "left join user_role ur on u.id = ur.uid "
                    + "left join Role r on r.id = ur.rid "
                    + "where u.name = ?";
            try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
                ps.setString(1, userName);
                ResultSet rs = ps.executeQuery();
    
                while (rs.next()) {
                    roles.add(rs.getString(1));
                }
    
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return roles;
        }
        public Set<String> listPermissions(String userName) {
            Set<String> permissions = new HashSet<>();
            String sql =
                    "select p.name from user u "+
                            "left join user_role ru on u.id = ru.uid "+
                            "left join role r on r.id = ru.rid "+
                            "left join role_permission rp on r.id = rp.rid "+
                            "left join permission p on p.id = rp.pid "+
                            "where u.name =?";
    
            try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
    
                ps.setString(1, userName);
    
                ResultSet rs = ps.executeQuery();
    
                while (rs.next()) {
                    permissions.add(rs.getString(1));
                }
    
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return permissions;
        }
    
        public static void main(String[] args) throws Throwable {
            System.out.println(new UserDao().listRoles("zhang3"));
            System.out.println(new UserDao().listRoles("li4"));
            System.out.println(new UserDao().listPermissions("zhang3"));
            System.out.println(new UserDao().listPermissions("li4"));
        }
    }
    
    

    TestShiro.java

    package com.company;
    
    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 org.apache.shiro.util.Factory;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @ProjectName: TestShiro
     * @Package: com.company
     * @Description:
     * @Author: huyuqiao
     * @CreateDate: 2020/9/25 9:35
     */
    public class TestShiro {
        public static void main(String[] args) {
            new UserDao().createUser("tom", "123");
            User user22 = new User();
            user22.setName("tom");
            user22.setPassword("123");
    
            if(login(user22))
                System.out.println("登录成功");
            else
                System.out.println("登录失败");
    
            //用户们
            User zhang3 = new User();
            zhang3.setName("zhang3");
            zhang3.setPassword("12345");
    
            User li4 = new User();
            li4.setName("li4");
            li4.setPassword("abcde");
    
            User wang5 = new User();
            wang5.setName("wang5");
            wang5.setPassword("wrongpassword");
    
            List<User> users = new ArrayList<>();
    
            users.add(zhang3);
            users.add(li4);
            users.add(wang5);
            //角色们
            String roleAdmin = "admin";
            String roleProductManager ="productManager";
    
            List<String> roles = new ArrayList<>();
            roles.add(roleAdmin);
            roles.add(roleProductManager);
    
            //权限们
            String permitAddProduct = "addProduct";
            String permitAddOrder = "addOrder";
    
            List<String> permits = new ArrayList<>();
            permits.add(permitAddProduct);
            permits.add(permitAddOrder);
    
            //登陆每个用户
            for (User user : users) {
                if(login(user))
                    System.out.printf("%s 	成功登陆,用的密码是 %s	 %n",user.getName(),user.getPassword());
                else
                    System.out.printf("%s 	成功失败,用的密码是 %s	 %n",user.getName(),user.getPassword());
            }
    
            System.out.println("-------how2j 分割线------");
    
            //判断能够登录的用户是否拥有某个角色
            for (User user : users) {
                for (String role : roles) {
                    if(login(user)) {
                        if(hasRole(user, role))
                            System.out.printf("%s	 拥有角色: %s	%n",user.getName(),role);
                        else
                            System.out.printf("%s	 不拥有角色: %s	%n",user.getName(),role);
                    }
                }
            }
            System.out.println("-------how2j 分割线------");
    
            //判断能够登录的用户,是否拥有某种权限
            for (User user : users) {
                for (String permit : permits) {
                    if(login(user)) {
                        if(isPermitted(user, permit))
                            System.out.printf("%s	 拥有权限: %s	%n",user.getName(),permit);
                        else
                            System.out.printf("%s	 不拥有权限: %s	%n",user.getName(),permit);
                    }
                }
            }
        }
    
        private static boolean hasRole(User user, String role) {
            Subject subject = getSubject(user);
            return subject.hasRole(role);
        }
    
        private static boolean isPermitted(User user, String permit) {
            Subject subject = getSubject(user);
            return subject.isPermitted(permit);
        }
    
        private static Subject getSubject(User user) {
            //加载配置文件,并获取工厂
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            //获取安全管理者实例
            SecurityManager sm = factory.getInstance();
            //将安全管理者放入全局对象
            SecurityUtils.setSecurityManager(sm);
            //全局对象通过安全管理者生成Subject对象
            Subject subject = SecurityUtils.getSubject();
    
            return subject;
        }
    
        private static boolean login(User user) {
            Subject subject= getSubject(user);
            //如果已经登录过了,退出
            if(subject.isAuthenticated())
                subject.logout();
    
            //封装用户的数据
            UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user.getPassword());
            try {
                //将用户的数据token 最终传递到Realm中进行对比
                subject.login(token);
            } catch (AuthenticationException e) {
                //验证错误
                return false;
            }
    
            return subject.isAuthenticated();
        }
    
    }
    
    
  • 相关阅读:
    关于apache的动态与静态编译
    使用awk处理正则表达式时注意事项
    fedora下apache默认配置
    vim显示行号、语法高亮、自动缩进的设置
    简单介绍apahce内存管理机制
    处理路径上的小技巧
    Educational Codeforces Round 80 (Rated for Div. 2)
    web前端页面性能优化小结
    web标准—可用性、可维护性、可访问性
    雅虎团队经验:网站页面性能优化的 34条黄金守则
  • 原文地址:https://www.cnblogs.com/meditation5201314/p/13731955.html
Copyright © 2020-2023  润新知