美文网首页SpringBoot
springboot集成shiro的实体

springboot集成shiro的实体

作者: 意识流丶 | 来源:发表于2017-03-11 15:57 被阅读1087次

    3.身份认证

    在认证、授权内部实现机制中都有提到,最终处理都将交给Real进行处理。因为在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO.

    认证实现

    Shiro的认证过程最终会交由Realm执行,这时会调用RealmgetAuthenticationInfo(token)方法。
    该方法主要执行以下操作:
    1、检查提交的进行认证的令牌信息
    2、根据令牌信息从数据源(通常为数据库)中获取用户信息
    3、对用户信息进行匹配验证。
    4、验证通过将返回一个封装了用户信息的AuthenticationInfo实例。
    5、验证失败则抛出AuthenticationException异常信息。
    而在我们的应用程序中要做的就是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doGetAuthenticationInfo (),重写获取用户信息的方法。

    既然需要进行身份权限控制,那么少不了创建用户实体类,权限实体类。

    在权限管理系统中,有这么几个角色很重要,这个要是不清楚的话,那么就很难理解,我们为什么这么编码了。
    第一是用户表:在用户表中保存了用户的基本信息,账号、密码、姓名,性别等;
    第二是:权限表(资源+控制权限):这个表中主要是保存了用户的URL地址,权限信息;
    第三就是角色表:在这个表重要保存了系统存在的角色;
    第四就是关联表:用户-角色管理表(用户在系统中都有什么角色,比如admin,vip等),
    第五就是角色-权限关联表(每个角色都有什么权限可以进行操作)。依据这个理论,我们进行来进行编码,很明显的我们第一步就是要进行实体类的创建。在这里我们使用Mysql和JPA进行操作数据库。

    引入mysql和JPA的依赖。JPA版本(Mar 03, 2017),mysql版本默认,可以自己选择版本

    <!-- Spirng data JPA依赖; -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>1.5.2.RELEASE</version>
    </dependency>
    <!-- mysql驱动; -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    

    application.yml配置mysql数据库和JPA

    spring:
        datasource:
          url: jdbc:mysql://localhost:3306/数据库名称
          username: mysql的登录帐号
          password: mysql的登录密码
          driver-class-name: com.mysql.jdbc.Driver
        jpa:
          database: mysql
          show-sql: true
          hibernate:
            ddl-auto: update
            naming:
              strategy: org.hibernate.cfg.DefaultComponentSafeNamingStrategy
          properties:
             hibernate:
                dialect: org.hibernate.dialect.MySQL5Dialect
    

    JPA强大之处在于可以自动建表,只要在实体类中用好注解
    UserInfoSysRoleSysPermission至于之前的关联表我们使用JPA进行自动生成。

    UserInfo用户信息实体类
    @Entity声明为实体类
    @Id``@GeneratedValue说Id是个自增主键,映射到你这个类中的Integer uid
    @Column(unique =true)是指username这个字段的值在这张表里不能重复,所有记录值都要唯一,就像主键那样
    @ManyToMany(fetch=FetchType.EAGER)不写默认为LAZY
    如果是EAGER,那么表示取出这条数据时,它关联的数据也同时取出放入内存中.
    如果是LAZY,那么取出这条数据时,它关联的数据并不取出来
    表关联@JoinTable name属性为连接两个表的表名称。若不指定,则使用默认的表名称,格式:"表名1" + "_" + "表名2"(JPA会为我们新建这个表)
    joinColumn属性表示,在保存关系的表中,所保存关联关系的外键的字段,并配合@JoinColumn标记使用;
    inverseJoinColumn属性与joinColumn类似,它保存的是保存关系的另外一个外键字段;

    @Entity
    public class UserInfo implements Serializable{
        @Id@GeneratedValue
        private Integer uid;
        @Column(unique =true)
        private String username;//帐号
        private String name;//名称(昵称或者真实姓名,不同系统不同定义)
        private String password; //密码;
        private String salt;//加密密码的盐
        private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
        @ManyToMany(fetch=FetchType.EAGER)//立即从数据库中进行加载数据;
        @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
        private List<SysRole> roleList;// 一个用户具有多个角色
        set和get方法....
        /**
         * 密码盐.
         * @return
         */
        public String getCredentialsSalt(){
            return this.username+this.salt;
        }
    //重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解
    }
    

    SysRole系统角色实体类

    @Entity
    public class SysRole {
        @Id@GeneratedValue
        private Integer id; // 编号
        private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
        private String description; // 角色描述,UI界面显示使用
        private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户
    
        //角色 -- 权限关系:多对多关系;
        @ManyToMany(fetch=FetchType.EAGER)
        @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
        private List<SysPermission> permissions;
    
        // 用户 - 角色关系定义;
        @ManyToMany
        @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})
        private List<UserInfo> userInfos;// 一个角色对应多个用户
        set和get方法....
    }
    

    SysPermission权限实体类
    @Column(columnDefinition="enum('menu','button')")``columnDefinition属性表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。
    例如
    columnDefinition属性的特殊使用:
    编程语言中字符串一般都用String表示,但是数据库中varcahr数值类型有长度限制,一旦需要大文本,则需要text数值类型
    但是String类型默认映射的数值类型是varcharcolumnDefinition可以进行额外指定
    @Column(name = "Remark",columnDefinition="text") private String remark;

    这里枚举类型enum,resourceType只能是menu或者button,其他都不行
     @Column(columnDefinition="enum('menu','button')")
        private String resourceType;
    

    具体的SysPermission实体类

    @Entity
    public class SysPermission implements Serializable{
        @Id@GeneratedValue
        private Integer id;//主键.
        private String name;//名称.
    
        @Column(columnDefinition="enum('menu','button')")
        private String resourceType;//资源类型,[menu|button]
        private String url;//资源路径.
        private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
        private Long parentId; //父编号
        private String parentIds; //父编号列表
        private Boolean available = Boolean.FALSE;
    
        @ManyToMany
        @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
        private List<SysRole> roles;
        set和get方法....
    }
    

    到这里实体类就编码完毕了,在这里我们看到的是3个实体类:UserInfo,SysRole,SysPermission
    对应的是数据库的五张表:
    UserInfo
    SysUserRole
    SysRole
    SysRolePermission
    SysPermission
    (只需要跑一下程序就会开始创建表)

    创建完表之后要输入下数据

    INSERT INTO `sys_permission` VALUES ('1', '�', '用户管理', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userList');
    INSERT INTO `sys_permission` VALUES ('2', '�', '用户添加', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd');
    INSERT INTO `sys_permission` VALUES ('3', '�', '用户删除', '1', '0/1', 'userInfo:del', 'button', 'userInfo/userDel');
    INSERT INTO `sys_role` VALUES ('1', '�', '管理员', 'admin');
    INSERT INTO `sys_role` VALUES ('2', '�', 'VIP会员', 'vip');
    INSERT INTO `sys_role_permission` VALUES ('1', '1');
    INSERT INTO `sys_role_permission` VALUES ('1', '2');
    INSERT INTO `sys_role_permission` VALUES ('1', '3');
    INSERT INTO `sys_user_role` VALUES ('1', '1');
    INSERT INTO `user_info` VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', '0');
    

    下一篇文章将讲实现身份认证,权限控制

    文章主要参考于作者林祥纤的博客

    http://412887952-qq-com.iteye.com/blog/2299777

    相关文章

      网友评论

        本文标题:springboot集成shiro的实体

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