springboot集成shiro简单认证、权限管理

 首先说一下shiro最关键的东西

Subject:就是当前用户(它本意并不是这样,它指的是和软件交互的任何东西,我理解就是用户)。

Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

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

Realm:Realm我的理解就是一个业务处理层,具体的认证、权限在这操作。

实际上我们写的时候 是反着来的(就像我们先写dao(Realm) 再写service(SecurityManager)就是这么个意思)

https://www.infoq.com/articles/apache-shiro/(shiro官网介绍)

----------------------------------------------------------------------------------------------------------------

springboot+shrio+mybatis+thymeleaf(

shiro-spring-boot-starter这个是集成的,boot2.5.2和shiro1.7.1有冲突,有些方法废弃了,所以用的1.7.0

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.admin</groupId>
    <artifactId>shrio</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>shrio</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.1.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-starter -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.7.0</version>
        </dependency>


        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>


        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </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>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 写shiroConfig

bean.setUnauthorizedUrl("/noAuthentication"); 这块是定义认证失败的自定义跳转

下面的1 2 3 代表我自己写的时候的顺序

Qualifier这个注解 是为了和我的1也就是realm绑定 

@RequestMapping("/noAuthentication")
    @ResponseBody
    public String noAuthentication() {
        return "未授权,请联系管理员";
    }
package com.admin.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
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 org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

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

/**
 * Created by zhl on 2021/8/18.
 */
@Configuration
public class ShrioConfig {
    //shrio filter 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
       //设置安全管理器
        bean.setSecurityManager(securityManager);
        /*
        * anon 所有人可以访问
        * authc 必须认证
        * user  '记住我'访问
        * perms 拥有某个资源的权限
        * role  拥有某个角色权限
        * */
        Map<String, String> filterMap = new LinkedHashMap<>();
        //这块和security 是有点不一样的 这边会依次判断 但是security是有一个没权限就会提示没权限
        filterMap.put("/add", "authc");
        filterMap.put("/update", "authc");

        filterMap.put("/add", "perms[1]");
        filterMap.put("/update", "perms[2]");

        bean.setFilterChainDefinitionMap(filterMap);

        //没有认证就跳到login界面
        bean.setLoginUrl("/login");
        //
        bean.setUnauthorizedUrl("/noAuthentication");
        return bean;
    }


    //manager 2
    @Bean
    public DefaultWebSecurityManager manager(@Qualifier("realm") UserRealm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联
        securityManager.setRealm(realm);
        return securityManager;
    }

    //realm 1
    @Bean
    public UserRealm realm() {
        return new UserRealm();
    }

    //整合shiro与thymeleaf
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

}

登录时要添加token注册

SecurityUtils.getSubject();  官网上的直接获取当前对象
new UsernamePasswordToken(username, password); 获取toke它会自动给你注册
subject.login(token); //根据token注册 然后就可以在UserRealm 用这个token
    @RequestMapping("/toLogin")
    public String toLogin(String username, String password) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //获取账号密码的token
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //注册
        try {
            subject.login(token);
            Session session = SecurityUtils.getSubject().getSession();
            session.setAttribute("name", username);
            return "index";
        } catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
            //model.mergeAttributes("msg", "用户名不存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
            return "login";
        }

    }

创建UserRealm在这里面要继承AuthorizingRealm并重写认证和授权

继承这两个要返回两个对应的对象。

AuthenticationInfo 是个接口你点进去看对应的实现类 我返回的就是SimpleAuthenticationInfo

(密码一般都会加salt 但是我这直接get了没加密,shiro 会自动对比)

(UsernamePasswordToken)authenticationToken; 获取controller里面的token
loginService.getUserByName(token.getUsername()); 这个就不说了查数据库
new SimpleAuthenticationInfo(user, user.getPass(),""); 我把user放进去 要在授权里查询它的权限

------------------------------------------------------------------------------------------------------------

AuthorizationInfo 开始授权
(UserCommen)subject.getPrincipal(); 获取认证的信息
zationInfo.addStringPermission(user.getRole()); 给当前用户加上对应资源访问权限
package com.admin.config;

import com.admin.pojo.UserCommen;
import com.admin.service.LoginService;
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.springframework.beans.factory.annotation.Autowired;

/**
 * Created by zhl on 2021/8/18.
 */
//自定义realm
public class UserRealm extends AuthorizingRealm {
    @Autowired
    LoginService loginService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("===============>授权");
        SimpleAuthorizationInfo zationInfo = new SimpleAuthorizationInfo();

        //zationInfo.addStringPermission("1");
        //获取当前用户对象进行权限判定
        Subject subject = SecurityUtils.getSubject();
        UserCommen user = (UserCommen)subject.getPrincipal();
        //zationInfo.addObjectPermissions();  多权限
        zationInfo.addStringPermission(user.getRole());
        return zationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("===============>认证");
        //controller 注册成功后 authenticationToken全局通用
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //取用户名密码
        UserCommen user = loginService.getUserByName(token.getUsername());
        if (user == null) {
            //UnknownAccountException
            return null;
        }

        return new SimpleAuthenticationInfo(user, user.getPass(),"");
    }
}
我数据库结构,我为了简单就写了两张表

上面代码写了 1的权限只能有新增

 

 

2的权限只能修改 

 至此简单的登录、权限就搞完了(我写的比较乱 想到哪写哪,在于我自己的理解)

我自己的git地址 https://github.com/zhuhl1996/boot_SImpleShiro.git 

https://github.com/apache/shiro.git   官网的地址里面有 很多例子 自己可以去下载上看看(包括怎么QuickStart)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhl_BeginLife

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

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

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

打赏作者

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

抵扣说明:

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

余额充值