spring boot 整合 shiro + mybatis

1,shiro安全框架整合

1.简介

三个核心组件:Subject, SecurityManager 和 Realms.

  • Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
    Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

  • SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过
    SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

  • Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果系统默认的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

image

2,整合

1.创建自定义的UserRealm 的realm对象

package com.example.config;

import com.example.pojo.User;
import com.example.service.UserServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
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 {

    public UserRealm() {
        super();
    }

    @Autowired
    UserServiceImpl userService;

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;

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

        if (user==null){
            return null;//UnknownAccountException
        }

        //密码验证,shiro自动来验证
        return new SimpleAuthenticationInfo("",user.getPwd(),"");
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}

2.编写shiroconfig配置类,创建shiro三大核心组件对象

package com.example.config;

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;

@Configuration
public class ShiroConfig {

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

    //DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //ShiroFilterFactoriBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //添加shiro的内置过滤器
        /*
        * anon: 无需认证就可以访问
        * authc: 认证才能访问
        * user: 拥有记住我才能访问
        * perms:拥有对某个资源的权限才能访问
        * role: 拥有某个角色权限才能访问
        * */
//        filterMap.put("/test/u1","authc");
//        filterMap.put("/test/u2","authc");

        //拦截功能
        Map<String, String> filterMap=new LinkedHashMap<>();
        filterMap.put("/test/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);

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

        return bean;
    }
}

3.编写controller类,封装用户的数据(token),执行登陆的方法

package com.example.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;

@Controller
public class controller {

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

    @RequestMapping("/test/u1")
    public String u1(){
        return "test/user1";
    }

    @RequestMapping("/test/u2")
    public String u2(){
        return "test/user2";
    }

    @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";
        }
    }
}

3.整合mybatis

上篇已整合,略......

posted @ 2021-04-15 14:47  Chcode  阅读(98)  评论(0)    收藏  举报