springboot-shiro 入门

个人笔记!仅供参考

1.引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--   mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <!-- 版本统一在properties里面管理; 1.0.5-->
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--   引入mybatis 官方提供适配springboot的    -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

        <!-- shiro 整合 thymeleaf  -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.1.0</version>
        </dependency>

        <!--
        subject 用户
        securityManager 管理所有用户;
        Realm 连接数据
        -->


        <!--  shiro 整合spring的包    -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.1</version>
        </dependency>
        <!--   thymeleaf模板     -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <!--  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.7.0</version>
        </dependency>

2配置文件yml-项目结构

在这里插入图片描述

mybatis:
  mapper-locations: classpath:mapper/*.xml

3配置shiro

ShiroConfig

package com.me.config.shiro;

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;

/**
 * Description: .
 * Date:        2022/6/2 19:14
 * author:      chuliujian
 * version:     V1.0
 */
@Configuration
public class ShiroConfig {

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

    //2.DafultWebSecurityManager
    //Qualifier("")绑定bean容器里对象,//如果@bean(name="securityManager") 那么此时bean对象的名称为securityManager; 不加name属性名称就是方法名getdefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getdefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联userRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //3.ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getshiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        //关联DefaultWebSecurityManager
        bean.setSecurityManager(defaultWebSecurityManager);

        //4,添加shiro过滤器
        /*
        * anon 无需认证就可以访问
        * authc:必须认证才能访问
        * user: 必须拥有记住我 功能才能用
        * perms:拥有对某个资源的权限才能访问
        * role:拥有某个角色才能访问
        *
        * logout  //框架的登出功能;
        * */

        //拦截的都是请求!!填写的都是请求接口 不是页面地址!!!
        Map<String, String> filterMap = new LinkedHashMap<>();
        //认证
        // authc 这条请求必须认证才能访问
        //支持通配符  //filterMap.put("/login/*","authc");
        filterMap.put("/login/add","authc");  // 请求"/login/add",必须认证才能请求 否则跳转到登录页面;


        //授权 //访问此请求 需要经过授权   没有授权会跳转到未授权页面
        filterMap.put("/login/add","perms[user:add]");
        //多个参数之间用,分割
//        filterMap.put("/login/add","perms[user:add,user:update]");

        //登出;  shiro自带的登出 完事自己重新返回登录页面
        filterMap.put("/auth/logout", "logout");

        //链式
        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录的请求 无权限的都会跳转到这进行登录。
        bean.setLoginUrl("/tologin");

        //未授权页面  设置未授权的请求
        bean.setUnauthorizedUrl("/noauth");

        return bean;
    }
}

shiro 认证和授权

package com.me.config.shiro;

import com.me.modules.userinfo.domain.User;
import com.me.modules.userinfo.service.UserService;
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.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Description: .
 * Date:        2022/6/2 19:16
 * author:      chuliujian
 * version:     V1.0
 */
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;


    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//       System.out.println("执行了=>授权");
        //登录后都会经过授权
        //SimpleAuthorizationInfo
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //那当当前登录的这个对象   //就是认证里面user信息 返回的第一个参数 与这关联getPrincipal
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal(); //拿到user对象;

        //添加权限           info.addStringPermission("user:add");
        //此处的权限 user:add 应该从数据库里面去取    user.get权限;
        info.addStringPermission("user:add");

        //返回info
        return info;
    }

    //认证(登录认证)
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   //=================================伪造数据=======================================================================
        /**
         * 此处作为理解!!!  数据未查库
         *
        // 执行 shirocontroller----登录方法subject.login(token);
        System.out.println("执行了=>认证");

        //从数据库查询的数据 此处为伪造数据
        String name="root";
        String password="123456";

       //从shirocontroller中封装的信息
        UsernamePasswordToken usertoken=(UsernamePasswordToken)token;
        //前端登录的账号
        String username = usertoken.getUsername();


        if (!username.equals(name)){
            //返回空 抛出异常 UnknownAccountException  具体写在shirocontroller里面 返回账号错误
            return null;
        }
        //密码认证;此处第二个参数为数据库查出的密码  第一个参数需要把user信息传进去 方便授权的时候去取
        //SimpleAuthenticationInfo三个参数
        return new SimpleAuthenticationInfo("",password,"");
         */
//=================================认证逻辑-与数据库交互====================================================================================

        //通过username查询到当前登录人信息 此处未id; 所以参数为1
        User userInfoservice = userService.getUserInfoservice(1);

        //从shirocontroller中封装的信息
        UsernamePasswordToken usertoken=(UsernamePasswordToken)token;
        //前端登录的账号
        String username = usertoken.getUsername();

        //账号与数据库中不匹配
        if (!userInfoservice.getUsername().equals(username)){
            //未查到
            return null;
        }
        //验证密码
        //第一个参数
        return new SimpleAuthenticationInfo(userInfoservice,userInfoservice.getPassword(),"");
    }
}

ShiroController层级

package com.me.config.shiro.shirocontroller;

import com.sun.org.glassfish.gmbal.ParameterNames;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
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;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Description: .shiro的登录请求接口
 * 在登录页面填写信息,然后提交按钮 走到该请求。
 * Date:        2022/6/2 20:50
 * author:      chuliujian
 * version:     V1.0
 */
@Controller
public class ShirlLoginController {

    @RequestMapping("/login")
    //此处的username 和password 都应该从前端传过来!
    public  String login(String username, String password, Model model){
        //确保username和password拿到
        System.out.println("登录信息username="+username+"登录信息password="+password);
        //获取当前用户信息
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            //执行登录方法 如果没有异常说明ok  ---去UserRealm中认证
            subject.login(token);
            //跳转首页
            return "index";

        }catch (UnknownAccountException e){
            //用户名不存在 /返回给前端信息 并且 跳转到登录页面
            model.addAttribute("msg","用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e){
            //密码不存在 /返回给前端信息 并且 跳转到登录页面
            model.addAttribute("msg","密码不存在");
            return "login";
        }

    }
    /**
     * 未授权页面
     */
    @RequestMapping("/noauth")
    @ResponseBody
    public  String noNoauth(){
        //跳转到对应页面
        return "未授权";
    }

    /**
     * shiro登出 在配置中已经写出shiroConfig  拦截请求 调用shiro的登出功能
     * 此处不需自己写。
     */
    @RequestMapping("/auth/logout")
    @ResponseBody
    public String toLogOut(){
    return "";
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路向楠i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值