• (补漏)Springboot2.0 集成shiro权限管理


    原文Springboot2.0 集成shiro权限管理

    一、关于停止使用外键。

    原本集成shiro建立用户、角色、权限表的时候使用了外键,系统自动创建其中两个关联表,用@JoinTable。看起来省事,但是实际上删除以及取出数据转成json都很麻烦,折腾的心累,真不如取消外键自己来搞定,比较灵活,业务逻辑掌握好就可以。

    所以,最后3个entity变成了5个。

    entity如下:

    @Entity
    public class User {
        @Id
        @GenericGenerator(name="generator",strategy = "native")
        @GeneratedValue(generator = "generator")
        private Integer userId;
        @Column(nullable = false, unique = true)
        private String userName; //登录用户名,账号
        @Column(nullable = false)
        private String name;//名称(昵称或者真实姓名,根据实际情况定义)
        @Column(nullable = false)
        private String password;
        private String salt;//加密密码的盐
        private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
    //    @ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;
    //    @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
        @Transient
        private List<IUserRole> roleList;// 一个用户具有多个角色
        @Transient
        private List<ISysPermission> permissionList;//用户的权限
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
        private LocalDateTime createTime;//创建时间
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate expiredDate;//过期日期
        private String email;
        private String tel;
    
        public List<IUserRole> getRoleList() {
            return roleList;
        }
    
        public void setRoleList(List<IUserRole> roleList) {
            this.roleList = roleList;
        }
    
        public List<ISysPermission> getPermissionList() {
            return permissionList;
        }
    
        public void setPermissionList(List<ISysPermission> permissionList) {
            this.permissionList = permissionList;
        }
    
        public String getTel() {
            return tel;
        }
    
        public void setTel(String tel) {
            this.tel = tel;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public LocalDateTime getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(LocalDateTime createTime) {
            this.createTime = createTime;
        }
    
        public LocalDate getExpiredDate() {
            return expiredDate;
        }
    
        public void setExpiredDate(LocalDate expiredDate) {
            this.expiredDate = expiredDate;
        }
    
        public Integer getUserId() {
            return userId;
        }
    
        public void setUserId(Integer userId) {
            this.userId = userId;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getSalt() {
            return salt;
        }
    
        public void setSalt(String salt) {
            this.salt = salt;
        }
    
        public byte getState() {
            return state;
        }
    
        public void setState(byte state) {
            this.state = state;
        }
    
        /**
         * 密码盐.
         * @return
         */
        public String getCredentialsSalt(){
            return this.userName+this.salt;
        }
        //重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解
    }
    @Entity
    public class SysRole {
        @Id
        @GenericGenerator(name="generator",strategy = "native")
        @GeneratedValue(generator = "generator")
        private Integer roleId; // 编号
    
        @Column(nullable = false, unique = true)
        @NotBlank(message ="名称不能为空")
        private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
        private String description; // 角色描述,UI界面显示使用
        private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户,
    
    //    @JsonFormat(pattern="yyyy-MM-dd HH:mm",timezone="GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
        private LocalDateTime createTime;//创建时间
    //    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate expiredDate;//过期日期
    
        //角色 -- 权限关系:多对多关系;
    //    @JsonIgnore
    //    @ManyToMany(fetch= FetchType.EAGER)
    //    @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
        @Transient
        private List<ISysRolePermission> permissions;
    
        // 用户 - 角色关系定义;
    //    @JsonIgnore
    //    @ManyToMany
    //    @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")})
    //    private List<User> users;// 一个角色对应多个用户
    
    
        public LocalDateTime getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(LocalDateTime createTime) {
            this.createTime = createTime;
        }
    
        public LocalDate getExpiredDate() {
            return expiredDate;
        }
    
        public void setExpiredDate(LocalDate expiredDate) {
            this.expiredDate = expiredDate;
        }
    
        public Integer getRoleId() {
            return roleId;
        }
    
        public void setRoleId(Integer roleId) {
            this.roleId = roleId;
        }
    
        public String getRole() {
            return role;
        }
    
        public void setRole(String role) {
            this.role = role;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public Boolean getAvailable() {
            return available;
        }
    
        public void setAvailable(Boolean available) {
            this.available = available;
        }
    
        public List<ISysRolePermission> getPermissions() {
            return permissions;
        }
    
        public void setPermissions(List<ISysRolePermission> permissions) {
            this.permissions = permissions;
        }
    
    }
    @Entity
    public class SysPermission {
        @Id
        @GenericGenerator(name="generator",strategy = "native")
        @GeneratedValue(generator = "generator")
        private Integer permissionId;//主键.
        @Column(nullable = false)
        private String permissionName;//名称.
        private String description;//描述
        @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 Integer level;//菜单层级,1(顶级),2,3
        private Boolean available = Boolean.FALSE;
        //角色 -- 权限关系:多对多关系;
    //    @ManyToMany
    //    @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
        @Transient
        private List<SysRole> roles;
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public Integer getLevel() {
            return level;
        }
    
        public void setLevel(Integer level) {
            this.level = level;
        }
    
        public Integer getPermissionId() {
            return permissionId;
        }
    
        public void setPermissionId(Integer permissionId) {
            this.permissionId = permissionId;
        }
    
        public String getPermissionName() {
            return permissionName;
        }
    
        public void setPermissionName(String permissionName) {
            this.permissionName = permissionName;
        }
    
        public String getResourceType() {
            return resourceType;
        }
    
        public void setResourceType(String resourceType) {
            this.resourceType = resourceType;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getPermission() {
            return permission;
        }
    
        public void setPermission(String permission) {
            this.permission = permission;
        }
    
        public Long getParentId() {
            return parentId;
        }
    
        public void setParentId(Long parentId) {
            this.parentId = parentId;
        }
    
        public String getParentIds() {
            return parentIds;
        }
    
        public void setParentIds(String parentIds) {
            this.parentIds = parentIds;
        }
    
        public Boolean getAvailable() {
            return available;
        }
    
        public void setAvailable(Boolean available) {
            this.available = available;
        }
    
        public List<SysRole> getRoles() {
            return roles;
        }
    
        public void setRoles(List<SysRole> roles) {
            this.roles = roles;
        }
    }

    新增的实体:

    //用户和角色关联表

    @Entity
    public class SysUserRole {
        @Id
        @GenericGenerator(name="generator",strategy = "native")
        @GeneratedValue(generator = "generator")
        private Integer id; // 编号
        private Integer userId;
        private Integer roleId;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getUserId() {
            return userId;
        }
    
        public void setUserId(Integer userId) {
            this.userId = userId;
        }
    
        public Integer getRoleId() {
            return roleId;
        }
    
        public void setRoleId(Integer roleId) {
            this.roleId = roleId;
        }
    }

    //角色权限对照表

    @Entity
    public class SysRolePermission {
        @Id
        @GenericGenerator(name="generator",strategy = "native")
        @GeneratedValue(generator = "generator")
        private Integer id; // 编号
        private Integer roleId; //
        private Integer permissionId;//
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getRoleId() {
            return roleId;
        }
    
        public void setRoleId(Integer roleId) {
            this.roleId = roleId;
        }
    
        public Integer getPermissionId() {
            return permissionId;
        }
    
        public void setPermissionId(Integer permissionId) {
            this.permissionId = permissionId;
        }
    }

    建立以上5个实体以后,实体之间的关联就需要自己来实现和掌控,例如删除角色的时候,角色和权限关联表里的对应角色记录就必须同步删除;删除用户的时候,用户和角色关联表的记录就必须同步删除。

    二、DAO层里需要自定义一些SQL,对于SQL比较熟悉的人来说非常简单。

    角色DAO

    public interface RoleRepository extends JpaRepository<SysRole,Integer> {
        Page<SysRole> findAllByRoleContains(String role, Pageable pageable);
        SysRole findSysRoleByRole(String role);
    
        //排除现有角色的情况下,判断新的角色是否存在
        @Query(value="select * from SysRole where role <> ?1 and role = ?2",nativeQuery = true)
        SysRole findSysRoleExists2(String oldRole, String newRole);
    
        //根据roleid列表删除所有的角色
        @Modifying
        @Query(value = "delete from SysRole where roleId in (?1)",nativeQuery = true)
        void deleteAllByRoleIdList(List<Integer> roleIdList);
    
        //根据roleid列出所有权限,包括没有的权限,如果没有权限,则roleid和role两个字段会是null值,可以根据此做业务判断
        @Query(value="select a.permissionId,a.permission,a.permissionName,a.parentId,c.roleId,c.role  from syspermission a 
    " +
                "left join sysrolepermission b on a.permissionId=b.permissionId and a.available=1 and b.roleId=?1
    " +
                "left join sysrole c on c.roleId=b.roleId",
        countQuery = "select count(*)  from syspermission a 
    " +
                "left join sysrolepermission b on a.permissionId=b.permissionId and a.available=1 and b.roleId=?1
    " +
                "left join sysrole c on c.roleId=b.roleId",
        nativeQuery = true)
        List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId);
    
        //根据roleid删除角色权限关联表里所有角色权限
        @Modifying
        @Query(value = "delete from SysRolePermission where roleId=?1",nativeQuery = true)
        void deleteRolePermission(Integer roleId);
    
        //插入角色和权限
        @Modifying
        @Query(value="insert into SysRolePermission(roleId,permissionId) VALUES(?1,?2) ",nativeQuery = true)
        void insertRolePermission(Integer roleId, Integer permissionId);
    }

    用户DAO

    public interface UserRepository extends JpaRepository<User,Integer> {
        User findByUserName(String userName);
        Page<User> findAllByUserNameContains(String userName, Pageable pageable);
    
        //排除现有用户的情况下,判断新用户是否存在
        @Query(value="select * from user where userName<> ?1 and userName=?2",nativeQuery = true)
        User findUserExist2(String oldUserName, String newUserName);
    
        //根据userid列表删除所有用户
        @Modifying
        @Query(value="delete from user where userId in (?1)",nativeQuery = true)
        void deleteAllUserByUserIdList(List<Integer> userIdList);
    
        //根据userid删除用户角色关联表里的记录
        @Modifying
        @Query(value="delete from SysUserRole where userId in (?1)",nativeQuery = true)
        void deleteAllUserRoleByUserIdList(List<Integer> userIdList);
    
        //根据userid删除用户角色关联表里的记录
        @Modifying
        @Query(value="delete from SysUserRole where userId = ?1",nativeQuery = true)
        void deleteAllUserRoleByUserId(Integer userId);
    
        //新增用户和角色关联记录
        @Modifying
        @Query(value="insert into SysUserRole(userId,roleId) VALUES(?1,?2)",nativeQuery = true)
        void insertUserRole(Integer userId, Integer roleId);
    
        //根据用户名获取用户所具备的角色列表
        @Query(value="select a.userId,a.userName,c.roleId,c.role,c.description from user a
    " +
                "inner join sysuserrole b on a.userId = b.userId 
    " +
                "inner join sysrole c on b.roleId=c.roleId and c.available=1
    " +
                "where a.userName=?1",
        countQuery = "select count(*) from user a
    " +
                "inner join sysuserrole b on a.userId = b.userId 
    " +
                "inner join sysrole c on b.roleId=c.roleId and c.available=1
    " +
                "where a.userName=?1",
        nativeQuery = true)
        List<IUserRole> findUserRoleByUserName(String userName);
    
        //根据用户id,列出所有角色,包括该用户不具备的角色,该用户不具备角色的时候,userid和username为null,可以做业务判断
        @Query(value="select a.roleId,a.role,a.description,c.userId,c.userName from SysRole a
    " +
                "left join SysUserRole b on a.roleId=b.roleId and a.available=1 and b.userId=?1
    " +
                "left join user c on c.userId=b.userId;",
        countQuery = "select count(*) from SysRole a
    " +
                "left join SysUserRole b on a.roleId=b.roleId and a.available=1 and b.userId=?1
    " +
                "left join user c on c.userId=b.userId;",
        nativeQuery = true)
        List<IUserRole> findAllUserRoleByUserId(Integer userId);
    
        //根据用户名,获取用户具备的权限。
        @Query(value="select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a 
    " +
                "inner join sysuserrole b on a.userId = b.userId 
    " +
                "inner join sysrolepermission c on b.roleId = c.roleId
    " +
                "inner join syspermission d on c.permissionId=d.permissionId
    " +
                "where a.userName=?1",
                countQuery = "select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a 
    " +
                        "inner join sysuserrole b on a.userId = b.userId 
    " +
                        "inner join sysrolepermission c on b.roleId = c.roleId
    " +
                        "inner join syspermission d on c.permissionId=d.permissionId
    " +
                        "where a.userName=?1",
                nativeQuery = true)
        List<ISysPermission> findUserRolePermissionByUserName(String userName);
    
    }

    JPA中自定义SQL返回结果需要自定义结果集接收,实际上最方便的是定义结果集接口,JPA自动会实现该接口,填充数据。

    结果集接口:

    //用于UserRepository自定义返回实体 用户与角色对应表
    public
    interface IUserRole { Integer getUserId(); String getUserName(); Integer getRoleId(); String getRole(); String getDescription(); }
    //用于UserRepository自定义返回实体用户与权限对应表
    public
    interface ISysPermission { Integer getUserId(); String getUserName(); Integer getPermissionId(); String getPermission(); String getPermissionName(); }
    //角色权限对照表,列出全部权限,没有权限的roleroleIdnull
    public
    interface ISysRolePermission { Integer getRoleId(); String getRole(); Integer getPermissionId(); String getPermission(); String getPermissionName(); Integer getParentId(); }

    三、service层和impl层实际上就没多少变化了。

    public interface UserService {
        User findByUserName(String userName);
    
        Optional<User> findUserById(Integer userId);
    
        User save(User user);
    
        boolean checkUserExists(String userName);
        boolean checkUserExists2(String oldUserName, String newUserName);
    
        List<IUserRole> findUserRoleByUserName(String userName);
    
        List<IUserRole> findAllUserRoleByUserId(Integer userId);
    
        List<ISysPermission> findUserRolePermissionByUserName(String userName);
    
        Page<User> findAllByUserNameContains(String userName, Pageable pageable);
    
        void deleteAllUserByUserIdList(List<Integer> userIdList);
    
        void deleteAllUserRoleByUserIdList(List<Integer> userIdList);
    
        void deleteAllUserRoleByUserId(Integer userId);
    
        void grantUserRole(Integer userId, List<Integer> roleIdList);
        
    }
    public interface RoleService {
        Page<SysRole> findAll(Pageable pageable);
    
        Page<SysRole> findAllByRoleContains(String role, Pageable pageable);
    
        Optional<SysRole> findById(Integer roleId);
    
        SysRole save(SysRole sysRole);
    
        boolean checkRoleExists(String role);
    
        boolean checkRoleExists(String oldRole, String newRole);
    
        boolean deleteAllByRoleIdIn(List<Integer> roleIdList);
    
        List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId);
    
        void grantAuthorization(Integer roleId, List<Integer> permissionList);
    
        void clearAuthorization(Integer roleId);
    }

    //这个登录相关的service

    public interface LoginService {
        LoginResult login(String userName, String password);
        String getCurrentUserName();
        void logout();
    }

    impl层,因为自定义的SQL要用事务,一般放在impl里实现,不建议放在controller里。

    比如授权,采用的方式是删除原先的所有授权,把新的权限重新插入,两步操作用事务。

    @Service
    public class UserServiceImpl implements UserService {
        @Resource
        private UserRepository userRepository;
        @Override
        public User findByUserName(String userName) {
            return userRepository.findByUserName(userName);
        }
    
        @Override
        public List<IUserRole> findUserRoleByUserName(String userName) {
            return userRepository.findUserRoleByUserName(userName);
    
        }
    
        @Override
        public List<IUserRole> findAllUserRoleByUserId(Integer userId) {
            return userRepository.findAllUserRoleByUserId(userId);
        }
    
        @Override
        public List<ISysPermission> findUserRolePermissionByUserName(String userName) {
            return userRepository.findUserRolePermissionByUserName(userName);
        }
    
        @Override
        public Optional<User> findUserById(Integer userId) {
            return userRepository.findById(userId);
        }
    
        @Override
        public User save(User user) {
            return userRepository.save(user);
        }
    
        @Override
        public boolean checkUserExists(String userName) {
            User user =  userRepository.findByUserName(userName);
            if(user!=null)
                return true;
            else
                return false;
        }
    
        @Override
        public boolean checkUserExists2(String oldUserName, String newUserName) {
            User user = userRepository.findUserExist2(oldUserName,newUserName);
    
            if(user!=null)
                return true;
            else
                return false;
        }
    
        @Override
        public Page<User> findAllByUserNameContains(String userName, Pageable pageable) {
            return userRepository.findAllByUserNameContains(userName,pageable);
        }
    
        @Transactional
        @Override
        public void deleteAllUserByUserIdList(List<Integer> userIdList) {
            userRepository.deleteAllUserRoleByUserIdList(userIdList);
            userRepository.deleteAllUserByUserIdList(userIdList);
        }
    
        @Transactional
        @Override
        public void deleteAllUserRoleByUserIdList(List<Integer> userIdList) {
            userRepository.deleteAllUserRoleByUserIdList(userIdList);
        }
    
        @Transactional
        @Override
        public void deleteAllUserRoleByUserId(Integer userId) {
            userRepository.deleteAllUserRoleByUserId(userId);
        }
    
        @Transactional
        @Override
        public void grantUserRole(Integer userId, List<Integer> roleIdList) {
            userRepository.deleteAllUserRoleByUserId(userId);
            for(Integer roleId:roleIdList)
            {
                userRepository.insertUserRole(userId,roleId);
            }
        }
    
    }
    @Service
    public class RoleServiceImpl implements RoleService {
        @Resource
        RoleRepository roleRepository;
    
        @Override
        public Page<SysRole> findAll(Pageable pageable) {
            return roleRepository.findAll(pageable);
        }
    
        @Override
        public Optional<SysRole> findById(Integer roleId) {
            return roleRepository.findById(roleId);
        }
    
        @Override
        public Page<SysRole> findAllByRoleContains(String role, Pageable pageable) {
            return roleRepository.findAllByRoleContains(role,pageable);
        }
    
        @Override
        public SysRole save(SysRole sysRole) {
            return roleRepository.save(sysRole);
        }
    
        @Override
        public boolean checkRoleExists(String role) {
            SysRole sysRole = roleRepository.findSysRoleByRole(role);
            if(sysRole!=null)
                return true;
            else
                return false;
        }
    
        @Override
        public boolean checkRoleExists(String oldRole, String newRole) {
            SysRole sysRole = roleRepository.findSysRoleExists2(oldRole,newRole);
            if(sysRole!=null)
                return true;
            else
                return false;
        }
    
        //删除角色权限和角色
        @Transactional
        @Override
        public boolean deleteAllByRoleIdIn(List<Integer> roleIdList) {
            try {
                for(Integer roleId:roleIdList)
                {
                    roleRepository.deleteRolePermission(roleId);
                }
                roleRepository.deleteAllByRoleIdList(roleIdList);
                return true;
            }catch (Exception e)
            {
                e.printStackTrace();
                return false;
            }
        }
    
        @Override
        public List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId) {
            return roleRepository.findSysRolePermissionByRoleId(roleId);
        }
    
        //授权前先清除原角色权限,然后重新新增授权
        @Transactional
        @Override
        public void grantAuthorization(Integer roleId, List<Integer> permissionList) {
            roleRepository.deleteRolePermission(roleId);
            for(Integer permissionId:permissionList)
            {
                roleRepository.insertRolePermission(roleId,permissionId);
            }
        }
    
        @Transactional
        @Override
        public void clearAuthorization(Integer roleId) {
            roleRepository.deleteRolePermission(roleId);
        }
    }
    LoginServiceImpl没多少变化。

    四、config,新增Kaptcha做图片验证码
    <dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
    </dependency>



    @Component
    public class KaptchaConfig {
    
        @Bean
        public DefaultKaptcha getDefaultKaptcha() {
            DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
            Properties properties = new Properties();
            // 图片边框
            properties.setProperty("kaptcha.border", "yes");
            // 边框颜色
            properties.setProperty("kaptcha.border.color", "105,179,90");
            // 字体颜色
            properties.setProperty("kaptcha.textproducer.font.color", "blue");
            // 图片宽
            properties.setProperty("kaptcha.image.width", "150");
            // 图片高
            properties.setProperty("kaptcha.image.height", "40");
            // 字体大小
            properties.setProperty("kaptcha.textproducer.font.size", "30");
            // session key
            properties.setProperty("kaptcha.session.key", "code");
            // 验证码长度
            properties.setProperty("kaptcha.textproducer.char.length", "4");
            // 字体
    //        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
    
            properties.put("kaptcha.obscurificator.impl","com.google.code.kaptcha.impl.ShadowGimpy");
    
            properties.put("kaptcha.textproducer.char.string","acdefhkmnprtwxy2345678");
    
    
            Config config = new Config(properties);
            defaultKaptcha.setConfig(config);
    
            return defaultKaptcha;
        }
    }

    这里有个坑,需要为验证码链接配置匿名访问,就是在ShiroConfig里,否则图片出不来。

    filterChainDefinitionMap.put("/getVerifyCode", "anon"); //给验证码使用

    五、controller

    HomeController用于登录验证

    @Controller
    public class HomeController {
        @Resource
        private LoginService loginService;
    
        @Resource
        DefaultKaptcha defaultKaptcha;
    
        private long verifyTTL = 60;//验证码过期时间60秒
    
        @RequestMapping({"/", "/index"})
        public String index() {
            return "/index";
        }
    
    
        /**
         * 2、生成验证码
         *
         * @param request
         * @param response
         * @throws Exception
         */
        @RequestMapping("/getVerifyCode")
        public void defaultKaptcha(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
            byte[] bytesCaptchaImg = null;
            ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
            try {
                // 生产验证码字符串并保存到session中
                String createText = defaultKaptcha.createText();
                request.getSession().setAttribute("verifyCode", createText);
                request.getSession().setAttribute("verifyCodeTTL", System.currentTimeMillis());
                // 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
                BufferedImage bufferedImage = defaultKaptcha.createImage(createText);
                ImageIO.write(bufferedImage, "jpg", jpegOutputStream);
            } catch (Exception e) {
                e.printStackTrace();
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
    
            // 定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
            bytesCaptchaImg = jpegOutputStream.toByteArray();
            response.setHeader("Cache-Control", "no-store");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
            ServletOutputStream responseOutputStream = response.getOutputStream();
            responseOutputStream.write(bytesCaptchaImg);
            responseOutputStream.flush();
            responseOutputStream.close();
        }
    
    
        @RequestMapping("/403")
        public String unauthorizedRole() {
            System.out.println("------没有权限-------");
            return "/user/403";
        }
    
        @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String toLogin(Map<String, Object> map, HttpServletRequest request) {
            loginService.logout();
            return "/user/login";
        }
    
        @RequestMapping(value = "/login", method = RequestMethod.POST)
        public String login(Map<String, Object> map, HttpServletRequest request) throws Exception {
            System.out.println("login()");
            String userName = request.getParameter("userName");
            String password = request.getParameter("password");
    
            String verifyCode = request.getParameter("verifyCode");
            String rightCode = (String) request.getSession().getAttribute("verifyCode");
            Long verifyCodeTTL = (Long) request.getSession().getAttribute("verifyCodeTTL");
            Long currentMillis = System.currentTimeMillis();
            if (rightCode == null || verifyCodeTTL == null) {
                map.put("msg", "请刷新图片,输入验证码!");
                map.put("userName", userName);
                map.put("password", password);
                return "/user/login";
            }
            Long expiredTime = (currentMillis - verifyCodeTTL) / 1000;
            if (expiredTime > this.verifyTTL) {
                map.put("msg", "验证码过期,请刷新图片重新输入!");
                map.put("userName", userName);
                map.put("password", password);
                return "/user/login";
            }
    
            if (!verifyCode.equalsIgnoreCase(rightCode)) {
                map.put("msg", "验证码错误,请刷新图片重新输入!");
                map.put("userName", userName);
                map.put("password", password);
                return "/user/login";
            }
    
            LoginResult loginResult = loginService.login(userName, password);
            if (loginResult.isLogin()) {
                map.put("userName", userName);
                return "/index";
            } else {
                map.put("msg", loginResult.getResult());
                map.put("userName", userName);
                return "/user/login";
            }
        }
    
        @RequestMapping("/logout")
        public String logOut(HttpSession session) {
            loginService.logout();
            return "/user/login";
        }
    }

    密码生成,前文没说,实际是比较简单的:

    public class EncryptUtils {
    
        public static String encrypt(String str,String salt, String algorithmName, int hashIterations)
        {
            return new SimpleHash(algorithmName,str, ByteSource.Util.bytes(salt),hashIterations).toString();
        }
    
    }

    UserController

    @Controller
    @RequestMapping("/user")
    public class UserController {
        private String algorithmName = "md5";
        private int hashIterations = 2;
        private String salt = "8d78869f470951332959580424d4bf4f";
    
        @Resource
        UserService userService;
        @Resource
        LoginService loginService;
        /**
         * 用户查询.
         * @return
         */
        @RequestMapping("/ulist")
        public String userList(){
            return "/user/userList";
        }
    
        @RequestMapping(value="/getUserList")
        @RequiresPermissions("user:view")//权限管理;
        @ResponseBody
        public Object getUserList(HttpServletRequest request, HttpServletResponse response)
        {
            int pageSize = 10;
            try {
                pageSize =  Integer.parseInt(request.getParameter("pageSize"));
            }catch (Exception e)
            {
                e.printStackTrace();
            }
    
            int pageNumber=0 ;
            try {
                pageNumber =  Integer.parseInt(request.getParameter("pageNumber"))-1;
            }catch (Exception e)
            {
                e.printStackTrace();
            }
    
            Map<String, Object> map = new HashMap<>();
    
            String strUserName=request.getParameter("searchText")==null ? "": request.getParameter("searchText");
    
            String sortName=request.getParameter("sortName")==null ? "roleId": request.getParameter("sortName");
            String sortOrder=request.getParameter("sortOrder")==null ? "asc": request.getParameter("sortOrder");
    
            Sort sortLocal = new Sort(sortOrder.equalsIgnoreCase("asc") ? Sort.Direction.ASC: Sort.Direction.DESC,sortName);
            Pageable pageable = PageRequest.of(pageNumber,pageSize,sortLocal);
            Page<User> userPage = userService.findAllByUserNameContains(strUserName,pageable);
            map.put("total",userPage.getTotalElements());
            map.put("rows",userPage.getContent());
         //如果使用外键,这里会出问题,需要在实体里添加注解忽略实体之间的相互引用。
            return map;
    
    
        }
    
        @RequestMapping(value = "/add",method = RequestMethod.GET)
        @RequiresPermissions("user:add")//权限管理;
        public String toUserAdd(User user){
            return "/user/userAdd";
        }
    
    
        /**
         * 用户添加;
         * @return
         */
        @RequestMapping(value = "/add",method = RequestMethod.POST)
        @RequiresPermissions("user:add")//权限管理;
        @ResponseBody
        public String save(@Valid User user, BindingResult bindingResult, String password2){
            if(bindingResult.hasErrors())
            {
                return "0";
            }
    
            user.setSalt(this.salt);
            if(user.getUserId()==null) {
                user.setCreateTime(LocalDateTime.now());
                String encryptPwd = EncryptUtils.encrypt(user.getPassword(),user.getCredentialsSalt(),this.algorithmName,this.hashIterations);
                user.setPassword(encryptPwd);
            }
            else {
                if(!user.getPassword().equals(password2))
                {
                    String encryptPwd = EncryptUtils.encrypt(user.getPassword(),user.getCredentialsSalt(),this.algorithmName,this.hashIterations);
                    user.setPassword(encryptPwd);
                }
            }
            try {
                userService.save(user);
                return "/user/ulist";
            }catch (Exception e)
            {
                e.printStackTrace();
                return "0";
            }
        }
    
        @RequestMapping("/checkUserExists")
        @ResponseBody
        public Object checkRoleExists(@RequestParam String newUserName, @RequestParam(required = false) Integer userId, @RequestParam(required = false) String oldUserName)
        {
            Map<String,Boolean> map = new HashMap<>();
            if(userId==null)
            {
                boolean result = !userService.checkUserExists(newUserName);
                map.put("valid",result);
            }
            else
            {
                boolean result = !userService.checkUserExists2(oldUserName,newUserName);
                map.put("valid",result);
            }
            return map;
        }
    
    
        @RequestMapping(value = "/edit/{id}")
        @RequiresPermissions("user:edit")
        public String edit(@PathVariable("id")Integer id, Map<String,Object> map)
        {
            User user = userService.findUserById(id).orElse(new User());
            map.put("user",user);
            return "/user/userAdd";
        }
    
        /**
         * 用户删除;
         * @return
         */
        @RequestMapping("/delete")
        @ResponseBody
        @RequiresPermissions("user:del")//权限管理;
        public Object userDel(@RequestParam String userIdList){
            if(userIdList==null || userIdList.isEmpty())
            {
                return "0";
            }
            String[] sList = userIdList.split(",");
            List<Integer> idList = new ArrayList<>();
            for (String s:sList )
            {
                if(s.equalsIgnoreCase("1"))
                    return "0";
                idList.add(Integer.parseInt(s));
    
            }
            Map<String,String> map = new HashMap<>();
            try {
                userService.deleteAllUserByUserIdList(idList);
                map.put("success","true");
                map.put("url","/user/ulist");
            }catch (Exception e)
            {
                e.printStackTrace();
                map.put("error","true");
            }
    
            return map;
        }
    
        @RequestMapping(value="/toListUserRole/{userId}")
        @RequiresPermissions("user:roleGrant")
        public String listUserRole(@PathVariable("userId")Integer userId, Map<String, Object> map)
        {
            User user = userService.findUserById(userId).orElse(new User());
            map.put("user",user);
            return "/user/userRole";
        }
    
    
        @RequestMapping(value = "/toGetUserRole/{userId}")
        @RequiresPermissions("user:roleGrant")
        @ResponseBody
        public Object getUserRole(@PathVariable("userId")Integer userId)
        {
            if(userId==null)
                return null;
    
            List<IUserRole> list = userService.findAllUserRoleByUserId(userId);
    
            return list;
        }
    
    
    
    
        @RequestMapping(value="/toGrantUserRole")
        @ResponseBody
        @RequiresPermissions("user:roleGrant")
        public Object grantUserRole(Integer userId, String roleIdList)
        {
            if(userId==1) return 0;
            Map<String,String> map = new HashMap<>();
            if(roleIdList==null || roleIdList.isEmpty())
            {
                try {
                    userService.deleteAllUserRoleByUserId(userId);
                    map.put("success","true");
                    map.put("url","/user/ulist");
                    return map;
                }catch (Exception e)
                {
                    e.printStackTrace();
                    map.put("sucess","false");
                    map.put("url","/user/ulist");
                    return map;
                }
            }
            String[] sList = roleIdList.split(",");
            List<Integer> idList = new ArrayList<>();
            for (String s:sList )
            {
                idList.add(Integer.parseInt(s));
            }
    
            try {
                userService.grantUserRole(userId,idList);
                map.put("sucess","true");
                map.put("url","/user/ulist");
    
                return map;
            }catch (Exception e)
            {
                e.printStackTrace();
                map.put("sucess","false");
                map.put("url","/user/ulist");
                return map;
            }
        }
    
        @RequestMapping(value="/toChangePassword")
        public String toChangePassword(String password,String newPassword,String newPassword2)
        {
            return "/user/changePwd";
        }
    
        @RequestMapping(value="/changePassword",method = RequestMethod.POST)
        @ResponseBody
        public Object changePassword(HttpServletRequest request)
        {
            Map<String,String> map = new HashMap<>();
            String password = request.getParameter("password");
            String newPassword = request.getParameter("newPassword");
            String newPassword2 = request.getParameter("newPassword2");
    
            if(newPassword==null)
            {
                map.put("success","false");
                map.put("result","密码不能为空");
                return map;
            }
    
            if(!newPassword.equals(newPassword2))
            {
                map.put("success","false");
                map.put("result","两次密码输入不一样");
                return map;
            }
    
            if(newPassword.length()<6)
            {
                map.put("success","false");
                map.put("result","密码长度必须大于6位");
                return map;
            }
    
    
            String userName = loginService.getCurrentUserName();
            if(userName==null || userName.isEmpty())
            {
                map.put("success","false");
                map.put("result","用户错误");
                return map;
            }
            User user = userService.findByUserName(userName);
            if(user==null)
            {
                map.put("success","false");
                map.put("result","用户错误");
                return map;
            }
    
            String encryptPwd = EncryptUtils.encrypt(password,user.getCredentialsSalt(),this.algorithmName,this.hashIterations);
            if(!encryptPwd.equals(user.getPassword()))
            {
                map.put("success","false");
                map.put("result","当前用户密码不正确");
                return map;
            }
    
            String encryptNewPwd = EncryptUtils.encrypt(newPassword,user.getCredentialsSalt(),this.algorithmName,this.hashIterations);
            user.setPassword(encryptNewPwd);
            userService.save(user);
            map.put("success","true");
            map.put("result","密码修改成功,请重新登录");
            map.put("url","/logout");
            return map;
        }
    
        @RequestMapping(value="/toCheckPwd")
        @ResponseBody
        public Object checkCurrentPwd(@RequestParam String password)
        {
            Map<String,Boolean> map = new HashMap<>();
            if(password==null)
            {
                map.put("valid",false);
                return map;
            }
    
            String userName = loginService.getCurrentUserName();
            if(userName==null || userName.isEmpty())
            {
                map.put("valid",false);
                return map;
            }
            User user = userService.findByUserName(userName);
            if(user==null)
            {
                map.put("valid",false);
                return map;
            }
    
            String encryptPwd = EncryptUtils.encrypt(password,user.getCredentialsSalt(),this.algorithmName,this.hashIterations);
            if(!encryptPwd.equals(user.getPassword()))
            {
                map.put("valid",false);
                return map;
            }
    
            map.put("valid",true);
            return map;
        }
    
    
    }

    RoleController

    @Controller
    @RequestMapping("/user")
    public class RoleController {
        @Resource
        RoleService roleService;
        
        @RequestMapping(value="/role")
        @ResponseBody
        @RequiresPermissions("role:view")
        public Object getRole(HttpServletRequest request, HttpServletResponse response)
        {
    
            int pageSize = 10;
            try {
                pageSize =  Integer.parseInt(request.getParameter("pageSize"));
            }catch (Exception e)
            {
                e.printStackTrace();
            }
    
            int pageNumber=0 ;
            try {
                pageNumber =  Integer.parseInt(request.getParameter("pageNumber"))-1;
            }catch (Exception e)
            {
                e.printStackTrace();
            }
    
            Map<String, Object> map = new HashMap<>();
    
            String strRole=request.getParameter("searchText")==null ? "": request.getParameter("searchText");
    
            String sortName=request.getParameter("sortName")==null ? "roleId": request.getParameter("sortName");
            String sortOrder=request.getParameter("sortOrder")==null ? "asc": request.getParameter("sortOrder");
    
            Sort sortLocal = new Sort(sortOrder.equalsIgnoreCase("asc") ? Sort.Direction.ASC: Sort.Direction.DESC,sortName);
            Pageable pageable = PageRequest.of(pageNumber,pageSize,sortLocal);
    
            Page<SysRole> sysRolePage = roleService.findAllByRoleContains(strRole, pageable);
            map.put("total",sysRolePage.getTotalElements());
            map.put("rows",sysRolePage.getContent());
    
            return map;
    
        }
    
        @RequestMapping("/rlist")
    //    @RequiresPermissions("user:view")
        public String list()
        {
            return "/user/roleList";
        }
    
    
        @RequestMapping(value="/roleAdd", method= RequestMethod.GET)
        @RequiresPermissions("role:add")
        public String toAdd(SysRole sysRole) {
            return "/user/roleAdd";
        }
    
        @RequestMapping(value="/roleAdd",method = RequestMethod.POST)
        @ResponseBody
        @RequiresPermissions("role:add")
        public String save(@Valid SysRole sysRole, BindingResult bindingResult)
        {
            if(bindingResult.hasErrors())
            {
                return "0";
            }
            if(sysRole.getCreateTime()==null)
                sysRole.setCreateTime(LocalDateTime.now());
            try {
                roleService.save(sysRole);
                return  "/user/rlist";
            }catch (Exception e)
            {
                e.printStackTrace();
                return "0";
            }
        }
    
    
        @RequestMapping("/checkRoleExists")
        @ResponseBody
        public Object checkRoleExists(@RequestParam String newRole, @RequestParam(required = false) Integer roleId, @RequestParam(required = false) String oldRole)
        {
            Map<String,Boolean> map = new HashMap<>();
            if(roleId==null)
            {
                boolean result = !roleService.checkRoleExists(newRole);
                map.put("valid",result);
            }
            else
            {
                boolean result = !roleService.checkRoleExists(oldRole,newRole);
                map.put("valid",result);
            }
            return map;
        }
    
    
        @RequestMapping(value = "/roleEdit/{id}")
        @RequiresPermissions("role:edit")
        public String edit(@PathVariable("id")Integer id, Map<String,Object> map)
        {
            SysRole sysRole = roleService.findById(id).orElse(new SysRole());
            map.put("sysRole",sysRole);
            return "/user/roleAdd";
        }
        
        @RequestMapping(value = "/roleDelete")
        @ResponseBody
        @RequiresPermissions("role:del")
        public Object delete(@RequestParam String roleIdList)
        {
            if(roleIdList==null || roleIdList.isEmpty())
            {
                return "0";
            }
            String[] sList = roleIdList.split(",");
            List<Integer> idList = new ArrayList<>();
            for (String s:sList )
            {
                if(s.equalsIgnoreCase("1"))
                    return "0";
                idList.add(Integer.parseInt(s));
    
            }
            boolean result = roleService.deleteAllByRoleIdIn(idList);
            Map<String,String> map = new HashMap<>();
            if(result)
            {
                map.put("success","true");
                map.put("url","/user/rlist");
            }
            else
            {
                map.put("error","true");
            }
    
            return map;
        }
    
        @RequestMapping(value = "/plist/{roleId}")
        @RequiresPermissions("role:authorize")
        public String permissionList(@PathVariable("roleId")Integer roleId, Map<String, Object> map)
        {
            SysRole sysRole = roleService.findById(roleId).orElse(new SysRole());
            map.put("sysRole",sysRole);
            return "/user/sysPermission";
        }
    
        @RequestMapping("/getPermission/{roleId}")
        @ResponseBody
        @RequiresPermissions("role:authorize")
        public Object getRolePermission(@PathVariable("roleId")Integer roleId)
        {
            if(roleId==null)
                return null;
    
            List<ISysRolePermission> list = roleService.findSysRolePermissionByRoleId(roleId);
            return list;
        }
    
        //根据roleid授权
        @RequestMapping(value = "/toAuthorize")
        @ResponseBody
        @RequiresPermissions("role:authorize")
        public Object toAuthorize(Integer roleId,String permissionIdList)
        {
            if(roleId==1) return 0;
            Map<String,String> map = new HashMap<>();
            if(permissionIdList==null || permissionIdList.isEmpty())
            {
                try {
                    roleService.clearAuthorization(roleId);
                    map.put("success","true");
                    map.put("url","/user/rlist");
                    return map;
                }catch (Exception e)
                {
                    e.printStackTrace();
                    map.put("sucess","false");
                    map.put("url","/user/rlist");
                    return map;
                }
            }
            String[] sList = permissionIdList.split(",");
            List<Integer> idList = new ArrayList<>();
            for (String s:sList )
            {
                idList.add(Integer.parseInt(s));
            }
    
            try {
                roleService.grantAuthorization(roleId,idList);
                map.put("sucess","true");
                map.put("url","/user/rlist");
    
                return map;
            }catch (Exception e)
            {
                e.printStackTrace();
                map.put("sucess","false");
                map.put("url","/user/rlist");
                return map;
            }
    
        }
    }

    代码可以参考这个地址:https://github.com/asker124143222/bus

     
  • 相关阅读:
    如何找按钮数组在布局中的横竖坐标位置?
    java中使用rmi进行远程方法调用
    测试视频集,各种测试用的视频文件
    如何彻底禁用VS 2008的智能感知功能
    JavaScript秘密花园 Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion
    JavaScript秘密花园 scope, namespace, constructor, equality and comparisons
    造成内存位置访问无效的一个原因
    depends在VS2008消失了
    12月10日晚的月全食照片
    JavaScript秘密花园 Array, Array Constructor, for in loop, typeof, instanceOf
  • 原文地址:https://www.cnblogs.com/asker009/p/9745470.html
Copyright © 2020-2023  润新知