springboot运用shiro简单控制权限

shiro简单介绍

shiro是一个功能强大的java安全框架,主要部分构成认证、授权、加密和会话管理等。

1.认证:身份认证,验证登录用户是否正确等。

2.授权:授予权利访问某个页面或接口。

3.加密:shiro提供加密服务。保护数据的安全性,如密码加密存储到数据库,而不是明文存储。

4.会话管理:用户登录了一次就是会话,在一定时间内,用户的所有信息都保存在会话中。

spring装配shiro,基于javaBean的写法

1.将SecurityManager交给spring处理

@Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm());
        return securityManager;
    }

2.创建realm

@Bean
    public ShiroRealm shiroRealm(){
        ShiroRealm shiroRealm=new ShiroRealm();
        return shiroRealm;
    }

3.配置ShiroFilterFactoryBean

@Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        System.out.println("---shiroFIlter---");

        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();

        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        //注意过滤器配置顺序 不能颠倒
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/favicon.ico", "anon");
        //拦截其他所以接口
        filterChainDefinitionMap.put("/**", "authc");
        //配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接 自行处理。不用shiro进行跳转
        // shiroFilterFactoryBean.setSuccessUrl("user/index");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/unauth");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return  shiroFilterFactoryBean;
    }

4.创建代理bean通知类和开起shiro aop切面编程支持,注:往spring里面注入这两个bean。才能用注解的方式去对权限做校验。

@Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
    /**
     * 开启shiro aop注解支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor sourceAdvisor=new AuthorizationAttributeSourceAdvisor();
        sourceAdvisor.setSecurityManager(securityManager);
        return sourceAdvisor;
    }

自定义实现realm,实现认证和授权的过程

1.认证过程

认证我们需要做的是通过用户名的比对。从数据库中查询相应的用户。并放入SimpleAuthenticationInfo中,剩下的交给shiro去认证校验。
myrealm的认证:

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String)authenticationToken.getPrincipal();
        System.out.println(username);
        ShiroUser shiroUser=shiroUserMapper.selectByUserName(username);
        if (shiroUser==null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(
                shiroUser,
                shiroUser.getPassword(),
                getName()
        );
        return authenticationInfo;
    }
}

查询语句:

<select id="selectByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from shiro_user
    where username = #{userName,jdbcType=VARCHAR}
  </select>

2.授权过程
授权需要我们做的是通过用户id查询角色和权限,将权限和角色注入到AuthorizationInfo
授权:

@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("--权限注入--");
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        ShiroUser shiroUser= (ShiroUser) principalCollection.getPrimaryPrincipal();
        //注入角色权限
     try {
         List<ShiroRole> shiroRoles=shiroUserMapper.selectRoleByUser(shiroUser.getId());
         for (ShiroRole s:shiroRoles){
             simpleAuthorizationInfo.addRole(s.getRoleName());
         }
         List<ShiroFunction> shiroFunctions =shiroUserMapper.queryByUserId(shiroUser.getId());
         for(ShiroFunction functions:shiroFunctions){
             simpleAuthorizationInfo.addStringPermission(functions.getPermissionName());

         }
     }catch (Exception e){
         e.printStackTrace();
     }
        return simpleAuthorizationInfo;
    }

查询语句:

<select id="selectRoleByUser" parameterType="java.lang.Integer" resultType="com.example.pojo.ShiroRole">
    select role_name,role_id,shiro_role.create_time
    from shiro_role
    left join shiro_user_role r on shiro_role.id = r.role_id
    left join shiro_user u on r.user_id = u.id
    where u.id=#{id,jdbcType=INTEGER}
  </select>
    <select id="queryByUserId" parameterType="java.lang.Integer" resultType="com.example.pojo.ShiroFunction">
      select shiro_function.id,shiro_function.create_time,shiro_function.function_name,shiro_function.permission_name,shiro_function.pid
    from shiro_function
    left join shiro_role_function r on shiro_function.id = r.function_id
    left join shiro_user_role u on u.role_id = r.role_id
    left join shiro_user su on u.user_id = su.id
    where su.id=#{id,jdbcType=INTEGER}
  </select>

结语:

这样一个简单的shiro权限的配置和注入就完成了,基本能够控制用户登录,根据用户的不用分配不同的权限和角色,达到对权限的控制。
demo地址:http://114.115.154.147/ 用户名:admin 密码:123 原谅没有域名。

猜你喜欢

转载自blog.csdn.net/luo_qianyu/article/details/88743650