Springboot+shiro+md5(配置類配置)


一.導入依賴包

 <!--spring boot 默認lettuce連接redis的技術-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--郵件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <!--jdbc依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--前端模板引擎依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--springmvc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>

        <!--mybatis依賴-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

        <!--熱部署依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--mysql數據庫依賴-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--簡化實體類依賴(set/get)-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--單元測試依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 分頁插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

        <!-- SpringBoot - MyBatis 逆向工程 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--EXCEL-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>net.oschina.likaixuan</groupId>
            <artifactId>excelutil</artifactId>
            <version>2.0.2</version>
        </dependency>

        <!--對象池-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <!--連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.0</version>
        </dependency>

        <!-- fastjson阿里巴巴jSON處理器 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.13</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.4.0</version>
        </dependency>

        <!--thymeleaf對shiro擴展的依賴-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!--jedis依賴包-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

        <!--redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.5.4</version>
        </dependency>

        <!-- shiro+redis緩存插件 -->
        <dependency>
            <groupId>org.crazycake</groupId>
            <artifactId>shiro-redis</artifactId>
            <version>2.4.2.1-RELEASE</version>
        </dependency>

       <!-- 整合jsp所需依賴,要是添加了thymeleaf似乎會出問題-->
        <!--<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>-->

        <!--jstl-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        
View Code

二.添加配置

#tomcat啟動端口
server.port=9090
#server.servlet.context-path=/

#自動重啟
spring.devtools.restart.enabled=true
#添加額外監聽的路徑
#spring.devtools.restart.additional-paths=src/main/
#添加忽略目錄(排除的路徑)
#spring.devtools.restart.exclude=/excludepath/

#實時刷新(通知瀏覽器實時刷新,要下插件)
spring.devtools.livereload.enabled=true

#mysql配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://xx.xx.xx.xx:3306/xxx?useUnicode=true&characterEncoding=utf8
spring.datasource.username = xxx
spring.datasource.password = xxxx
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10

#mybatis
#把數據庫字段的下划線轉換成實體類中的駝峰式命名
mybatis.configuration.map-underscore-to-camel-case=true

#mybatis表映射文件目錄
mybatis.mapper-locations=classpath:mapper/*.xml

#springmvc
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp


#配置分頁插件pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params.count=countSql

#禁用thymeleaf緩存
spring.thymeleaf.cache=false


#配置連接池
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#druid監控配置
spring.datasource.filters=stat,wall,log4j
spring.datasource.dbcp2.min-idle=5
#初始化提供的連接數
spring.datasource.dbcp2.initial-size=5
#最大的連接數
spring.datasource.dbcp2.max-total=5
#等待連接獲取的最大超時時間
spring.datasource.dbcp2.max-wait-millis=200




##rabbitMQ
#spring.rabbitmq.host=xx.xx.xx.xx
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=user
#spring.rabbitmq.password=user

##redis
#spring.redis.host=xx.xx.xx.xx
#spring.redis.port=6379
#spring.redis.password=xxx
#spring.redis.timeout=1000ms
##lettuce最大連接數
#spring.redis.lettuce.pool.max-active=8
##連接池最大阻塞時間(-1表示沒有限制
#spring.redis.lettuce.pool.max-wait=-1ms
##最大空閑連接
#spring.redis.lettuce.pool.max-idle=8
##最小空閑連接
#spring.redis.lettuce.pool.min-idle=0
#
#logging.level.com.seecen=debug
View Code

由於springboot還沒集成shiro的properties所以要添加配置類,配置類如下(添加配置類之前最好先自定義Realm)

自定義Realm

package com.taotao.shiro;

import com.taotao.pojo.User;
import com.taotao.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.crypto.hash.Md5Hash;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * Author: TaoTao  2019/9/14
 */
@Component
public class UserRealm  extends AuthorizingRealm {
    private static Logger logger = LoggerFactory.getLogger(UserRealm.class);
    @Autowired
    private UserService userService;

