2021-11-25最适合入门的Shiro框架教程(三)(springboot整合Shiro,自定义Realm,MyRealm)

一、Shiro认证流程回顾

subject调用login方法,将包含用户和密码token传递给SecurityManager

SecurityManager就会调用认证器(Authenticator)进行认证

Authenticator认证器将token传入绑定的Realm,在Realm中进行认证检查;如果认证通过正常执行,认证失败不通过抛出异常。

自定义MyRealm

1.1表设计

用户表tb_users
角色表tb_roles
权限表tb_permissions
用户角色表

tb_urs

角色权限表tb_rps
- RBAC基于角色的访问控制

  ```sql
  -- 用户信息表
  create table tb_users(
  	user_id int primary key auto_increment,
  	username varchar(60) not null unique,
  	password varchar(20) not null,
    password_salt varchar(60)
  );
  
  insert into tb_users(username,password) values('zhangsan','123456');
  insert into tb_users(username,password) values('lisi','123456');
  insert into tb_users(username,password) values('wangwu','123456');
  insert into tb_users(username,password) values('zhaoliu','123456');
  insert into tb_users(username,password) values('chenqi','123456');
  
  -- 角色信息表
  create table tb_roles(
  	role_id int primary key auto_increment,
  	role_name varchar(60) not null
  );
  
  insert into tb_roles(role_name) values('admin');
  insert into tb_roles(role_name) values('cmanager');  -- 仓管
  insert into tb_roles(role_name) values('xmanager');  --  销售
  insert into tb_roles(role_name) values('kmanager');  -- 客服
  insert into tb_roles(role_name) values('zmanager');  -- 行政
  
  -- 权限信息表
  create table tb_permissions(
  	permission_id int primary key auto_increment,		-- 1
  	permission_code varchar(60) not null,						-- sys:c:find
  	permission_name varchar(60)											-- 仓库查询
  );
  insert into tb_permissions(permission_code,permission_name) values('sys:c:save','入库');
  insert into tb_permissions(permission_code,permission_name) values('sys:c:delete','出库');
  insert into tb_permissions(permission_code,permission_name) values('sys:c:update','修改');
  insert into tb_permissions(permission_code,permission_name) values('sys:c:find','查询');
  
  insert into tb_permissions(permission_code,permission_name) values('sys:x:save','新增订单');
  insert into tb_permissions(permission_code,permission_name) values('sys:x:delete','删除订单');
  insert into tb_permissions(permission_code,permission_name) values('sys:x:update','修改订单');
  insert into tb_permissions(permission_code,permission_name) values('sys:x:find','查询订单');
  
  
  insert into tb_permissions(permission_code,permission_name) values('sys:k:save','新增客户');
  insert into tb_permissions(permission_code,permission_name) values('sys:k:delete','删除客户');
  insert into tb_permissions(permission_code,permission_name) values('sys:k:update','修改客户');
  insert into tb_permissions(permission_code,permission_name) values('sys:k:find','查询客户');
  
  -- 用户角色表
  create table tb_urs(
  	uid int not null,
  	rid int not null
  	-- primary key(uid,rid),
  	-- constraint FK_user foreign key(uid) references tb_users(user_id),
  	-- constraint FK_role foreign key(rid) references tb_roles(role_id)
  );
  insert into tb_urs(uid,rid) values(1,1);
  insert into tb_urs(uid,rid) values(1,2);
  insert into tb_urs(uid,rid) values(1,3);
  insert into tb_urs(uid,rid) values(1,4);
  insert into tb_urs(uid,rid) values(1,5);
  
  insert into tb_urs(uid,rid) values(2,2);
  insert into tb_urs(uid,rid) values(3,3);
  insert into tb_urs(uid,rid) values(4,4);
  insert into tb_urs(uid,rid) values(5,5);
  
  -- 角色权限表
  create table tb_rps(
  	rid int not null,
  	pid int not null
  );
  -- 给仓管角色分配权限
  insert into tb_rps(rid,pid) values(2,1);
  insert into tb_rps(rid,pid) values(2,2);
  insert into tb_rps(rid,pid) values(2,3);
  insert into tb_rps(rid,pid) values(2,4);
  -- 给销售角色分配权限
  insert into tb_rps(rid,pid) values(3,4);
  insert into tb_rps(rid,pid) values(3,5);
  insert into tb_rps(rid,pid) values(3,6);
  insert into tb_rps(rid,pid) values(3,7);
  insert into tb_rps(rid,pid) values(3,8);
  insert into tb_rps(rid,pid) values(3,9);
  insert into tb_rps(rid,pid) values(3,10);
  insert into tb_rps(rid,pid) values(3,11);
  insert into tb_rps(rid,pid) values(3,12);
  -- 给客服角色分配权限
  insert into tb_rps(rid,pid) values(4,11);
  insert into tb_rps(rid,pid) values(4,12);
  -- 给行政角色分配权限
  insert into tb_rps(rid,pid) values(5,4);
  insert into tb_rps(rid,pid) values(5,8);
  insert into tb_rps(rid,pid) values(5,12);
  ```

