SpringBoot——Shiro框架技术整合(课时二十三)

本案例实战框架用了以下技术

  • SpringBoot框架

  • Shiro的框架

  • MyBatis框架

  • Spring框架

  • thymeleaf技术

  • SSM三层框架

  • 数据库

实操部分

  • Subject——org.apache.shiro.subject.Subject

    特定于当前与软件交互的实体的安全视图

  • SecurityManager——org.apache.shiro.mgt.SecurityManager

    Shiro架构的核心,管理并协调各个组件共同完成安全工作,它还管理每个应用程序用户的Shiro视图,因此它知道如何为每个用户执行安全操作。

  • Authenticator——org.apache.shiro.authc.Authenticator

    Authenticator是负责认证的组件,当用户尝试登录时,登录是由Authenticator来执行的,Authenticator将会从Realms取出用户信息,来和用户提供的登录信息进行比对

    • Authenticator Strategy——org.apache.shiro.authc.pam.AuthenticationStrategy

      如果超过一个Realm被配置了,这个AuthenticationStrategy将会协调这些Realms来决定认证操作是否成功,比如,认证成功是需要所有的Realms都认证成功,还是仅仅一个Realm成功

  • Authorizer——org.apache.shiro.authz.Authorizer

    Authorizer是负责访问控制的组件,换句话说,它负责检测用户是否有执行某个操作的权限。和Authenticator一样,Authorizer也从多个Realms数据源中获取用户的角色信息和权限信息,通过这些信息来判断用户是否可以执行某个操作

  • SessionManager——org.apache.shiro.session.mgt.SessionManager

    注意不是SecurityManager,SessionManager负责创建和管理用户的Session周期。在安全框架中,Shiro提供了一个独有的特性,Shiro可以在任何环境中管理用户会话,即使实在非Web/Servlet和非EJB容器环境中,默认情况下,Shiro将会使用已有的会话机制,如Servlet容器,如果没有,Shiro将会使用内建的企业会话管理机制来管理会话。通过SessionDao,我们可以使用任何数据源来持久化Session

    • SessionDAO——org.apache.shiro.session.mgt.eis.SessionDAO

      SessionDAO代表SessionManager执行会话持久性(CRUD)操作。它允许将任何数据存储插入到Session Management基础结构中

  • CacheManager——org.apache.shiro.cache.CacheManager

    CacheManager负责创建Shiro中的其他组件的Cache实例并管理其生命周期,因为Shiro需要访问各种数据源来进行认证,授权和会话管理,缓存一直是框架中的一流架构特性,可以在使用这些数据源时提高性能,任何现代的开源或者企业缓存产品都可以接入Shiro中

  • Cryptography——org.apache.shiro.crypto.*

    Shiro的crypto包包含了易于使用和理解的常见加密算法实现。使用过Java自带的加密库的人都应该知道它很难使用,Shiro提供的加密API简化了复杂的Java机制,让加密更便于使用

  • Realms——org.apache.shiro.realm.Realm

    正如前面提到的,Realms是Shiro和应用程序数据的桥梁,当需要执行认证和授权时,Shiro会从至少一个Realm中寻找用户信息,应用程序中可以配置许多个Realm,Shiro会在必要时协调这些Realm

pom.xml文件信息配置



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.4
         
    
    com.lop
    shiro-springboot
    0.0.1-SNAPSHOT
    shiro-springboot
    Demo project for Spring Boot
    
        1.8
    
    
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.2
        

        
        
            org.thymeleaf.extras
            thymeleaf-extras-shiro
            2.0.0
        


        
        
            com.alibaba
            druid
            1.2.12
        

        
        
            log4j
            log4j
            1.2.14
        

        
        
            mysql
            mysql-connector-java
            1.2.17
        
        
        
            org.apache.shiro
            shiro-spring
            1.9.1
        


        
        
        
            org.thymeleaf
            thymeleaf-spring5
        
        
            org.thymeleaf.extras
            thymeleaf-extras-java8time
            3.0.4.RELEASE
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.xmlunit
            xmlunit-core
            2.5.1
            compile
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


Yml文件信息

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    initial-size: 5
    min-idle: 5
    max-active: 20
    # 配置获取连接等待超时的时间
    max-wait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    time-between-eviction-runs-millis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    min-evictable-idle-time-millis: 300000
    validation-query: SELECT 1 FROM DUAL
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    pool-prepared-statements: true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 最好的功能
    max-pool-prepared-statement-per-connection-size: 20
    filters: stat,wall
    use-global-data-source-stat: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

SpringBoot——Shiro框架技术整合(课时二十三)_第1张图片

 index.html页面




    
    Document



假如hasPermisssion有这个限制 add

index

add
update

login.html页面




    
    Title



登录


用户名:

用户密码:

