• Springboot 手动搭建项目 --shiro实现


    项目git网址:https://github.com/David-BIQI/manage.git(项目使用比较新的springboot2.0 还有jdk8 )

    参照的代码规范:https://github.com/xwjie/PLMCodeTemplate.git (这个是一套能够落地的代码规范,跟着风哥学习很多)

    shiro的数据库设计
     
    用户表、角色表、权限表、用户与角色中间表、角色与权限中间表
     
    drop table if exists permission;
    
    drop table if exists role;
    
    drop table if exists role_to_permission;
    
    drop table if exists user_to_role;
    
    /*==============================================================*/
    /* Table: permission                                            */
    /*==============================================================*/
    create table permission
    (
       id                   int not null auto_increment,
       name                 varchar(50) comment '权限名称',
       url                  varchar(100) not null comment '请求路径',
       permission           varchar(150) not null comment '角色编码',
       status               tinyint(1) default 1,
       created              datetime default CURRENT_TIMESTAMP,
       createdby            int,
       updated              datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       updatedby            int default 0,
       remark               varchar(50) default '',
       primary key (id)
    );
    
    alter table permission comment '权限表';
    
    /*==============================================================*/
    /* Table: role                                                  */
    /*==============================================================*/
    create table role
    (
       id                   int not null auto_increment,
       role_name            varchar(100) not null comment '角色名称',
       role_code            varchar(150) not null comment '角色编码',
       status               tinyint(1) default 1,
       created              datetime default CURRENT_TIMESTAMP,
       createdby            int,
       updated              datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       updatedby            int,
       remark               varchar(50) default '',
       primary key (id)
    );
    
    alter table role comment '角色表';
    
    /*==============================================================*/
    /* Table: role_to_permission                                    */
    /*==============================================================*/
    create table role_to_permission
    (
       id                   int not null auto_increment,
       permission_id        varchar(100) not null comment '权限id',
       role_id              varchar(150) not null comment '角色id',
       status               tinyint(1) default 1,
       created              datetime default CURRENT_TIMESTAMP,
       createdby            int,
       updated              datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       updatedby            int,
       primary key (id)
    );
    
    alter table role_to_permission comment '角色与权限表';
    
    /*==============================================================*/
    /* Table: user_to_role                                          */
    /*==============================================================*/
    create table user_to_role
    (
       id                   int not null auto_increment,
       user_id              varchar(100) not null,
       role_id              varchar(150) not null,
       status               tinyint(1) default 1,
       created              datetime default CURRENT_TIMESTAMP,
       createdby            int,
       updated              datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       updatedby            int,
       primary key (id)
    );
    
    alter table user_to_role comment '用户角色表';
    

      

    shiro结合springboot
    @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>();
    		// 配置不会被拦截的链接 顺序判断
    		filterChainDefinitionMap.put("/static/**", "anon");
    		//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
    		filterChainDefinitionMap.put("/logout", "logout");
    		//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
    		//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
    		filterChainDefinitionMap.put("/**", "authc");
    		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
    		shiroFilterFactoryBean.setLoginUrl("/login");
    		// 登录成功后要跳转的链接
    		shiroFilterFactoryBean.setSuccessUrl("/main");
    
    		//未授权界面;
    		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
    		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    		return shiroFilterFactoryBean;
    	}
    
    	/**
    	 * 凭证匹配器
    	 * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
    	 * )
    	 * @return
    	 */
    	@Bean
    	public HashedCredentialsMatcher hashedCredentialsMatcher(){
    		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    		hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
    //		hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
    		return hashedCredentialsMatcher;
    	}
    
    	@Bean
    	public UserRealm myShiroRealm(){
    		UserRealm myShiroRealm = new UserRealm();
    		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","403");
    		r.setExceptionMappings(mappings);  // None by default
    		r.setDefaultErrorView("error");    // No default
    		r.setExceptionAttribute("ex");     // Default is "exception"
    		//r.setWarnLogCategory("example.MvcLogger");     // No default
    		return r;
    	}
    

      

    real的校验

    @Slf4j
    public class UserRealm extends AuthorizingRealm {
    
        //注入角色权限等表
         @Autowired
         private PermissionDao permissionDao;
         @Autowired
         private RoleDao roleDao;
         @Autowired
         private RoleToPermissionDao roleToPermissionDao;
         @Autowired
         private UserDao userDao;
         @Autowired
         private UserToRoleDao userToRoleDao;
    
    
        /**
         * 授权
         * @param principals
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    
            User userInfo  = (User)principals.getPrimaryPrincipal();
            UserToRole userToRole = new UserToRole();
            userToRole.setUserId(userInfo.getId());
            List<UserToRole> roleList = userToRoleDao.select(userToRole);
    
            //获取role表和权限表-->设置到realm中去
            List<Role> roles = new ArrayList<>(roleList.size());
            //List<Role> roles = roleDao.selectAll();
            roleList.forEach(item->{
                roles.add(roleDao.selectByPrimaryKey(item.getRoleId()));
            });
    
            roles.forEach(item->{
                authorizationInfo.addRole(item.getRoleName());
                RoleToPermission roleToPermission = new RoleToPermission();
                roleToPermission.setStatus(BaseConstant.STATUS.YES);
                roleToPermission.setRoleId(item.getId());
                List<RoleToPermission> select = roleToPermissionDao.select(roleToPermission);
                for (RoleToPermission itemRoleToPermission : select) {
                    Permission permission = permissionDao.selectByPrimaryKey(itemRoleToPermission.getPermissionId());
                    authorizationInfo.addStringPermission(permission.getPermission());
                }
            });
            System.out.println(authorizationInfo.toString());
            return authorizationInfo;
        }
    
    
        /**
         * @param token
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
            System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
            //获取用户的输入的账号.
            String username = (String)token.getPrincipal();
            System.out.println(token.getCredentials());
            //通过username从数据库中查找 User对象,如果找到,没找到.
            User user = new User();
            user.setName(username);
            User userInfo = userDao.selectOne(user);
            System.out.println("----->>userInfo="+userInfo);
            if(userInfo == null){
                return null;
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    userInfo, //用户名
                    userInfo.getPassword(), //密码
                    ByteSource.Util.bytes("123"),//salt=username+salt
                    getName()  //realm name
            );
            return authenticationInfo;
    
        }
    }
    

      

    最后shiro通过注解实现
     
    shiro实现实现拦截器的功能,自身集成session的管理等,通过注解权限好上手,通过jdbc配置配置权限就要做好数据库权限表的维护等
     
     
  • 相关阅读:
    洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 解题报告
    牛客练习赛 小D的剑阵 解题报告
    牛客练习赛 小A与最大子段和 解题报告
    牛客练习赛 小D的Lemon 解题报告
    牛客练习赛 小A与任务 解题报告
    洛谷 P1452 Beauty Contest 解题报告
    洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告
    【模板】矩阵求逆
    洛谷 P4097 [HEOI2013]Segment 解题报告
    连接数据库的增删改查
  • 原文地址:https://www.cnblogs.com/xiebq/p/9356569.html
Copyright © 2020-2023  润新知