• 我和shiro有个故事02


    springboot+shiro  -----------  明文密码方式

    表还是那三张表

    user表

    (此篇忽略salt盐和加密的密码。这篇使用的明文密码)

    role  角色表

    权限表

    maven 除了基本的spring包还需要shiro包

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

    ----------------------------------------------------------------------------------------------------------------

    我们需要一个 MyShiroRealm 类来做验证和授权的事情

    public class MyShiroRealm extends AuthorizingRealm {
    
    
        @Autowired
        private UserDao userDao;
    
    
    
    
    
    
        //权限信息,包括角色以及权限
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("权限验证----");
            String account = (String) principals.getPrimaryPrincipal();
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            try {
                User user =new User();
                user.setAccount(account);
                authorizationInfo.setRoles(userDao.selectRoleByAccount(user));
    //          authorizationInfo.setStringPermissions(userDao.getPermissions(user));
    
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
    
            }
    
            return authorizationInfo;
        }
    
    
        /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
    
    
            System.out.println("登录验证-------");
            String account= (String) token.getPrincipal();
            try {
                User user_param =new User(); 
                user_param.setAccount(account);
                User user = userDao.selectUserByAccount(user_param);
                if(user!=null){
                    ByteSource salt = ByteSource.Util.bytes(user.getSalt());
                    AuthenticationInfo authcInfo =new SimpleAuthenticationInfo(user.getAccount(),user.getPassword(),"xx");//明文密码验证
                  //  AuthenticationInfo authcInfo =new SimpleAuthenticationInfo(user.getAccount(),user.getPassword(),salt,"xx");   // 加盐加密码的验证
                    return authcInfo;
                }else{
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    一些需要的查询如下

    
         <select id="selectUserByAccount" resultType="User">
    
                select  *  from  tb_user where account=#{account} limit 1;
    
    
         </select>
    
    
        <select id="selectRoleByAccount" resultType="string">
             select r.rolename  from tb_user u,tb_role r where u.roleid = r.roleid and u.account = #{account}
        </select>
    
    

    需要一个shiroconfig来初始化配置

    @Configuration
    public class ShiroConfig {
    
        @Bean
        public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
            System.out.println("ShiroConfiguration.shirFilter()");
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            //拦截器.
            Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
            // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
            filterChainDefinitionMap.put("/css/**", "anon");
            filterChainDefinitionMap.put("/fonts/**", "anon");
            filterChainDefinitionMap.put("/img/**", "anon");
            filterChainDefinitionMap.put("/js/**", "anon");
            filterChainDefinitionMap.put("/html/**", "anon");
            filterChainDefinitionMap.put("/layui/**", "anon");
            filterChainDefinitionMap.put("/UserController/**", "anon");
            //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
            filterChainDefinitionMap.put("/logout", "logout");
            //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
            //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
            filterChainDefinitionMap.put("/**", "authc");
            // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
            shiroFilterFactoryBean.setLoginUrl("/login.html");
            // 登录成功后要跳转的链接
            shiroFilterFactoryBean.setSuccessUrl("/index.html");
    
            //未授权界面;
            shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
        }
    
        /**
         * 凭证匹配器
         * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
         * )
         * @return
         */
        @Bean
        public SimpleCredentialsMatcher hashedCredentialsMatcher(){
                 //  SimpleCredentialsMatcher 对象使用明文验证密码
                // HashedCredentialsMatcher  对象使用加密的方式验证密码
    
    
    //        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    //       hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
    //        hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
    //        return hashedCredentialsMatcher;
            SimpleCredentialsMatcher simpleCredentialsMatcher =new SimpleCredentialsMatcher();
            return simpleCredentialsMatcher;
        }
    
        @Bean
        public MyShiroRealm myShiroRealm(){
            MyShiroRealm myShiroRealm = new MyShiroRealm();
            myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            return myShiroRealm;
        }
    
    
        @Bean
        public SecurityManager securityManager(){
            DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
            securityManager.setRealm(myShiroRealm());
            return securityManager;
        }
    
        /**
         *  开启shiro aop注解支持.
         *  使用代理方式;所以需要开启代码支持;
         * @param securityManager
         * @return
         */
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    
    //    @Bean(name="simpleMappingExceptionResolver")
    //    public SimpleMappingExceptionResolver
    //    createSimpleMappingExceptionResolver() {
    //        SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
    //        Properties mappings = new Properties();
    //        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
    //        mappings.setProperty("UnauthorizedException","/user/403");
    //        r.setExceptionMappings(mappings);  // None by default
    //        r.setDefaultErrorView("error");    // No default
    //        r.setExceptionAttribute("exception");     // Default is "exception"
    //        //r.setWarnLogCategory("example.MvcLogger");     // No default
    //        return r;
    //    }
    
    
    
    
    
    
    
    }

    登录controller验证

       String account = user.getAccount();
                String password = user.getPassword();
    
    
    
                Subject subject = SecurityUtils.getSubject();
    
                //session 失效时间
                subject.getSession().setTimeout(60*30*1000L);
    
                UsernamePasswordToken token = new UsernamePasswordToken(account, password);
    
    
                subject.login(token);
                Session session = subject.getSession();
  • 相关阅读:
    Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)
    Spring Boot 2 快速教程:WebFlux 快速入门(二)
    ES 集群上,业务单点如何优化升级?
    Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)
    泥瓦匠想做一个与众不同的技术"匠"
    java编程行业微信群,无论新手老手欢迎加入,会一直更新
    Spring Boot 2.x 系列教程:WebFlux REST API 全局异常处理 Error Handling
    解决方案:如何防止数据重复插入?
    阿里 Java 手册系列教程:为啥强制子类、父类变量名不同?
    品阿里 Java 开发手册有感
  • 原文地址:https://www.cnblogs.com/fangyuandoit/p/13713804.html
Copyright © 2020-2023  润新知