舒大少博客

一个95后少年的个人博客

当前时间为:
欢迎大家来到舒大少博客https://www.9713job.com,广告合作以及淘宝商家推广请微信联系15357240395

shiro权限框架

2022-05-06 09:58:45
swq1822677238

手机扫码查看

shiro权限框架

shiro依赖

<!--shiro-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.8.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.4.0</version>
</dependency>

数据库设计

drop database if exists springboot_shiro;
create database if not exists springboot_shiro;
use springboot_shiro;

create table shiro_user(
    id int auto_increment primary key ,
    username varchar(50),
    password varchar(50),
    salt varchar(50)
)charset=utf8;

shiro 框架相关的配置类

@Configuration
public class ShiRoConfig {
    // 1. 创建 shiro filter // 负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager dwm){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        // 给 filter 设置安全管理器
        factoryBean.setSecurityManager(dwm);
        // 配置系统受限资源
        // 配置系统公共资源
        Map<String,String> map=new HashMap<String,String>();
        map.put("/server/login","anon");// anon 设置为公共资源
        map.put("/server/reg","anon");// anon 设置为公共资源
        map.put("/","anon");// anon 设置为公共资源
        map.put("/admin/*","authc");// authc 请求这个资源需要认证和授权
        // 未登录跳转登录页面
        factoryBean.setLoginUrl("/server/login");

        factoryBean.setFilterChainDefinitionMap(map);

        return factoryBean;
    }
    // 2. 创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
        // 给安全管理器设置 realm
        webSecurityManager.setRealm(realm);
        return webSecurityManager;
    }
    // 3. 创建自定义realm
    @Bean
    public Realm getRealm(){
        CustomerRealm customerRealm = new CustomerRealm();
        // 修改凭证效验匹配器
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        // 设置加密算法为MD5
        matcher.setHashAlgorithmName("sha-256");
        // 设置三列次数
        matcher.setHashIterations(10000);
        // true=hex格式,FALSE=base64格式
        matcher.setStoredCredentialsHexEncoded(false);
        // 将密文比对器 注册在 realm 中
        customerRealm.setCredentialsMatcher(matcher);
        return customerRealm;
    }
}

创建user对象实体类

mapper

@Select("select*from shiro_user where username=#{username}")
ShiroUser queryShiroUsername(String username);

在entity包下创建CustomerRealm实体类

// 自定义 realm
public class CustomerRealm extends AuthorizingRealm {
    @Autowired
    private SqlSession ss;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取身份信息
        String principal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println("调用授权验证:"+principal);
        // 根据主身份信息获取角色 和 权限信息
        if("admin".equals(principal)){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRole("admin");
            info.addRole("user");
            info.addStringPermission("user:add");
            return info;
        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("================");
        // 获取身份信息
        String principal = (String) token.getPrincipal();

        ShiroUserMapper mapper = ss.getMapper(ShiroUserMapper.class);
        ShiroUser user = mapper.queryShiroUsername(principal);

        if(!ObjectUtils.isEmpty(user)){
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),
                    user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());
            return info;
        }
        return null;
    }
}

控制层

// 注册服务
@PostMapping("/reg")
public String reg(ShiroUser user){
    ShiroUserMapper mapper = ss.getMapper(ShiroUserMapper.class);
    // 加密
    String salt = UUID.randomUUID().toString();
    String pass = new Sha256Hash(user.getPassword(),salt,10000).toBase64();
    // 设置盐
    user.setSalt(salt);
    // 设置密文
    user.setPassword(pass);
    try {
        int insert=mapper.insertSelective(user);
        if (insert!=1) {
            log.error("[注册失败] user={}",user);
            throw new RuntimeException("[注册失败]");
        }
        return "redirect:/server/login";
    } catch (Exception e) {
        e.printStackTrace();
        return "public/reg";
    }
}
// 登录服务
@PostMapping("/login")
public String login(String username,String password){
    // 获取主体对象
    Subject subject = SecurityUtils.getSubject();
    try{
        subject.login(new UsernamePasswordToken(username,password));
        return "redirect:/";
    }catch (UnknownAccountException e){
        e.printStackTrace();
        System.out.println("用户名错误");
    }catch (IncorrectCredentialsException e){
        e.printStackTrace();
        System.out.println("密码错误");
    }
    return "redirect:/server/login";
}

首页

<shiro:guest>
    <a href="/server/login">登录</a>
</shiro:guest>
<shiro:authenticated>
    <a href="/server/logout">退出</a>
</shiro:authenticated>

<div>
    <ul>用户管理
        <shiro:hasPermission name="user:add">
            <li>添加用户</li>
        </shiro:hasPermission>
        <shiro:hasPermission name="user:update">
            <li>修改用户</li>
        </shiro:hasPermission>
        <shiro:hasPermission name="user:query">
            <li>查询用户</li>
        </shiro:hasPermission>
        <shiro:hasPermission name="user:delete">
            <li>删除用户</li>
        </shiro:hasPermission>
    </ul>
</div>

订单控制层

@Controller
@RequestMapping("/order")
public class OrderControllers {
    @RequestMapping("/save")
    @RequiresRoles(value = {"admin","user"}) // 用来判断角色,同时具有的角色
    @RequiresPermissions("user:add") // 用来判断权限字符串
    public String save(){
        System.out.println("进入方法");
        return "redirect:/";
    }
}

发表评论

邮箱地址不会被公开。 必填项已用*标注