zoukankan      html  css  js  c++  java
  • Java-Shiro(五):Shiro Realm讲解(二)IniRealm的用法、JdbcRelam的用法

    引入

    上一篇在讲解Realm简介时,介绍过Realm包含大概4类缺省的Realm,本章主要讲解:

    1)IniRealm的用法;

    2)JdbcRealm基于mysql   默认表及查询语句实现认证、授权;

    3)JdbcRealm基于mysql自定义表及查询语句实现认证、授权。

    4)自定义Realm。

    在上一张讲解时,截图了一张Realm的类图,这里需要重复引用下:

    从图中,我们可以看出AuthenticatingRealm是AuthorizingRealm的父类:

    1)AuthenticatingRealm类内部对外提供了抽象认证接口:

    2)AuthorizingRealm    类内部对外提供了抽象授权接口:

    3)因AuthorizingRealm继承了AuthenticationgRelam,因此AuthorizingRealm具有了认证、授权接口。

    因此后边讲解自定义Realm时,我们会采用继承 AuthorizingRealm的方式去实现自定义Realm。

    IniRealm的用法

    在Shiro缺省的几种实际上IniRealm和PropertiesRealm的用法最为类似。

    主要是将用户信息、用户角色、用户资源信息存储到相应的*.ini文件中,认证和授权时从文件中查找相应的数据是否存在。

    *.ini主要分为4个部分:[main]、[users]、[roles]、[urls]

    示例:
    shiro-config.ini文件:

    [main] 
    #authenticator 
    #配置验证器
    authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator 
    #配置策略
    authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy 
    #将验证器和策略关联起来
    authenticator.authenticationStrategy=$authenticationStrategy 
    securityManager.authenticator=$authenticator 
      
    #authorizer 
    authorizer=org.apache.shiro.authz.ModularRealmAuthorizer 
    permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver 
    authorizer.permissionResolver=$permissionResolver 
    securityManager.authorizer=$authorizer 
      
    #realm 
    dataSource=com.alibaba.druid.pool.DruidDataSource 
    dataSource.driverClassName=com.mysql.jdbc.Driver 
    dataSource.url=jdbc:mysql://localhost:3306/shiro 
    dataSource.username=root 
    dataSource.password=123456
    
    jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm 
    jdbcRealm.dataSource=$dataSource 
    jdbcRealm.permissionsLookupEnabled=true
    securityManager.realms=$jdbcRealm 
    [users] 
    #提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
    zhangsan=123,admin,member
    lisi=1234,member
    
    [roles] 
    #提供了角色及权限之间关系的配置,角色=权限1,权限2
    admin=article:update,article:delete,article:query
    member=article:query
      
    [urls] 
    #用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器 
    /index.html = anon 
    /admin/** = authc, roles[admin], perms["article:query"] 

    1)[main]模块:

    主要负责shiro相关配置:securityManger,realm,credentialsMatcher,authenticator,authorizer等。
    给securityManger配置authenticator(认证器),authenticator.authenticationStrategy(认证器的多realm策略)
    给securityManger配置authorizer(授权器),authorizer.permissionResolver(授权器的资源解析器)
    给securityManger配置realms,realm(认证、授权 存储器).属性设置(JdbcRealm.dataSource/JdbcRealm.permissionLookupEnabled)
    给realm配置credentialsMatcher(凭证匹配器:它内部包含采用哪种方式进行加密:md5、sha256,slat[盐值],hashIterations[加密迭代多少次])

    2)[users]模块:
    提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2,示例:

    [users]
    zhangsan=123,admin,member lisi=1234,member

    3)[roles]模块:
    提供了角色及权限之间关系的配置,角色=权限1,权限2,示例:

    [roles]
    admin=article:update,article:delete,article:query member=article:query

    4)[urls]模块:
    用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器,示例:

    [urls]
    /index.html = anon /admin/** = authc, roles[admin], perms["article:query"]

    上边配置信息在shiro比较早点版本(shiro1.4.2就不是特别好用了)可使用IniSecurityManagerFactory进行加载:

    Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-config.ini"); 
    org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); 
     
    //将SecurityManager设置到SecurityUtils 方便全局使用 
    SecurityUtils.setSecurityManager(securityManager); 
    Subject subject = SecurityUtils.getSubject(); 
    UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); 
    subject.login(token); 
      
    Assert.assertTrue(subject.isAuthenticated()); 

     实际上边配置shiro-config.xml中[main]配置信息等同于:

            DefaultSecurityManager securityManager = new DefaultSecurityManager();
    
            // #配置验证器
            ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
            // #配置策略
            AtLeastOneSuccessfulStrategy authenticationStrategy = new AtLeastOneSuccessfulStrategy();
            // #将验证器和策略关联起来
            authenticator.setAuthenticationStrategy(authenticationStrategy);
            securityManager.setAuthenticator(authenticator);
    
            // #授权器
            ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
            WildcardPermissionResolver permissionResolver = new WildcardPermissionResolver();
            authorizer.setPermissionResolver(permissionResolver);
            securityManager.setAuthorizer(authorizer);
    
            DruidDataSource dataSource = new DruidDataSource();
            {
                dataSource.setUsername("root");
                dataSource.setPassword("123456");
                dataSource.setUrl(
                        "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
                dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            }
    
            JdbcRealm jdbcRealm = new JdbcRealm();
            jdbcRealm.setDataSource(dataSource);
            // JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
            jdbcRealm.setPermissionsLookupEnabled(true);
    
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");
            credentialsMatcher.setHashIterations(8);
            jdbcRealm.setCredentialsMatcher(credentialsMatcher);
            
            securityManager.setRealms(Arrays.asList(jdbcRealm));

    使用时,通过SecurityUtils与securityManager进行关联,然后获取Subject对象,通过subject进行认证验证,授权验证,退出认证。

            SecurityUtils.setSecurityManager(securityManager);
    
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            subject.login(token);
            System.out.println("是否通过认证:" + subject.isAuthenticated());
    
            System.out.println("是否拥有admin角色:" + subject.hasRole("admin"));
            // 必须设置JdbcRealm为jdbcRealm.setPermissionsLookupEnabled(true)
            // 是否拥有修改的权限
            System.out.println("是否拥有user:update角色:" + subject.isPermitted("user:update"));
    
            subject.logout();
            System.out.println("是否通过认证:" + subject.isAuthenticated());

    IniRealm的使用示例:

    1)认证用法:

    配置文件 shiroAuthenticator.ini

    #用来认证
    #============================
    #设置用户,可设置多名用户
    [users]
    # 用户名=密码
    zhangsan=123
    lisi=1234

    用法测试:

        /**
         * 测试认证
         */
        @Test
        public void testAuthenticator() {
            // 1)根据IniRealm进行数据读取 *.ini 配置,另外也可以通过JdbcRealm读取数据中存储的信息,也可以采用内存存储方式,还可以用户自定义。
            // Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager需验证用户身份,那么它需要从Realm获取响应的用户进行比较以确定用户身份是否合法;
            // 也需要从Realm得到用户相应的角色、权限进行验证用户是否能进行操作;
            // 可以把Realm看成DataSource。
            Realm iniRealm = new IniRealm("classpath:shiroAuthenticator.ini");
    
            // 2) 管理所有的Subject,负责认证、授权、会话以及缓存的管理。
            // SecurityManager:安全管理器,即所有与安全有关的操作都会与SecurityManager交互;
            // 且其管理所有Subject;
            // 可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC中DispatcherServlet的角色。
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(iniRealm);
    
            SecurityUtils.setSecurityManager(defaultSecurityManager);
            // Subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject。
            // Subject代表了当前"用户",这个用户不一定就是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;
            // 与Subject的所有交互都委托给SecurityManager;
            // Subject其实是一个门面,SecurityManager才是实际的执行者;
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            // 进行认证
            subject.login(token);
    
            System.out.println("是否认证通过:" + subject.isAuthenticated());
        }

    2)授权的用法:

    配置文件 shiroAuthorizer.ini

    #用来授权
    #===========================
    #设置用户及用户角色
    [users]
    # 用户名=密码,角色
    zhangsan=123,admin
    lisi=1234,member
    
    #设置角色与角色权限
    [roles]
    # 角色=资源1,资源2
    admin=user:delete,user:update,user:query
    member=user:query

    用法测试:

        /**
         * 测试认证+授权
         */
        @Test
        public void testAuthorizer() {
            Realm iniRealm = new IniRealm("classpath:shiroAuthorizer.ini");
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(iniRealm);
    
            SecurityUtils.setSecurityManager(defaultSecurityManager);
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            // 调用 Realm#getAuthenticationinfo()
            subject.login(token);
    
            System.out.println("是否认证通过:" + subject.isAuthenticated());
    
            // 调用 Realm#getAuthorizationinfo()
            System.out.println("是否授权admin角色:" + subject.hasRole("admin"));
            System.out.println("是否拥有user:update资源:" + subject.isPermitted("user:update"));
            System.out.println("是否拥有user:delete资源:" + subject.isPermitted("user:delete"));
            System.out.println("是否拥有user:create资源:" + subject.isPermitted("user:create"));
    
            subject.logout();
    
            System.out.println("是否认证通过:" + subject.isAuthenticated());
    
            System.out.println("是否授权admin角色:" + subject.hasRole("admin"));
            System.out.println("是否拥有user:update资源:" + subject.isPermitted("user:update"));
            System.out.println("是否拥有user:delete资源:" + subject.isPermitted("user:delete"));
            System.out.println("是否拥有user:create资源:" + subject.isPermitted("user:create"));
        }

    JdbcRealm的用法

    使用JdbcRealm内部默认表和查询SQL

    JdbcRealm实际上在代码内部缺省在关系数据库中存在三张表:

    `users`{id,username,password,password_salt}
    `user_roles`{id,username,role_name}
    `roles_permissions`{id,role_name,permission}

    其实,从JdbcRealm内部定义的查询语句可以看出内置表结构:

        /**
         * The default query used to retrieve account data for the user.
         */
        protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
        
        /**
         * The default query used to retrieve account data for the user when {@link #saltStyle} is COLUMN.
         */
        protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
    
        /**
         * The default query used to retrieve the roles that apply to a user.
         */
        protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
    
        /**
         * The default query used to retrieve permissions that apply to a particular role.
         */
        protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";

    JdbcRealm使用时,需要在关系数据库中创建默认的那三张表,然后配置信息写入到对应表中。

    -- ----------------------------
    -- Table structure for users
    -- ----------------------------
    DROP TABLE IF EXISTS `users`;
    CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(64) NOT NULL,
      `password` varchar(64) NOT NULL,
      `password_salt` varchar(64) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_username` (`username`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of users
    -- ----------------------------
    BEGIN;
    INSERT INTO `users` VALUES (1, 'zhangsan', '0349a8cd4b237e190e6e4b471e214ef3','eC4mL7bZ5sN8');
    INSERT INTO `users` VALUES (2, 'lisi', '4d7a330008c2191c4c76b9b3dd59841d','qN3fT4eK2yQ9');
    COMMIT;
    
    -- ----------------------------
    -- Table structure for user_roles
    -- ----------------------------
    DROP TABLE IF EXISTS `user_roles`;
    CREATE TABLE `user_roles` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(64) NOT NULL,
      `role_name` varchar(64) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_role_name` (`role_name`),
      KEY `idx_username` (`username`),
      KEY `idx_role_name` (`role_name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user_roles
    -- ----------------------------
    BEGIN;
    INSERT INTO `user_roles` VALUES (1, 'zhangsan', 'admin');
    INSERT INTO `user_roles` VALUES (2, 'lisi', 'member');
    COMMIT;
    
    -- ----------------------------
    -- Table structure for roles_permissions
    -- ----------------------------
    DROP TABLE IF EXISTS `roles_permissions`;
    CREATE TABLE `roles_permissions` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `role_name` varchar(64) DEFAULT NULL,
      `permission` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_role_name_permission` (`role_name`,`permission`),
      KEY `idx_role_name` (`role_name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of roles_permissions
    -- ----------------------------
    BEGIN;
    INSERT INTO `roles_permissions` VALUES (2, 'admin', 'user:delete');
    INSERT INTO `roles_permissions` VALUES (1, 'admin', 'user:update');
    INSERT INTO `roles_permissions` VALUES (3, 'member', 'user:query');
    COMMIT;

    使用测试代码:

        /**
         * 使用默认 JdbcRealm 中相关表进行相关登录认证、使用默认的sql语句进行授权
         */
        @Test
        public void testJdbcRealmByDefaultDBConfiguration() {
            DefaultSecurityManager securityManager = new DefaultSecurityManager();
    
            // #配置验证器
            ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
            // #配置策略
            AtLeastOneSuccessfulStrategy authenticationStrategy = new AtLeastOneSuccessfulStrategy();
            // #将验证器和策略关联起来
            authenticator.setAuthenticationStrategy(authenticationStrategy);
            securityManager.setAuthenticator(authenticator);
    
            // #授权器
            ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
            WildcardPermissionResolver permissionResolver = new WildcardPermissionResolver();
            authorizer.setPermissionResolver(permissionResolver);
            securityManager.setAuthorizer(authorizer);
    
            DruidDataSource dataSource = new DruidDataSource();
            {
                dataSource.setUsername("root");
                dataSource.setPassword("123456");
                dataSource.setUrl(
                        "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
                dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            }
    
            JdbcRealm jdbcRealm = new JdbcRealm();
            jdbcRealm.setDataSource(dataSource);
            // JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
            jdbcRealm.setPermissionsLookupEnabled(true);
    
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");
            credentialsMatcher.setHashIterations(8);
            jdbcRealm.setCredentialsMatcher(credentialsMatcher);
            
            securityManager.setRealms(Arrays.asList(jdbcRealm));
    
            SecurityUtils.setSecurityManager(securityManager);
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            subject.login(token);
            System.out.println("是否通过认证:" + subject.isAuthenticated());
    
            System.out.println("是否拥有admin角色:" + subject.hasRole("admin"));
            // 必须设置JdbcRealm为jdbcRealm.setPermissionsLookupEnabled(true)
            // 是否拥有修改的权限
            System.out.println("是否拥有user:update角色:" + subject.isPermitted("user:update"));
    
            subject.logout();
            System.out.println("是否通过认证:" + subject.isAuthenticated());
        }

    打印信息:

    log4j:WARN No appenders could be found for logger (com.alibaba.druid.pool.DruidDataSource).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    是否通过认证:true
    是否拥有admin角色:true
    是否拥有user:update角色:true
    是否通过认证:false

    JdbcRealm使用自定义表和插叙SQL

    需要在关系数据自定义三张表:my_user,my_role,my_permission。

    -- ----------------------------
    -- Table structure for my_user
    -- ----------------------------
    DROP TABLE IF EXISTS `my_user`;
    CREATE TABLE `my_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(64) NOT NULL,
      `password` varchar(64) NOT NULL,
      `password_salt` varchar(64) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_username` (`username`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of my_user
    -- ----------------------------
    BEGIN;
    INSERT INTO `my_user` VALUES (1, 'zhangsan', '0349a8cd4b237e190e6e4b471e214ef3','eC4mL7bZ5sN8');
    INSERT INTO `my_user` VALUES (2, 'lisi', '4d7a330008c2191c4c76b9b3dd59841d','qN3fT4eK2yQ9');
    COMMIT;
    
    -- ----------------------------
    -- Table structure for my_role
    -- ----------------------------
    DROP TABLE IF EXISTS `my_role`;
    CREATE TABLE `my_role` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(64) NOT NULL,
      `role_name` varchar(64) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_role_name` (`role_name`) USING BTREE,
      KEY `idx_username` (`username`),
      KEY `idx_role_name` (`role_name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of my_role
    -- ----------------------------
    BEGIN;
    INSERT INTO `my_role` VALUES (1, 'zhangsan', 'admin');
    INSERT INTO `my_role` VALUES (2, 'lisi', 'member');
    COMMIT;
    -- ----------------------------
    -- Table structure for my_permission
    -- ----------------------------
    DROP TABLE IF EXISTS `my_permission`;
    CREATE TABLE `my_permission` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `role_name` varchar(64) DEFAULT NULL,
      `permission` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `un_idx_role_name_permission` (`role_name`,`permission`) USING BTREE,
      KEY `idx_role_name` (`role_name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of my_permission
    -- ----------------------------
    BEGIN;
    INSERT INTO `my_permission` VALUES (2, 'admin', 'user:delete');
    INSERT INTO `my_permission` VALUES (1, 'admin', 'user:update');
    INSERT INTO `my_permission` VALUES (3, 'member', 'user:query');
    COMMIT;

    使用测试:

        @Test
        public void testJdbcRealmByMyDBConfiguration() {
            DruidDataSource dataSource = new DruidDataSource();
            {
                dataSource.setUsername("root");
                dataSource.setPassword("123456");
                dataSource.setUrl(
                        "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
                dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            }
    
            JdbcRealm jdbcRealm = new JdbcRealm();
            jdbcRealm.setDataSource(dataSource);
            // JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
            jdbcRealm.setPermissionsLookupEnabled(true);
            jdbcRealm.setSaltStyle(SaltStyle.COLUMN); // 启用表 password_salt 字段
            
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");
            credentialsMatcher.setHashIterations(8);
            jdbcRealm.setCredentialsMatcher(credentialsMatcher);
            
            jdbcRealm.setAuthenticationQuery("select `password`,`password_salt` from `my_user` where `username`=? ");
            jdbcRealm.setUserRolesQuery("select `role_name` from `my_role` where `username`=? ");
            jdbcRealm.setPermissionsQuery("select `permission` from `my_permission` where role_name=? ");
    
            // 创建SecurityManager;
            DefaultSecurityManager securityManager = new DefaultSecurityManager(jdbcRealm);
    
            SecurityUtils.setSecurityManager(securityManager);
            Subject subject = SecurityUtils.getSubject();
    
            subject.logout();
            UsernamePasswordToken token = new UsernamePasswordToken("lisi", "1234");
            subject.login(token);
    
            System.out.println("是否通过认证:" + subject.isAuthenticated());
            System.out.println("是否已经授权member角色:" + subject.hasRole("member"));
            System.out.println("是否已经授权admin角色:" + subject.hasRole("admin"));
    
            System.out.println("是否已经拥有user:create资源:" + subject.isPermitted("user:create"));
            System.out.println("是否已经拥有user:update资源:" + subject.isPermitted("user:update"));
            System.out.println("是否已经拥有user:delete资源:" + subject.isPermitted("user:delete"));
            System.out.println("是否已经拥有user:query资源:" + subject.isPermitted("user:query"));
    
            subject.logout();
            System.out.println("是否通过认证:" + subject.isAuthenticated());
        }

    打印结果:

    log4j:WARN No appenders could be found for logger (com.alibaba.druid.pool.DruidDataSource).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    是否通过认证:true
    是否已经授权member角色:true
    是否已经授权admin角色:false
    是否已经拥有user:create资源:false
    是否已经拥有user:update资源:false
    是否已经拥有user:delete资源:false
    是否已经拥有user:query资源:true
    是否通过认证:false
  • 相关阅读:
    CoreBluetooth
    IOS Monkey 测试
    Ruby+appium实现截图、滑屏、长按、日志输出到本地文件夹
    maven中GroupID 和ArtifactID怎么写
    MAC安装Eclipse及对其进入相关配置
    单元测试断言利器 AssertJ
    python+appium app自动化的方法实例运用
    美团接口自动化测试实践
    appium滑动操作总结
    Appium+python自动化-Appium Python API
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/12089148.html
Copyright © 2011-2022 走看看