1.2DAO实现

Shiro进行认证需要用户信息:

        根据用户名查询用户信息

Shiro进行授权管理需要当前用户的角色和权限

        根据用户名查询当前角色的角色列表

        根据用户名查询当前用户的权限列表

1.2.1创建SpringBoot项目,整合Mybatis

1.2.2根据用户名查询用户信息

创建UserBean

import lombok.Data;

@Data
public class User {
    private Integer userId;
    private String userName;
    private String userPwd;
    private String pwdSalt;

}

//创建Dao
public interface UserDao {
    public User queryUserByUsername(String username) throws  Exception;
}

//mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qfedu.shiro3.dao.UserDao">

    <resultMap id="userMap" type="com.qfedu.shiro3.beans.User">
        <id column="user_id" property="userId"></id>
        <result column="username" property="userName"/>
        <result column="password" property="userPwd"/>
        <result column="password_salt" property="pwdSalt"/>
    </resultMap>

    <select id="queryUserByUsername" resultMap="userMap">
        select * from tb_users
        where username=#{username}
    </select>


</mapper>

1.2.3根据用户名查询当前角色的角色列表

//roledao
public interface RoleDao {
    public Set<String> queryRoleNameByUserName(String username);
}
//
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qfedu.shiro3.dao.RoleDao">
    <select id="queryRoleNameByUserName" resultSets="java.util.Set"  resultType="string">
        SELECT tb_roles.role_name FROM tb_users
        INNER JOIN tb_urs on tb_users.user_id = tb_urs.uid
        INNER JOIN tb_roles ON tb_urs.rid = tb_roles.role_id
        where tb_users.username=#{username}
    </select>
</mapper>

 1.2.4根据用户名查询当前用户的权限列表

//dao
public interface PermissionDao {
    public Set<String> queryPermissionByUserName(String username) throws Exception;
}
//mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qfedu.shiro3.dao.PermissionDao">
    <select id="queryPermissionByUserName" resultSets="java.util.Set"  resultType="string">
        SELECT tb_permissions.permission_code FROM tb_users
        INNER JOIN tb_urs on tb_users.user_id = tb_urs.uid
        INNER JOIN tb_roles ON tb_urs.rid = tb_roles.role_id
        INNER JOIN tb_rps on tb_urs.rid = tb_rps.rid
        inner join tb_permissions on tb_rps.pid = tb_permissions.permission_id
        where tb_users.username=#{username}
    </select>
</mapper>

1.3整合Shiro

导入依赖


```xml
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>
```

配置Shiro-基于Java配置方式

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
    @Bean
    public MyRealm getMyRealm(){
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }
    //SecurityManager要完成验证,需要realm
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManage(MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        filter.setSecurityManager(securityManager);
        //设置拦截规则
        // anon匿名用户可访问
        //authc 认证用户可以访问
        //user 认证用户可以访问
        //perms 对应权限可以访问
        //role 对应的角色可以访问

        Map<String,String> filterMap=new HashMap<>();
        filterMap.put("/","anon");
        filterMap.put("/login.html","anon");
        filterMap.put("/index.html","anon");
        filterMap.put("/user/login","anon");
        filterMap.put("/user/regist","anon");
        filterMap.put("/static/**","anon");
        filterMap.put("/**","authc");
        filter.setFilterChainDefinitionMap(filterMap);
        filter.setLoginUrl("/login.html");
        filter.setUnauthorizedUrl("/login.html");

        return filter;
    }
}

自定义Realm

import com.qfedu.shiro3.beans.User;
import com.qfedu.shiro3.dao.PermissionDao;
import com.qfedu.shiro3.dao.RoleDao;
import com.qfedu.shiro3.dao.UserDao;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {
    @Resource
    private UserDao userDao;
    @Resource
    private RoleDao roleDao;
    @Resource
    private PermissionDao permissionDao;
    @Override
    public String getName() {
        return "myRealm";
    }

    //获取授权数据:将当前用户的角色及权限查询出来

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.iterator().next();
        //查询用户角色和权限列表
        Set<String> roleName = roleDao.queryRoleNameByUserName(username);
        Set<String> ps = permissionDao.queryPermissionByUserName(username);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roleName);
        info.setStringPermissions(ps);

        return info;
    }
        //获取认证数据

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //authenticationToken 就是传递suject。login(token)
        UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
        String username=token.getUsername();
        User user = userDao.queryUserByUsername(username);
        if (user==null){
            return null;
        }
        AuthenticationInfo info = new SimpleAuthenticationInfo(username,user.getUserPwd(),getName());
        return info;
    }
}

二、springboot项目应用部署

SpringBoot项目集成了web容器(Tomcat),所以SpringBoot应用是可以打包成jar直接运行的

nohup java -jar  shiro4.jar

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值