zoukankan      html  css  js  c++  java
  • springboot 整合shiro

    一、创建数据库

    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for mz_permission
    -- ----------------------------
    DROP TABLE IF EXISTS `mz_permission`;
    CREATE TABLE `mz_permission` (
      `id` bigint(8) NOT NULL AUTO_INCREMENT,
      `permission_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '权限名称',
      `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '资源地址',
      `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '权限描述',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `modify_time` datetime DEFAULT NULL COMMENT '修改时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    
    -- ----------------------------
    -- Table structure for mz_permission_role
    -- ----------------------------
    DROP TABLE IF EXISTS `mz_permission_role`;
    CREATE TABLE `mz_permission_role` (
      `role_id` bigint(8) DEFAULT NULL COMMENT '角色ID',
      `permission_id` bigint(8) DEFAULT NULL COMMENT '权限ID'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    
    -- ----------------------------
    -- Table structure for mz_role
    -- ----------------------------
    DROP TABLE IF EXISTS `mz_role`;
    CREATE TABLE `mz_role` (
      `id` bigint(8) NOT NULL AUTO_INCREMENT,
      `role_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色名称',
      `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色描述',
      `create_time` datetime DEFAULT NULL,
      `modify_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    
    -- ----------------------------
    -- Table structure for mz_user
    -- ----------------------------
    DROP TABLE IF EXISTS `mz_user`;
    CREATE TABLE `mz_user` (
      `id` bigint(8) NOT NULL AUTO_INCREMENT,
      `user_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名',
      `password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
      `nickname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '昵称',
      `sex` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '性别',
      `age` int(2) DEFAULT NULL COMMENT '年龄',
      `token` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL,
      `salt` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL,
      `create_time` datetime DEFAULT NULL,
      `modify_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    
    -- ----------------------------
    -- Table structure for mz_user_role
    -- ----------------------------
    DROP TABLE IF EXISTS `mz_user_role`;
    CREATE TABLE `mz_user_role` (
      `user_id` bigint(8) DEFAULT NULL COMMENT '用户ID',
      `role_id` bigint(20) DEFAULT NULL COMMENT '角色ID'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

    二、代码实现

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.3.2</version>
    </dependency>

    1.自定义realm

    import com.mz.cloud.model.MzUser;
    import com.mz.cloud.service.MzUserService;
    import org.apache.shiro.SecurityUtils;
    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 org.apache.shiro.util.ByteSource;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.util.Set;
    
    public class CustomRealm extends AuthorizingRealm {
    
        @Autowired
        private MzUserService mzUserService;
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String userName = (String) SecurityUtils.getSubject().getPrincipal();
    
            //从数据库或者缓存中获取角色数据
            Set<String> roles = mzUserService.getRolesByUserName(userName);
            //获取权限数据
            Set<String> permissions = mzUserService.getPermissionByUserName(userName);
    
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.setRoles(roles);
            simpleAuthorizationInfo.setStringPermissions(permissions);
            return simpleAuthorizationInfo;
        }
    
        //认证登录
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            //获取登录的用户名和密码
            String userName = (String) authenticationToken.getPrincipal();
            String password = new String((char[]) authenticationToken.getCredentials());
    
            //根据用户名获取用户信息
            MzUser mzUser = mzUserService.queryByUserName(userName);
            if (mzUser == null) {
                throw new AccountException("用户不存在");
            }else if (!mzUser.getPassword().equals(MD5Pwd(userName, password))) {
                throw new AccountException("密码不正确");
            }
            return new SimpleAuthenticationInfo(userName, mzUser.getPassword(), ByteSource.Util.bytes(userName + "salt"), getName());
        }
    
        //注册的时候调用这个方法
        public static String MD5Pwd(String userName, String password) {
            //salt盐:userName+salt
            String md5Pwd = new SimpleHash("MD5", password,
                    ByteSource.Util.bytes(userName + "salt"), 2).toHex();
            return md5Pwd;
        }
    
        public static void main(String[] args) {
            System.out.println(MD5Pwd("test", "123456"));
        }
    }

    2.设置配置信息,注入spring容器

    @Configuration
    public class ShiroConfig {
    
        @Bean(name = "shiroFilter")
        public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            // 登录的url
            shiroFilterFactoryBean.setLoginUrl("/mz/user/login");
            // 登录成功后跳转的url
            shiroFilterFactoryBean.setSuccessUrl("/mz/index");
            // 权限拒绝时跳转的url
            shiroFilterFactoryBean.setUnauthorizedUrl("/mz/unauthorize");
    
            // 定义请求拦截规则,key是正则表达式用于匹配访问的路径,value则用于指定使用什么拦截器进行拦截
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            //所有的url必须通过认证才能访问,authc表示需要认证才能访问
            filterChainDefinitionMap.put("/**", "authc");
            // anon表示不拦截
            filterChainDefinitionMap.put("/mz/user/login", "anon");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    
            return shiroFilterFactoryBean;
        }
    
        @Bean
        public SecurityManager securityManager() {
            DefaultSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
            defaultSecurityManager.setRealm(customRealm());
            return defaultSecurityManager;
        }
    
        @Bean
        public CustomRealm customRealm() {
            CustomRealm customRealm = new CustomRealm();
            //告诉realm使用credentialsMatcher加密算法类来验证密文
            customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            customRealm.setCachingEnabled(false);
            return customRealm;
        }
    
        @Bean
        public HashedCredentialsMatcher hashedCredentialsMatcher() {
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
            //散列算法:这里使用MD5算法
            hashedCredentialsMatcher.setHashAlgorithmName("md5");
            //散列的次数,比如散列两次,相当于md5(md5(""));
            hashedCredentialsMatcher.setHashIterations(2);
            //storedCredentialsHexEncoded默认是true,此时的密码加密用的是Hex编码,false时用Base64编码
            hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
            return hashedCredentialsMatcher;
        }
    
        /*
        * 开启@RequirePermission注解的配置,要结合DefaultAdvisorAutoProxyCreator一起使用,或者导入aop的依赖
        */
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    
         @Bean
        public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
              DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
              advisorAutoProxyCreator.setProxyTargetClass(true);
              return advisorAutoProxyCreator;
        }
    
    }

    代码出处:https://www.jianshu.com/p/63449d21b4b9https://blog.51cto.com/zero01/2172662

  • 相关阅读:
    学习笔记8:《大型网站技术架构 核心原理与案例分析》之 固若金汤:网站的安全架构
    学习笔记8:《大型网站技术架构 核心原理与案例分析》之 随需应变:网站的可扩展架构
    13 集合
    12 泛型程序设计
    11 异常, 日志, 断言和调试
    10 部署应用程序和applet
    08 事件处理
    06 接口与内部类
    05 继承
    04 对象与类
  • 原文地址:https://www.cnblogs.com/gyli20170901/p/11226305.html
Copyright © 2011-2022 走看看