美文网首页
Shiro + MySQL动态权限验证

Shiro + MySQL动态权限验证

作者: 索伦x | 来源:发表于2019-06-04 23:22 被阅读0次

    数据库设计


    在实际开发中,用户名密码、角色、权限需要存在数据库中动态管理。一个简单的Shiro+MySQL的项目需要三张表:

    用户表SHIRO_USER:
    测试数据:
    用户角色表SHIRO_USER_ROLE:
    测试数据:
    角色权限表SHIRO_ROLE_PERMISSION:
    测试数据:

    添加依赖

    <dependencies>
        <!--shiro核心类库-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!--日志工具包-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>
    </dependencies>
    <!-- shiro动态权限控制 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.32</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.3.11.RELEASE</version>
    </dependency>
    

    配置文件

    配置文件在使用jdbc数据源的时候,不需要指定user和roles,而是在配置文件中指定数据库连接信息和要执行的sql语句。

    在resources文件夹下创建配置文件shiro-mysql.ini:

    [main]
    dataSource=org.springframework.jdbc.datasource.DriverManagerDataSource
    dataSource.driverClassName=com.mysql.jdbc.Driver
    dataSource.url=jdbc:mysql://127.0.0.1:3306/数据库名
    dataSource.username=用户名
    #如果数据库没有密码,就不要写这行
    dataSource.password=你的密码
    jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
    #是否检查权限
    jdbcRealm.permissionsLookupEnabled = true
    jdbcRealm.dataSource=$dataSource
    #重写sql语句
    #根据用户名查询出密码
    jdbcRealm.authenticationQuery = select PASSWORD from SHIRO_USER where USER_NAME = ?
    #根据用户名查询出角色
    jdbcRealm.userRolesQuery = select ROLE_NAME from SHIRO_USER_ROLE where USER_NAME = ?
    #根据角色名查询出权限
    jdbcRealm.permissionsQuery = select PERM_NAME from SHIRO_ROLE_PERMISSION WHERE ROLE_NAME = ?
    securityManager.realms=$jdbcRealm
    

    注意sql语句,每次只查询一个shiro要求查询的字段,如果写select *就会报错了。

    ini配置文件要求必须是key=value的形式,如果有些人没有设置数据库的密码,就不要写对应的配置。只写”dataSource.password=”等号右面没有值会报错。

    测试代码

    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    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 org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ShiroMySqlTest {
        private static final transient Logger log =
                LoggerFactory.getLogger(ShiroMySqlTest.class);
        public static void main(String[] args) {
            Factory<SecurityManager> factory =
                    new IniSecurityManagerFactory("classpath:shiro-mysql.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
            Subject currentUser = SecurityUtils.getSubject();
            UsernamePasswordToken token =
                    new UsernamePasswordToken("test@shiro.com", "123456");
            token.setRememberMe(true);//是否记住用户
            try {
                currentUser.login(token);
                //当我们获登录用户之后
                log.info("用户 [" + currentUser.getPrincipal() + "] 登陆成功");
                //查看用户是否有角色
                if (currentUser.hasRole("admin")) {
                    log.info("您有admin角色");
                } else {
                    log.info("您没有admin角色");
                }
                if (currentUser.hasRole("test")) {
                    log.info("您有test角色");
                } else {
                    log.info("您没有test角色");
                }
                // 查看用户是否有某个权限
                if (currentUser.isPermitted("perm1")) {
                    log.info("您有perm1权限");
                } else {
                    log.info("您没有perm1权限");
                }
                if (currentUser.isPermitted("guest")) {
                    log.info("您有guest权限");
                } else {
                    log.info("您没有guest权限");
                }
                //登出
                currentUser.logout();
            } catch (UnknownAccountException uae) {
                log.info(token.getPrincipal() + "账户不存在");
            } catch (IncorrectCredentialsException ice) {
                log.info(token.getPrincipal() + "密码不正确");
            } catch (LockedAccountException lae) {
                log.info(token.getPrincipal() + "用户被锁定了 ");
            } catch (AuthenticationException ae) {
                //无法判断是什么错了
                log.info(ae.getMessage());
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Shiro + MySQL动态权限验证

          本文链接:https://www.haomeiwen.com/subject/loedxctx.html