Shiro

ⅰ亾dé卋堺 提交于 2019-12-30 03:05:18

导入依赖:

<dependency>
   <groupId>org.apache.shiro</groupId>
   <artifactId>shiro-spring-boot-starter</artifactId>
   <version>1.4.2</version>
</dependency>

配置数据库信息:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC
    username: root
    password: 123456

编写mapper模块:

@Mapper
@Repository
public interface UserMapper {

    @Select("select * from user where username = #{username}")
    Map getUser(String username);//按账号查询用户方法

    @Select("select c.name from user a join ur b on a.id=b.uid join role c on b.rid=c.id where a.id=#{id}")
    List<String> getRole(String id);//按用户id查询角色集合方法

    @Select("select e.name from user a join ur b on a.id=b.uid join role c on b.rid=c.id join rp d on c.id=d.rid join perm e on d.pid=e.id where a.id = #{id}")
    List<String> getPerm(String id);//按用户id查询角色权限方法

}

自定义Realm:

//自定义Realm
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserMapper userMapper;

    @Override//负责授权逻辑
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获得从doGetAuthenticationInfo方法得到的map
        Map map = (Map)principalCollection.getPrimaryPrincipal();
        //查询角色集合
        List<String> roleList = userMapper.getRole(map.get("id").toString());
        //查询权限集合
        List<String> permList = userMapper.getPerm(map.get("id").toString());
        //用于聚合权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //放入查询角色集合
        info.addRoles(roleList);
        //放入查权限色集合
        info.addStringPermissions(permList);
        return info;
    }

    @Override//负责认证逻辑
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //拿到控制层传过来的UsernamePasswordToken
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //通过token里的账号查询用户
        Map map = userMapper.getUser(token.getUsername());
        if(map==null) return null;
        //把用户,密码传入框架中校验
        return new SimpleAuthenticationInfo(map,map.get("password"),getName());
    }
    
}

编写配置类:

@Configuration
public class ShiroConfig {

    @Bean//创建用户主体并关联DefaultWebSecurityManager
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //设置没有权限会跳转到的页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        shiroFilterFactoryBean.setUnauthorizedUrl("/index.html");
        /*
        * Shiro内置过滤器:实现权限相关的拦截
        *   anon:无需验证
        *   authc:验证后可访问
        *   user:使用rememberMe的功能可以访问
        *   perms:必须得到资源权限才可以访问
        *   roles:必须得到角色权限才可以访问
        */
        Map<String,String> filteMap = new LinkedHashMap<>();
        //登陆验证
        filteMap.put("/select","anon");//放行路径中带有select
        filteMap.put("/insert","authc");//需要验证后才有权限访问路径中带有insert
        filteMap.put("/delete","authc");//需要验证后才有权限访问路径中带有delete
        filteMap.put("/update","authc");//需要验证后才有权限访问路径中带有update
        //filteMap.put("/*","authc");//需要验证后才有权限访问所有路径

        //授权验证
        filteMap.put("/insert","perms[insert]");//访问insert路径需要insert权限
        filteMap.put("/delete","perms[delete]");//访问delete路径需要delete权限
        filteMap.put("/update","perms[update]");//访问update路径需要update权限

        filteMap.put("/select","roles[boss]");//访问select路径需要boss角色

        //把map放入用户主体中
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filteMap);
        return shiroFilterFactoryBean;
    }


    @Bean//创建安全管理器并关联Realm
    public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm myRealm) {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(myRealm);
        return defaultSecurityManager;
    }

    @Bean//把自己编写的Realm放入spring容器
    public MyRealm getMyRealm(){
        return new MyRealm();
    }
}

用于测试的提供者:

@RestController
public class LoginController {

    @RequestMapping("/login")
    public String login(@RequestParam Map map){
        //获取当前用户,即subject
        Subject subject = SecurityUtils.getSubject();
        //把用户名密码封装成UsernamepasswordToken
        UsernamePasswordToken token = new UsernamePasswordToken((String)map.get("username"),(String)map.get("password"));
        try {
            //传入框架中
            subject.login(token);
        }catch (UnknownAccountException e){
            //此异常代表用户名不存在
            return "用户名不存在";
        }catch (IncorrectCredentialsException e){
            //此异常代表密码错误
            return "密码错误";
        }
        return "登陆成功";
    }

}
@Controller
public class UserController {

    @RequestMapping("/insert")
    public String insert(){
        return "insert.html";
    }

    @RequestMapping("/delete")
    public String delete(){
        return "delete.html";
    }

    @RequestMapping("/update")
    public String update(){
        return "update.html";
    }

    @RequestMapping("/select")
    public String select(){
        return "select.html";
    }

    @RequestMapping("/getuser")
    public String user(){
        return "user/user.html";
    }

}

SQL语句:

create table user(
id int(10) PRIMARY KEY AUTO_INCREMENT,
username varchar(20) not null,
password varchar(20) not null
);

insert into user values(default,'abcd','123456');
insert into user values(default,'efg','123456');

create table role(
id int(10) PRIMARY KEY AUTO_INCREMENT,
name varchar(20) not null
);  

insert into role values(default,'boss');
insert into role values(default,'staff');

create table perm(
id int(10) PRIMARY KEY AUTO_INCREMENT,
name varchar(20) not null
);  

insert into perm values(default,'insert');
insert into perm values(default,'delete');
insert into perm values(default,'update');
insert into perm values(default,'select');

create table ur(
id int(10) PRIMARY KEY AUTO_INCREMENT,
uid int(20) not null,
rid int(20) not null
);  

insert into ur values(default,1,1);
insert into ur values(default,2,2);

create table rp(
id int(10) PRIMARY KEY AUTO_INCREMENT,
rid int(20) not null,
pid int(20) not null
);  

insert into rp values(default,1,1);
insert into rp values(default,1,2);
insert into rp values(default,1,3);
insert into rp values(default,1,4);
insert into rp values(default,2,4);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!