    /**
     * 驗證身份信息
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        /**
         * 驗證用戶名步驟
         * 1.獲取令牌中的用戶名
         * 2.根據用戶名去查詢是否有該用戶
         *      a.有用戶存在
         *      b.沒有,直接拋出異常
         * 3.返回一個驗證用戶名和密碼的類對象(封裝了md5加密的驗證方式)
         */
        logger.info("---------------- 執行 Shiro 憑證認證 ----------------------");
        String name = (String) token.getPrincipal();
        // 從數據庫獲取對應用戶名密碼的用戶
        User userInfo = userService.findUserByNames(name);
        if (userInfo != null) {
            // 用戶為禁用狀態
            if (userInfo.getuState() != 0) {
                throw new DisabledAccountException("賬戶已被禁用!");
            }
            logger.info("---------------- Shiro 憑證認證成功 ----------------------");
            //md5加密再加鹽
            //根據表單數據和加密字符串和鹽值進行比較驗證
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    name, //用戶
                    userInfo.getuPwd(), //密碼
                    ByteSource.Util.bytes(userInfo.getuSal()),//鹽值
                    getName()  //realm name
            );
            // 返回給安全管理器,由 securityManager 比對密碼的正確性
            return authenticationInfo;
        }
        throw new UnknownAccountException();
    }

    /**
     * 獲取操作權限
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.info("---------------- 執行 Shiro 權限獲取 ---------------------");
        //給資源進行授權
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //到數據庫查詢當前登錄用戶的授權字符串
        //獲取當前登錄用戶
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
//        User dbUser = userService.find
        info.addStringPermission(null);
        logger.info("---------------- Shiro 權限獲取成功 ----------------------");
        return info;
      /*  String username = (String) principals.getPrimaryPrincipal();
        //持久化操作:根據用戶名獲取角色信息和權限信息
        //role: admin manage    perms:user:create user :update  模塊:權限
        Set<String> permissionList = new HashSet<>();
        permissionList.add("user:list");
        permissionList.add("user:create");
        permissionList.add("user:update");
        Set<String> roleList = new HashSet<>();
        roleList.add("admin");
        roleList.add("manager");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roleList);
        authorizationInfo.setStringPermissions(permissionList);
        return authorizationInfo;*/

        }

    }

}

添加配置

package com.taotao.shiro;

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;

/**
 * Author: TaoTao  2019/9/18
 */
@Configuration
public class ShiroConfig {

    /**
     * Filter工廠
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
        //設置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String,String> filterMap = new LinkedHashMap<String, String>();
        filterMap.put("/user/login","anon"); //指定路徑放行
        filterMap.put("/user/loginVer","anon");

        //設置為登錄跳轉的頁面
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        //設置未授權跳轉頁面
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/noAuth");
        //授權過濾
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 密碼校驗規則HashedCredentialsMatcher
     * 這個類是為了對密碼進行編碼的 ,
     * 防止密碼在數據庫里明碼保存 , 當然在登陸認證的時候 ,
     * 這個類也負責對form里輸入的密碼進行編碼
     * 處理認證匹配處理器:如果自定義需要實現繼承HashedCredentialsMatcher
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 使用md5 算法進行加密
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        // 設置散列次數: 加密次數(這個地方沒有鹽值也不會影響密碼對比)
        hashedCredentialsMatcher.setHashIterations(3);
        return hashedCredentialsMatcher;
    }


    /**
     * 自定義Realm
     */
    @Bean(name="userRealms")
    public UserRealm getRealm(){
        UserRealm userRealm = new UserRealm();
        //配置加密方式(不然登錄失敗)
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return userRealm;
    }

    /**
     * 安全管家
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealms") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //關聯realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


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



}

 

MD5加密加鹽

    public static void main(String[] args) {
        //第一:把用戶的密碼通過md5算法加密 
        String password = "uuu";
//        String md5String = new Md5Hash(password).toString();//不可逆加密算法
//        System.out.println("原密碼:"+password);
//        System.out.println("md5加密的密碼:"+md5String);
//        //注冊,保存加密后的值
//        //登錄驗證  把表單值動態加密再進行比較uuu
//        //第二種:加密同時加點鹽
//        md5String = new Md5Hash(password,"abc").toString();
//        System.out.println("md5加密且加鹽后的密碼:"+md5String);

        //第三種:加密次數 增加破解成本
        String md5String;
        md5String = new Md5Hash("aaa","9734983ae2c939da48d8bc738d34ffb2",3).toString();
        System.out.println("md5加密且加鹽,還加加密次數后的密碼:"+md5String);

//        //第四種:隨機鹽值,配合加密次數
////        String sal = getRandomString();
//        md5String = new Md5Hash(password,"abc",3).toString();
//        System.out.println("md5加密且隨機顏值,還加加密次數后的密碼:"+md5String);

 

總結

在搭建和權限這塊基本沒什么問題,我所出現的問題是,將密碼加密存入數據庫后,用戶登入失敗,在查詢資料后發現沒有添加 HashedCredentialsMatcher 配置,

然后一直在糾結數據庫中的密碼使用了鹽值進行加密,然后HashedCredentialsMatcher 中並沒有添加鹽值,而且在該配置類中修改加密次數也可以登入成功(難道這個配置只是在說我加密了哦,求大佬指點)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM