Springboot整合Shiro

ShiroShiroShiro核心组件Shiro是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。Shiro 就是用来解决安全管理的系统化框架Shiro核心组件用户,角色,权限会给角色赋予权限,给用户赋予角色用户拥有角色,角色拥有权限,用户不跟权限直接挂钩UsernamePasswordToken,Shiro用来封装用户登录信息,使用户的登录信息来创建令牌Tok
摘要由CSDN通过智能技术生成

Shiro

是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。

Shiro 就是用来解决安全管理的系统化框架

Shiro核心组件

用户,角色,权限
会给角色赋予权限,给用户赋予角色
在这里插入图片描述
用户拥有角色,角色拥有权限,用户不跟权限直接挂钩

  1. UsernamePasswordToken,Shiro用来封装用户登录信息,使用户的登录信息来创建令牌Token
  2. SecurityManager,Shiro的核心部分,负责安全认证和授权
  3. Suject,Shiro的一个抽象概念,包装了用户信息
  4. Realm,开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部卸载Realm中
  5. AuthenticationInfo,用户的角色信息的集合,认证时使用
  6. AuthorzationInfo,角色的权限信息集合,授权时是用
  7. DefaultWebSecurityManager,安全管理器,开发者自定义可的Realm,需要注入到DefaultWebSecurityManager进入管理才能生效
  8. ShiroFilterFactoryBean,过滤器工厂,Shiro的基本运行机制是开发者定制的规则,Shiro去执行,具体的执行操作就是由ShiroFilterFactoryBean创建一个个的Filter对象来完成。

Shiro的运行机制如下图所示。
,S
Token相当于公司的工牌 ,Token关联到Subject,SecurityManager核心部分。关联着角色信息和权限信息。Realm里面写逻辑,然后传到他们两个。在这里插入图片描述

  1. 创建SpringBoot工程,集合Shiro及其相关组件。
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.7.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
  1. 创建一张表
create table account(
    id int(20) not null primary key ,
    username varchar(30) null,
    password varchar(30) null,
    perms varchar(30),
    role varchar(30)
)engine=InnoDB default charset=utf8;

要管理数据库,则需要加上数据库的驱动。mysql,这次没有使用mybatis,而是使用mybatis-plus的依赖

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.3.1.tmp</version>
</dependency>
  1. 创建实体类关联表,entity包
package com.zhou.entity;

import lombok.Data;

@Data
public class Account {
   
    private Integer id;
    private String username;
    private String password;
    private String perms;
    private String role;
}
  1. 创建mapper包,
package com.zhou.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhou.entity.Account;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

// 使用mybatis-plus,不用自己写sql,需要继承BaseMapper,泛型是对应的表的类
@Repository
@Mapper // 把mapper中的包也扫进去,也可以在启动类上加注解@MapperScan也可以
public interface AccountMapper extends BaseMapper<Account> {
   
}
  1. yml配置数据库和mybatis-plus
# 配数据库
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT
    username: root
    password: 123456

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  1. 测试看是否能查询出来,在测试类写
package com.zhou;

import com.zhou.mapper.AccountMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootShiroApplicationTests {
   

    @Autowired
    private AccountMapper accountMapper;
    @Test
    void contextLoads() {
   
        // 测试接口的查询是否正常
        accountMapper.selectList(null).forEach(System.out::println);
    }
}
  1. 创建service层,controller调用service,service调用mapper
    接口:AccountService
package com.zhou.service;

import com.zhou.entity.Account;

public interface AccountService {
   
    // 写一个接口,这个接口让它返回一个登录的操作
    // 先通过用户名去查询对象
    Account findByUserName(String username);
}

实现类先建一个impl包,AccountServiceImpl

package com.zhou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhou.entity.Account;
import com.zhou.mapper.AccountMapper;
import com.zhou.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AccountServiceImpl implements AccountService {
   
    @Autowired
    private AccountMapper accountMapper;

    @Override
    public Account findByUserName(String username) {
   
        // 通过用户名查询,需要使用QueryWrapper
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        return accountMapper.selectOne(wrapper);
    }
    // 然后测试一下这个查询名字的方法对不对,在这个接口处进行测试
}

测试

package com.zhou.service;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class AccountServiceTest {
   
    @Autowired
    private AccountService accountService;

    @Test
    void findByUsername(){
   
        System.out.println(accountService.findByUserName("ls"));
    }
}
  1. 开始写自己的逻辑,创建一个realm包,根据项目的需求,验证和授权的逻辑全部写在realm包中,自定义过滤器Shiro。

客户端传过来的用户名和密码会直接的封装到token中,先根据token中的用户名进行查询对应的对象,如果对象为null,则说明用户名错误。
如果不为null,说明用户名是正确的,所以只需要验证密码,通过SimpleAuthenticationInfo来验证密码

package com.zhou.realm;

import com.zhou.entity.Account;
import com.zhou.service.AccountService;
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.springframework.beans.factory.annotation.Autowired;

// realm用于验证和授权,验证和授权需要继承AuthorizingRealm,作者授权领域
public class AccountShiro extends AuthorizingRealm {
   
    // 把service层的东西注入进来
    @Autowired
    private AccountService accountService;
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
   
        return null;
    }

    /**
     * token则说明是验证用户和密码
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
   
        // 验证用户名和密码
        // 把AuthenticationToken转成用户名和密码的token
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        // 获取账户的名字,通过名字查询
        Account account = accountService.findByUserName(usernamePasswordToken.getUsername());
        // 判断对象是否为空
        if(account != null){
   
            // 验证密码
            return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
        }
        // 为空的话,直接返回null即可
        return null;
    }
}
  1. 配置Shiro。创建Config包,ShiroConfig类
package com.zhou.config;

import com.zhou.entity.Account;
import com.zhou.realm.AccountRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值