溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Springboot快速整合shiro安全框架

發(fā)布時間:2023-04-03 16:04:50 來源:億速云 閱讀:149 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“怎么用Springboot快速整合shiro安全框架”,在日常操作中,相信很多人在怎么用Springboot快速整合shiro安全框架問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用Springboot快速整合shiro安全框架”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

咱們先來普及一下什么是shiro,shiro原名Apache Shiro 是一個Java 的安全(權(quán)限)框架。Shiro 可以非常容易的開發(fā)出足夠好的應用,其不僅可以用在JavaSE環(huán)境,也可以用在JavaEE環(huán)境。Shiro可以完成,認證,授權(quán),加密,會話管理,Web集成,緩存等高級應用。如圖看shiro的功能和架構(gòu)圖:

怎么用Springboot快速整合shiro安全框架

怎么用Springboot快速整合shiro安全框架

話不多說,Springboot整合shiro,咱們直接上代碼

pom.xml文件

<?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.6.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo02</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo02</name>
    <description>demo02</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
           <version>8.0.31</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
           <version>1.18.18</version>
            <scope>compile</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <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>

        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

然后我們建立一個數(shù)據(jù)庫 /*
Navicat MySQL Data Transfer

Source Server :
Source Server Version : 80030
Source Host : localhost:3306
Source Database : mybatis

Target Server Type : MYSQL
Target Server Version : 80030
File Encoding : 65001

Date: 2023-03-14 18:00:05
*/

SET FOREIGN_KEY_CHECKS=0;

&ndash; Table structure for user

DROP TABLE IF EXISTS user;
CREATE TABLE user (
id int NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
pwd varchar(255) DEFAULT NULL,
perms varchar(100) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

&ndash; Records of user

INSERT INTO user VALUES (&lsquo;1&rsquo;, &lsquo;qin&rsquo;, &lsquo;d1b129656359e35e95ebd56a63d7b9e0&rsquo;, &lsquo;user:add&rsquo;);
INSERT INTO user VALUES (&lsquo;2&rsquo;, &lsquo;hai&rsquo;, &lsquo;123&rsquo;, &lsquo;user:insert&rsquo;);
INSERT INTO user VALUES (&lsquo;3&rsquo;, &lsquo;root&rsquo;, &lsquo;d1b129656359e35e95ebd56a63d7b9e0&rsquo;, &lsquo;user:update&rsquo;);

application.yml文件

spring:
   datasource:
      username: xxxx
      password: xxxxxxxxxxxx
      url: jdbc:mysql://localhost:3306/mybatis
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
mybatis:
   mapper-locations: classpath:mapper/*tat.slowSqlMillis=500

controller層MyController類

package com.example.demo02.controller;

import lombok.extern.slf4j.Slf4j;
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;

@Controller
@Slf4j
public class MyController {

    @RequestMapping("/")
    public  String toIndex(Model model){
        model.addAttribute("msg","hello,shiro");
        return "login";

    }


    @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("/noauth")
    @ResponseBody
    public String noAuth(){
        return "未經(jīng)授權(quán)不能訪問此頁面";
    }

    //登錄操作
    @RequestMapping("/login")
    public String login(String username, String password, @RequestParam(defaultValue = "false")boolean rememberMe,Model model){
//使用shiro,編寫認證操作
//1. 獲取Subject
        Subject subject = SecurityUtils.getSubject();
//2. 封裝用戶的數(shù)據(jù)
        UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
//3. 執(zhí)行登錄的方法,只要沒有異常就代表登錄成功!
        try {
            subject.login(token); //登錄成功!返回首頁
            System.out.println("輸出認證成功跳轉(zhuǎn)頁面");


            return "index";
        } catch (UnknownAccountException e) { //用戶名不存在
            model.addAttribute("msg","用戶名不存在");
            return "login";
        } catch (IncorrectCredentialsException e) { //密碼錯誤
            model.addAttribute("msg","密碼錯誤");
            return "login";
        }
    }
}

pojo層User

package com.example.demo02.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
    private String perms;
}

config層配置兩個類
第一個類ShiroConfig

package com.example.demo02.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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 {
    //創(chuàng)建 ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean
    getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//設置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
/*
添加Shiro內(nèi)置過濾器,常用的有如下過濾器:
anon: 無需認證就可以訪問
authc: 必須認證才可以訪問
user: 如果使用了記住我功能就可以直接訪問
perms: 擁有某個資源權(quán)限才可以訪問
role: 擁有某個角色權(quán)限才可以訪問
*
/

 */
        //進行一個攔截
    Map<String,String> filterMap = new LinkedHashMap<String, String>();
//    filterMap.put("/user/add","authc");
//    filterMap.put("/user/update","authc");
        //授權(quán)
//        filterMap.put("/user/add","perms[user:add]"); //大家記得注意順序!

        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        filterMap.put("/user/*","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);




    shiroFilterFactoryBean.setLoginUrl("/toLogin");
    //未授權(quán)頁面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");
        return shiroFilterFactoryBean;
}
    //創(chuàng)建 DefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager
    getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //2創(chuàng)建加密對象,設置相關(guān)屬性
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //2.1采用md5加密
        matcher.setHashAlgorithmName("md5");
        //2.2迭代加密次數(shù)
        matcher.setHashIterations(3);
        //3將加密對象存儲到myRealm中
        userRealm.setCredentialsMatcher(matcher);


//關(guān)聯(lián)Realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //創(chuàng)建 realm 對象
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //配置ShiroDialect:方言,用于 thymeleaf 和 shiro 標簽配合使用
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

UserRealm

package com.example.demo02.config;


import com.example.demo02.pojo.User;
import com.example.demo02.service.UserService;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

//自定義得UserRaelm
public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;
    //授權(quán)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("執(zhí)行了=》授權(quán)doGetAuthorizationInfo");
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

//        info.addStringPermission("user:update");
        info.addStringPermission("user:add");
        //拿到當前用戶登陸對象
        Subject subject= SecurityUtils.getSubject();
        User currentUser= (User) subject.getPrincipal();//拿到User對象
         info.addStringPermission(currentUser.getPerms());//設置當前用戶對象

        return info;
    }

    //執(zhí)行認證邏輯
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("執(zhí)行了=>認證邏輯AuthenticationToken");
//假設數(shù)據(jù)庫的用戶名和密碼
//        String name = "root";
//        String password = "123456";


