Shiro入门案例

1.准备环境,引入maven依赖

 <!--1. 整合springboot,shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.1</version>
        </dependency>



        <!--整合mybatisplus-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.18</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

2.数据源配置

spring:
  datasource:
#    url: jdbc:mysql://127.0.0.1:3306/blog_3?serverTimezone=UTC
    url: jdbc:mysql://127.0.0.1:3306/mybatisplus?serverTimezone=UTC
    #    username: root
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
#开启mybatis-plus sql日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志

3.配置shiro配置类

package cn.hmc.demo.config;

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

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 创建用户: HMC
 * 创建时间: 2021/12/6
 */
@Configuration
public class ShiroConfig {

    //shiro必须要的三大模块
    //ShiroFilterFactoryBean 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(
                                            //拿到下面的DefaultWebSecurityManager对象
                                            @Qualifier("getDefaultWebSecurityManager")
                                            DefaultSecurityManager defaultSecurityManager
    ){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultSecurityManager);

        //添加shiro内置过滤器

        //拦截访问页面
        Map<String, String> filterMap = new LinkedHashMap<>();

        //拦截规则
        /**
         *  anon:无需认证可以访问
         *  authc:必须认证才能访问
         *  user:必须拥有 记住我 功能才能用
         *  perms:拥有对某个资源的权限才能访问
         */
        filterMap.put("/add","authc");
        filterMap.put("/update","authc");
//        filterMap.put("user/*","autc");

        //授权,必须要有这个权限,才能访问这个add
        filterMap.put("/add","perms[add]");
        filterMap.put("/update","perms[update]");
        //(type=Unauthorized, status=401). 未授权,报错码

        //将拦截规则与权限规则加进bean中
        bean.setFilterChainDefinitionMap(filterMap);

        //设置没有权限跳转的页面
        bean.setUnauthorizedUrl("/unauthorized");
        //设置登录请求
        bean.setLoginUrl("/login");

        return bean;
    }


    //DetaultWebSecurityManager 2
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") //拿到下面的realm对象
                                                                UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    //创建realm对象,需要自定义类 1
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //用来整合shiro thymeleaf
    @Bean
    public ShiroDialect getshiroDialect(){
        return new ShiroDialect();
    }

}

4.自定义realm

package cn.hmc.demo.config;

import cn.hmc.demo.domain.Admin;
import cn.hmc.demo.mapper.AdminMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
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.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 创建用户: HMC
 * 创建时间: 2021/12/6
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    AdminMapper mapper;

    //授权,根据查询出来的用户权限,开放相关模块
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("UserRealm=>doGetAuthorizationInfo授权");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //不管谁访问都给个权限
//        info.addStringPermission("admin:add");
        //拿到登录的用户
        Subject subject = SecurityUtils.getSubject();
        //取出认证传递的数据
        Admin o = (Admin) subject.getPrincipal();

        //判断有什么权限,开启什么内容
        //设置用户权限
        if (o.getPerms()!=null){
            info.addStringPermission(o.getPerms());
        }
        return info;
    }

    //认证,就是判断用户名密码是否正确
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("UserRealm=>doGetAuthorizationInfo认证");

        //模拟查询数据库操作
        /*String name = "admin";
        String password = "123456";*/
        //连接真实的数据库

        //拿到令牌
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        /*if (!name.equals(token.getUsername())){
            return null;//抛出UnknownAccountException异常
        }*/
        Admin admin = mapper.selectOne(new QueryWrapper<Admin>().eq("username", token.getUsername()));
        if (admin==null){//没有这个人
            return null;
        }

        //登录成功,将用户信息存入session中
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("admin",admin);


        //密码认证,shiro自动帮我们做,因为它不相信我们
//        return new SimpleAuthenticationInfo("",password,"");
        return new SimpleAuthenticationInfo(admin,admin.getPassword(),"");
    }
}

5.controller,静态文件

package cn.hmc.demo.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 创建用户: HMC
 * 创建时间: 2021/12/6
 */
@Controller
public class MyController {

    @RequestMapping({"/","/index"})
    public String test(Model model){
        model.addAttribute("msg","你好shrio");
        return "index";
    }

    @RequestMapping("/add")
    public String add(){
        return "user/add";
    }

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

    //登录页面
    @RequestMapping("/login")
    public String login(){
        return "login";
    }

    @RequestMapping("/logOut")
    public String logOut(Model model){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        model.addAttribute("msg","安全退出!");
        return "index";
    }

    //用户未授权跳转页面
    @RequestMapping("/unauthorized")
    public String Unauthorized(){
        return "unauthorized";
    }

    //登录功能
    @RequestMapping("/loginIn")
    public String loginIn(String name,String password,Model model){

        Subject subject = SecurityUtils.getSubject();
        //将用户名密码传入令牌中
        UsernamePasswordToken token = new UsernamePasswordToken(name,password);
        //执行登录方法,如果没有异常就说明ok
        try {
            subject.login(token);
            return "index";
        } catch (UnknownAccountException e) {//用户名不存在
            model.addAttribute("msg","用户名错误!");
            return "login";
        } catch (IncorrectCredentialsException e) {//密码错误
            model.addAttribute("msg","密码错误!");
            return "login";
        }
    }
}

html文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

这里是首页
<h1 th:text="${msg}"></h1>
<hr>

<div th:if="${session.admin==null}">
    <p>
        <a href="/login">登录</a>
    </p>
</div>

<div th:if="${session.admin!=null}">
    <p>
        <a href="/logOut">注销</a>
    </p>
</div>

<p th:text="${msg}"></p>
<!--如果需要使用这个功能,需要引入一个bean ShiroDialect-->
<div shiro:hasPermission="add">
    <a href="/add">add</a>
</div>
<div shiro:hasPermission="update">
    <a href="/update">update</a>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>登录</h1>
<hr>
<span th:text="${msg}" style="color: #ff0000"></span>
<form th:action="@{/loginIn}" method="post">
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
    <input type="submit">
</form>

</body>
</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值