SpringBoot——Shiro框架技术整合(课时二十三)_第2张图片 add.html

 

SpringBoot——Shiro框架技术整合(课时二十三)_第3张图片 update.html

 数据层:






    
package com.lop.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;


@Repository
@Mapper
public interface UserMapper {

    public UserMapper queryUserByName(String username);

}

Service层:

package com.lop.Service;

import com.lop.pojo.User;

public interface UserService {
    public User queryUserByName(String username);


}
package com.lop.Service;

import com.lop.mapper.UserMapper;
import com.lop.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceLmp implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public User queryUserByName(String username) {
        userMapper.queryUserByName(username);
        return null;
    }
}

控制层:

package com.lop.Controller;

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.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 首页控制器
 */
@Controller

public class MyController {

    @RequestMapping({"/", "/index"})
    public String toIndex(Model model) {
        model.addAttribute("msg", "hllow");
        return "index";
    }


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


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


    @RequestMapping("/tologin")
    public String toLogin() {
        return "login";
    }

    @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        //获取当前的用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        //执行登录方法
        try {
            subject.login(token);


            return "index";
        } catch (UnknownAccountException e) {
            model.addAttribute("msg", "用户的名字步存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("msg", "用户的密码有误");
            return "login";
        }
    }

    @RequestMapping("/noauth")
    public  String unauthorized(){
        return "没有授权无法访问信息";

    }

}

认证授权

package com.lop.config;

import com.lop.Service.UserService;
import com.lop.pojo.User;

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;


/**
 * 自定义的UserRealm
 */


public class UserRealm extends AuthorizingRealm {
    //把用户数据库拿过来 连接真实数据库
    @Autowired
    UserService  userService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("----------------------授权");

        //  SimpleAuthorizationInfo
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //打开没有授权的功能
        info.addStringPermission("uder:add");

        //拿到当前对象
        Subject subject = SecurityUtils.getSubject();
        User  currentUser = (User) subject.getPrincipal();//拿到user对象
        //设置当前用户的权限
        info.addStringPermission(currentUser.getPerms());

        return info;
    }

  
  //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==========================认证");
    //        String name = "root";
    //        String password = "123456";

        UsernamePasswordToken usertoken = (UsernamePasswordToken) token;
        //连接真实数据库
       User user=userService.queryUserByName(usertoken.getUsername());

         if (user == null) {
             return null;
         }
        Subject cursubject = SecurityUtils.getSubject();
        Session session = cursubject.getSession();
        session.setAttribute("loginUser",user);


        //        if(!usertoken.getUsername().equals(name)){
    //            return null;
    //        }
        //密码认证
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

ShiroConfig 代码解读:

package com.lop.config;

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.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

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

@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();

设置管理器

bean.setSecurityManager(defaultWebSecurityManager);

SpringBoot——Shiro框架技术整合(课时二十三)_第4张图片

 

  //授权的信息内容 有user:add 没有授权
        filterMap.put("/user/add", "perms[user:add]");
        filterMap.put("/user/update", "perms[user:update]");
 //用户没有授权请前往这个页面
        bean.setLoginUrl("/noauth");
 //设置登录请求
        bean.setLoginUrl("/tologin");

        bean.setFilterChainDefinitionMap(filterMap);

        return bean;
    }
 // 自定义的UserRealm
    //    @Bean(name = "userRealm")
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

SpringBoot——Shiro框架技术整合(课时二十三)_第5张图片

 

假如hasPermisssion有这个限制 add

index

add
update
SpringBoot——Shiro框架技术整合(课时二十三)_第6张图片 login的登录

 

SpringBoot——Shiro框架技术整合(课时二十三)_第7张图片 SpringBoot

 

理论介绍:

//设置管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //增加shiro的内置过滤器
        /**
         * anon
         * authc
         * perms
         * role
         */
        Map filterMap = new LinkedHashMap<>();
//        filterMap.put("/user/add","authc");
//        filterMap.put("/user/update","authc");
        filterMap.put("/user/*", "authc");

        //授权的信息内容 有user:add 没有授权
        filterMap.put("/user/add", "perms[user:add]");
        filterMap.put("/user/update", "perms[user:update]");

        //用户没有授权请前往这个页面
        bean.setLoginUrl("/noauth");

        //设置登录请求
        bean.setLoginUrl("/tologin");

        bean.setFilterChainDefinitionMap(filterMap);

        return bean;
    }

    //DefaultWebSecurityManager
    //DefaultWebSecurityManager 管理
    @Bean("securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    // 自定义的UserRealm
    //    @Bean(name = "userRealm")
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    /*整合包 thymeleaf-extras-shiro */
    @Bean
    public  SiroDialect getSiroDialect() {
        return new SiroDialect();
    }




 

你可能感兴趣的:(SpringBoot,SSM,SSMS,spring,boot,mybatis,spring)