//1.判斷用戶名
        UsernamePasswordToken userToken = (UsernamePasswordToken)token;
       //連接真實的數(shù)據(jù)庫
        User user= userService.queryUserByName(userToken.getUsername());
//
        if(user==null){
            return  null;
        }
        Subject subject = SecurityUtils.getSubject();
        subject.getSession().setAttribute("loginUser",user);


//2. 驗證密碼,我們可以使用一個AuthenticationInfo實現(xiàn)類SimpleAuthenticationInfo
// shiro會自動幫我們驗證!重點是第二個參數(shù)就是要驗證的密碼!
        return new SimpleAuthenticationInfo(user, user.getPwd(),ByteSource.Util.bytes("salt"),"");
//        if(user !=null){
//            AuthenticationInfo info = new SimpleAuthenticationInfo(
//                    token.getPrincipal(),
//                    user.getPwd(),
//                    ByteSource.Util.bytes("salt"),
//                    token.getPrincipal().toString()
//            );
//            return info;
//        }
//        return null;




    }
}

service層
先是類UserServiceImpl

package com.example.demo02.service;


import com.example.demo02.mapper.UserMapper;
import com.example.demo02.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Override
    public User queryUserByName(String name) {
        return userMapper.queryUserByName(name);
    }
}

再是接口UserService

package com.example.demo02.service;

import com.example.demo02.pojo.User;

public interface UserService {
    public User queryUserByName(String name);
}

mapper層
接口Usermapper

package com.example.demo02.mapper;

import com.example.demo02.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Repository
//@Mapper
public interface UserMapper {
    @Select("select * from user where name=#{name}")
    public User queryUserByName(@Param("name") String name);
}

再就是前端resources里面的static和templates

后端實現(xiàn)鑒權(quán)圖

怎么用Springboot快速整合shiro安全框架

存入數(shù)據(jù)庫的數(shù)據(jù)為加密文件

怎么用Springboot快速整合shiro安全框架

到此,關(guān)于“怎么用Springboot快速整合shiro安全框架”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI