最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot 整合shiro實(shí)現(xiàn)權(quán)限控制的方法

 更新時(shí)間:2020年11月02日 10:02:40   作者:只寫有用的blog  
這篇文章主要介紹了Springboot 整合shiro實(shí)現(xiàn)權(quán)限控制的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Author:jeffrey

Date:2019-04-08

一、開發(fā)環(huán)境:

1、mysql - 5.7
2、navicat(mysql客戶端管理工具)
3、idea 2017.2
4、jdk8
5、tomcat 8.5
6、springboot2.1.3
7、mybatis 3
8、shiro1.4
9、maven3.3.9

二、數(shù)據(jù)庫(kù)設(shè)計(jì)

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-CB46ByC1-1604249108144)(img/shiro01.png)]

三、創(chuàng)建springboot項(xiàng)目

 3.1 添加組件

添加 web、lombok、thymeleaf、jdbc、mysql、mybatis等模塊;

3.2 pom.xml

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.4.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
	
	<dependencies>
		<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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.1</version>
		</dependency>
		<!--配置shiro依賴包-->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		<!--配置數(shù)據(jù)庫(kù)連接池依賴-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.26</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<!--配置lombok插件-->
		<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>
	</dependencies>

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

3.3 創(chuàng)建項(xiàng)目包結(jié)構(gòu)

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-NNuns5Pt-1604249108145)(img/shiro02.png)]

3.4 配置初始化文件application.yml

#配置服務(wù)端口號(hào)
server:
 port: 8080
#配置數(shù)據(jù)源
spring:
 datasource:
 type: com.alibaba.druid.pool.DruidDataSource
 driver-class-name: com.mysql.jdbc.Driver
 url: jdbc:mysql://localhost:3306/my_shiro?useUnicode=true&characterEncoding=utf-8
 username: root
 password: 59852369
#配置mybatis
mybatis:
 mapper-locations: classpath:mapper/*.xml
 type-aliases-package: com.qf.domain.pojo

四、程序設(shè)計(jì)開發(fā)

4.1 實(shí)體類開發(fā)

​ SysUser.java

package com.qf.domain;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;
/**
 * Created by 54110 on 2019-07-05.
 */
@Data
public class SysUser implements Serializable {
 private int userId;//用戶id
 private String loginName;//登錄名
 private String password;//
 private Integer state;
 private Date createTime;
 private String realname;

}

SysPermission.java

package com.qf.domain;

import lombok.Data;

import java.io.Serializable;

/**
 * Created by 54110 on 2019-07-05.
 */
@Data
public class SysPermission implements Serializable {
 private int permId;
 private String permName;//權(quán)限名稱
 private String permUrl;//權(quán)限操作地址(路徑)
 private String menuName;//菜單名
 private String menuLevel;//菜單級(jí)別(11:一級(jí);12:二級(jí)。。。)
 private String menuCode;//菜單編碼(每級(jí)兩位數(shù)字)
 private int ifValid;
 private String parentCode;
}

4.2 數(shù)據(jù)訪問(wèn)層接口開發(fā)

SysUserMapper.java

package com.qf.mapper;

import com.qf.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;

/**
 * Created by 54110 on 2019-07-05.
 */
@Mapper
public interface SysUserMapper {
 public SysUser findUserByUsername(String username);
}

SysPermissionMapper

package com.qf.mapper;

import com.qf.domain.SysPermission;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * Created by 54110 on 2019-07-05.
 */
@Mapper
public interface SysPermissionMapper {
 //	根據(jù)用戶登錄名查詢其所擁有的權(quán)限
 public List<SysPermission> findPermissionsByLoginName(String loginName);
}

4.3 Mybatis映射開發(fā)

SysUsersMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qf.mapper.SysUserMapper">
 <resultMap type="com.qf.domain.SysUser" id="userMap">
  <id column="USERID" property="userid" />
  <result column="LOGIN_NAME" property="loginName" />
  <result column="PASSWORD" property="password" />
  <result column="STATE" property="state" />
  <result column="CREATE_TIME" property="createTime" />
  <result column="REALNAME" property="realname" />
 </resultMap>

 <sql id="tbusers_columns">
  PASSWORD,LOGIN_NAME,CREATE_TIME,REALNAME,STATE
 </sql>
 <!--根據(jù)用戶名查詢對(duì)象 -->
 <select id="findUserByUsername" parameterType="string" resultMap="userMap">
  SELECT
  <include refid="tbusers_columns"></include>
  FROM
  TB_SYS_USER US
  WHERE
  US.LOGIN_NAME = #{name}
 </select>
</mapper>

SysPermissionMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qf.mapper.SysPermissionMapper">
 <resultMap type="com.qf.domain.SysPermission" id="permMap">
  <id column="PERMISSION_ID" property="permId" />
  <result column="PER_NAME" property="permName" />
  <result column="MENU_URL" property="permUrl" />
  <result column="MENU_NAME" property="menuName" />
  <result column="MENU_TYPE" property="menuLevel" />
  <result column="MENU_CODE" property="menuCode" />
  <result column="PARENT_CODE" property="parentCode" />
  <result column="IF_ViLID" property="ifValid" />

 </resultMap>

 <select id="findPermissionsByLoginName" parameterType="string" resultMap="permMap">

  SELECT
  p.*
  FROM
  TB_SYS_USER us ,
  TB_USER_ROLE ur,
  TB_SYS_ROLE r,
  TB_ROLE_PERMISSION rp,
  TB_SYS_PERMISSION p
  WHERE
  us.USERID = ur.USER_ID AND ur.ROLE_ID = r.ROLE_ID
  AND r.ROLE_ID = rp.ROLE_ID AND rp.PERMISSION_ID = p.PERMISSION_ID
  AND trim(us.LOGIN_NAME) = #{loginName}
  ORDER BY p.MENU_CODE

 </select>
</mapper>

4.4 業(yè)務(wù)層開發(fā)

SysUsersServiceImpl.java

package com.qf.service.impl;

import com.qf.domain.SysUser;
import com.qf.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created by 54110 on 2019-07-05.
 */
@Service
public class SysUsersServiceImpl {

  @Autowired
  private SysUserMapper userMapper;
  
  public SysUser queryUserByLoginName(String loginName) {

   SysUser tbUsers = userMapper.findUserByUsername(loginName);
   return tbUsers;
  }

}

​SysPermissionServiceImpl.java

package com.qf.service.impl;

import com.qf.domain.SysPermission;
import com.qf.mapper.SysPermissionMapper;
import com.qf.service.SysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by 54110 on 2019-07-05.
 */
@Service
public class SysPermissionServiceImpl implements SysPermissionService {

 @Autowired
 private SysPermissionMapper permMapper;
 @Override
 public List<SysPermission> queryPermissionsByLoginName(String loginName) {
  List<SysPermission> list = permMapper.findPermissionsByLoginName(loginName);
  return list;
 }

}

4.5 控制層接口開發(fā)

UserController.java

package com.qf.controller;

import com.qf.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

/**
 * Created by 54110 on 2019-07-05.
 */
@Controller
public class UserController {
 @Autowired
 private SysUserService userService;
 // 登錄頁(yè)(view)展示
 @RequestMapping("/login")
 public String showlogin(){
  return "login";
 }

 /**
  * 登錄處理
  * @param map 用戶登錄表單數(shù)據(jù)
  * @return 邏輯視圖
  */
 @RequestMapping(value="dealLogin" ,method= RequestMethod.POST)
 public String dealLogin(@RequestParam Map<String,Object> map){
  System.out.println( map.values().toString());

  try {
   Subject subject = SecurityUtils.getSubject();//從安全管理器中獲取主體對(duì)象
   UsernamePasswordToken token = new UsernamePasswordToken();//構(gòu)建令牌對(duì)象
   token.setUsername(map.get("name").toString());//賦身份信息
   token.setPassword(map.get("password").toString().toCharArray());//賦憑證信息
   subject.login(token);//使用主體的login方法判定用戶的權(quán)限
   if(subject.isAuthenticated()){
    //  已登陸
    //  用戶信息及權(quán)限信息的存儲(chǔ)(session|| redis)
    return "main";
   }
  } catch (AuthenticationException e) {
   e.printStackTrace();
   System.out.println("登錄失敗");
  }
  return "login";
 }
 // 登錄且擁有user:
 @RequestMapping("/one")
 public String showCaseOne(){
  return "one";
 }
 @RequestMapping("/two")
 public String showCaseTwo(){
  return "two";
 }
 // 權(quán)限不足時(shí),響應(yīng)的頁(yè)面
 @RequestMapping("/unauth")
 public String showPermission(){
  return "unauth";
 }
 // 用戶注銷操作
 @RequestMapping("/logout")
 public String logout(){
  Subject subject = SecurityUtils.getSubject();
  subject.logout();//登出
  return "redirect:login";
 }
}

4.6 關(guān)于shiro的開發(fā)

a、自定義安全策略

MyShiroRealm.java

package com.qf.shiro;

import com.qf.domain.SysPermission;
import com.qf.domain.SysUser;
import com.qf.service.SysPermissionService;
import com.qf.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;

/**
 * Created by 54110 on 2019-07-05.
 */
public class MyShiroRealm extends AuthorizingRealm {
 @Autowired
 private SysUserService sysUserServiceImpl;
 @Autowired
 private SysPermissionService sysPermissionServiceImpl;
 private String username;

 // 系統(tǒng)授權(quán)
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  Subject subject = SecurityUtils.getSubject();//獲取主體對(duì)象
  String username =(String ) subject.getPrincipal();//獲取用戶身份信息
  List<SysPermission> permissions = sysPermissionService.queryPermissionsByLoginName(username);//根據(jù)用戶名獲取用戶的權(quán)限信息
//  權(quán)限去重
  Collection<String > perms = new HashSet<>();
  for (SysPermission perm: permissions ) {
   perms.add(perm.getPermName());
  }
  SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
  simpleAuthorizationInfo.addStringPermissions(perms);//授權(quán)
  return simpleAuthorizationInfo;
 }
 //用戶認(rèn)證
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  String username = (String) token.getPrincipal();//獲取用戶信息

  //根據(jù)用戶信息查詢數(shù)據(jù)庫(kù)獲取后端的用戶身份,轉(zhuǎn)交給securityManager判定
  SysUser user1 = sysUserService.queryUserByLoginName(username);//從數(shù)據(jù)庫(kù)直接取
  System.out.println(user1);
  if(user1!=null) {
   SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user1.getLoginName(), user1.getPassword(), getName());
   return simpleAuthenticationInfo;
  }
  return null;
 }
}

b、自定義Shiro配置管理

ShiroConfig.java

package com.qf.config;

import com.qf.shiro.MyShiroRealm;
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.HashMap;
import java.util.Map;

/**
 * Created by 54110 on 2019-07-05.
 */
@Configuration
public class ShiroConfig {

 @Bean
 public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
  ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
  Map<String ,String> map = new HashMap<>();
  map.put("/main","authc"); //必須登錄才可訪問(wèn)
  map.put("/one","perms[user_edit]");//只有特定權(quán)限(“user_edit”)的用戶登錄后才可訪問(wèn)
  map.put("/two","perms[user_forbidden]");//只有特定權(quán)限(“user_forbidden”)的用戶登錄后才可訪問(wèn)
  shiroFilterFactoryBean.setLoginUrl("/login");//設(shè)置登錄頁(yè)(匿名)
  shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");//權(quán)限不足的錯(cuò)誤提示頁(yè)
  shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//裝配攔截策略
  return shiroFilterFactoryBean;
 }
 // 配置安全管理器(注入Realm對(duì)象)
 @Bean(name="defaultWebSecurityManager")
 public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("myShiroRealm") MyShiroRealm myShiroRealm){
  DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
  defaultWebSecurityManager.setRealm(myShiroRealm);
  return defaultWebSecurityManager;
 }

 @Bean(name="myShiroRealm") //使用該注解是的Realm對(duì)象由spring容器管理
 public MyShiroRealm myShiroRealm(){
  MyShiroRealm shiroRealm = new MyShiroRealm();
  return shiroRealm;
 }
}

五、功能測(cè)試

​ 地址欄輸入http://localhost:8080/login

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-BdyHhsoT-1604249108147)(img\shiro03.png)]

​ 使用用戶:admin密碼:admin登錄,登錄成功后顯示頁(yè)面如下:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-LdoaSOGM-1604249108149)(img/shiro04.png)]

​ 因?yàn)閍dmin2用戶擁有case one功能的操作權(quán)限,所以當(dāng)鼠標(biāo)單擊case one鏈接時(shí),顯示如下成功訪問(wèn)頁(yè)面

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-Co1rUWJi-1604249108150)(img/shiro05.png)]

因?yàn)閍dmin2沒(méi)有case two訪問(wèn)權(quán)限,當(dāng)用戶單擊case two時(shí),會(huì)顯示無(wú)權(quán)限訪問(wèn)的頁(yè)面:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-geha4PCi-1604249108150)(img/shiro06.png)]

當(dāng)單擊logout鏈接時(shí),系統(tǒng)重回登錄頁(yè)。此時(shí)使用用戶test2密碼test2再次登錄。因test2用戶無(wú)case one權(quán)限,有case two權(quán)限,所以當(dāng)test2用戶單擊case two時(shí)會(huì)顯示如下頁(yè)面:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-AWZrOeGj-1604249108151)(img/shiro07.png)]

六、啟動(dòng)shiro注解模式

6.1、在ShiroConfig.java中注釋掉原先使用路徑過(guò)濾的權(quán)限攔截語(yǔ)句:

//只有特定權(quán)限(“user_edit”)的用戶登錄后才可訪問(wèn)
// map.put("/one","perms[user_edit]");
//只有特定權(quán)限(“user_forbidden”)的用戶登錄后才可訪問(wèn)
// map.put("/two","perms[user_forbidden]");

6.2、修改ShiroConfig.java類代碼添加如下內(nèi)容:

/**
  * 開啟Shiro注解(如@RequiresRoles,@RequiresPermissions),
  * 需借助SpringAOP掃描使用Shiro注解的類,并在必要時(shí)進(jìn)行安全邏輯驗(yàn)證
  * 配置以下兩個(gè)bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)
  */
 @Bean
 public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
  DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
  advisorAutoProxyCreator.setProxyTargetClass(true);
  return advisorAutoProxyCreator;
 }
 /**
  * 開啟aop注解支持
  */
 @Bean
 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) {
  AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager);
  return authorizationAttributeSourceAdvisor;
 }

6.3、修改UserController.java控制器接口代碼:

// 登錄且擁有user:
 @RequiresPermissions(value={"user_edit"})
 @RequestMapping("/one")
 public String showCaseOne(){
  return "one";
 }
 @RequiresPermissions(value={"user_forbidden"})
 @RequestMapping("/two")
 public String showCaseTwo(){
  return "two";
 }

6.4、測(cè)試

此事有權(quán)限訪問(wèn)的也頁(yè)面正常,但未授權(quán)的頁(yè)面,無(wú)法進(jìn)入提示頁(yè),顯示如下:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-pM9lRu2Z-1604249108152)(img/shiro08.png)]

​ 后臺(tái)亦拋出org.apache.shiro.authz.AuthorizationException異常:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-k8KTUuoi-1604249108152)(img/shiro09.png)]

6.5、此時(shí)使用aop攔截拋出的異常

package com.jeffrey.exception;

import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by jeffrey on 2019/4/8.
 */
@ControllerAdvice
public class ExceptionController {

 @ExceptionHandler(value = UnauthorizedException.class)//處理訪問(wèn)方法時(shí)權(quán)限不足問(wèn)題
 public String defaultErrorHandler(HttpServletRequest req, Exception e) {
  return "unauth";
 }
}

七、shiro密碼的MD5加密處理

 7.1.密碼的加密

在數(shù)據(jù)表中存的密碼不應(yīng)該是12345,而應(yīng)該是12345加密之后的字符串,而且還要求這個(gè)加密算法是不可逆的,即由加密后的字符串不能反推回來(lái)原來(lái)的密碼,如果能反推回來(lái)那這個(gè)加密是沒(méi)有意義的。

著名的加密算法,比如 MD5,SHA1

7.2.MD5加密

1). 如何把一個(gè)字符串加密為MD5

2). 使用MD5加密算法后,前臺(tái)用戶輸入的字符串如何使用MD5加密,需要做的是將當(dāng)前的Realm 的credentialsMatcher屬性,替換為Md5CredentialsMatcher 由于Md5CredentialsMatcher已經(jīng)過(guò)期了,推薦使用HashedCredentialsMatcher 并設(shè)置加密算法即可。

7.3.使用MD5加密

1). 修改ShiroConfig.java文件添加如下內(nèi)容;

 /**
  * 密碼校驗(yàn)規(guī)則HashedCredentialsMatcher
  * 這個(gè)類是為了對(duì)密碼進(jìn)行編碼的 ,
  * 防止密碼在數(shù)據(jù)庫(kù)里明碼保存 , 當(dāng)然在登陸認(rèn)證的時(shí)候 ,
  * 這個(gè)類也負(fù)責(zé)對(duì)form里輸入的密碼進(jìn)行編碼
  * 處理認(rèn)證匹配處理器:如果自定義需要實(shí)現(xiàn)繼承HashedCredentialsMatcher
  */
 @Bean("hashedCredentialsMatcher")
 public HashedCredentialsMatcher hashedCredentialsMatcher() {
  HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
  //指定加密方式為MD5
  credentialsMatcher.setHashAlgorithmName("MD5");
  //加密次數(shù)
  credentialsMatcher.setHashIterations(1024);
  credentialsMatcher.setStoredCredentialsHexEncoded(true);
  return credentialsMatcher;
 }
 @Bean("myShiroRealm")
 public MyShiroRealm myShiroRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher matcher) {
  MyShiroRealm authRealm = new MyShiroRealm();
  authRealm.setAuthorizationCachingEnabled(false);
  authRealm.setCredentialsMatcher(matcher);
  return authRealm;
 }

​ 2).修改MyRealm.java的認(rèn)證邏輯如下:

//用戶認(rèn)證
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  String username = (String) token.getPrincipal();//獲取用戶信息

  SysUser user1 = sysUserService.queryUserByLoginName(username);//從數(shù)據(jù)庫(kù)直接取
  System.out.println(user1);
  if(user1!=null) {
   //當(dāng)前realm對(duì)象的name
   String realmName = getName();
   //鹽值
   ByteSource credentialsSalt = ByteSource.Util.bytes(username);
   //封裝用戶信息,構(gòu)建AuthenticationInfo對(duì)象并返回
   AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(username, user1.getPassword(), credentialsSalt, realmName);
   return authcInfo;

  }
  return null;
 }

​ 3). 通過(guò) new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 我們可以得到"12345"經(jīng)過(guò)MD5 加密1024后的字符串;

package com.jeffrey;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

/**
 * Created by jeffrey on 2019/4/8.
 */
public class MD5Salt {

 public static void main(String[] args){
  String hashAlgorithName = "MD5";//加密算法
  String password = "12345";//登陸時(shí)的密碼
  int hashIterations =1024;//加密次數(shù)
  ByteSource credentialsSalt = ByteSource.Util.bytes("admin2");//使用登錄名做為salt
  SimpleHash simpleHash = new SimpleHash(hashAlgorithName, password, credentialsSalt, hashIterations);
  System.out.println("ok "+simpleHash);
 }

}

​ 使用密文替換數(shù)據(jù)庫(kù)中的明文密碼;

7.4 測(cè)試 略。。。。

7.5 后記 為什么使用 MD5 鹽值加密: 希望即使兩個(gè)原始密碼相同,加密得到的兩個(gè)字符串也不同。

為什么使用 MD5 鹽值加密:
希望即使兩個(gè)原始密碼相同,加密得到的兩個(gè)字符串也不同。
如何做到:
1). 在 doGetAuthenticationInfo 方法返回值創(chuàng)建 SimpleAuthenticationInfo 對(duì)象的時(shí)候, 需要使用SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName) 構(gòu)造器
2). 使用 ByteSource.Util.bytes() 來(lái)計(jì)算鹽值.
3). 鹽值需要唯一: 一般使用隨機(jī)字符串或 user id
4). 使用 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 來(lái)計(jì)算鹽值加密后的密碼的值.

到此這篇關(guān)于Springboot 整合shiro實(shí)現(xiàn)權(quán)限控制的文章就介紹到這了,更多相關(guān)Springboot權(quán)限控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java如何獲取一個(gè)IP段內(nèi)的所有IP地址

    Java如何獲取一個(gè)IP段內(nèi)的所有IP地址

    這篇文章主要為大家詳細(xì)介紹了Java如何根據(jù)起始和結(jié)束的IP地址獲取IP段內(nèi)所有IP地址,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • logback自定義json日志輸出示例詳解

    logback自定義json日志輸出示例詳解

    這篇文章主要為大家介紹了logback自定義json日志輸出,就是通過(guò)logback日志體系以及l(fā)ogstash提供的json?log依賴將數(shù)據(jù)以json格式記錄到日志文件的例子
    2022-03-03
  • JAVA異常分類和處理解析

    JAVA異常分類和處理解析

    這篇文章主要介紹了JAVA異常分類和處理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • SpringMVC框架REST架構(gòu)體系原理分析

    SpringMVC框架REST架構(gòu)體系原理分析

    REST:Representational State Transfer,資源表現(xiàn)層狀態(tài)轉(zhuǎn)換,是目前&#12112;較主流的&#12032;種互聯(lián)網(wǎng)軟件架構(gòu),它結(jié)構(gòu)清晰、標(biāo)準(zhǔn)規(guī)范、易于理解、便于擴(kuò)展
    2021-09-09
  • Java基于二叉查找樹實(shí)現(xiàn)排序功能示例

    Java基于二叉查找樹實(shí)現(xiàn)排序功能示例

    這篇文章主要介紹了Java基于二叉查找樹實(shí)現(xiàn)排序功能,結(jié)合實(shí)例形式分析了Java二叉查找樹的定義、遍歷及排序等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Spring Security實(shí)現(xiàn)多次登錄失敗后賬戶鎖定功能

    Spring Security實(shí)現(xiàn)多次登錄失敗后賬戶鎖定功能

    當(dāng)用戶多次登錄失敗的時(shí)候,我們應(yīng)該將賬戶鎖定,等待一定的時(shí)間之后才能再次進(jìn)行登錄操作。今天小編給大家分享Spring Security實(shí)現(xiàn)多次登錄失敗后賬戶鎖定功能,感興趣的朋友一起看看吧
    2019-11-11
  • 淺談java中的一維數(shù)組、二維數(shù)組、三維數(shù)組、多維數(shù)組

    淺談java中的一維數(shù)組、二維數(shù)組、三維數(shù)組、多維數(shù)組

    下面小編就為大家?guī)?lái)一篇淺談java中的一維數(shù)組、二維數(shù)組、三維數(shù)組、多維數(shù)組。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • springboot pojo對(duì)象日期屬性的問(wèn)題

    springboot pojo對(duì)象日期屬性的問(wèn)題

    這篇文章主要介紹了springboot pojo對(duì)象日期屬性的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java警告:源發(fā)行版17 需要目標(biāo)發(fā)行版17問(wèn)題及解決

    java警告:源發(fā)行版17 需要目標(biāo)發(fā)行版17問(wèn)題及解決

    文章介紹了如何解決項(xiàng)目JDK版本不一致的問(wèn)題,包括修改Project Structure、Modules、Dependencies和Settings中的JDK版本,以及在pom.xml中指定JDK源版本
    2024-11-11
  • 老生常談JVM的內(nèi)存溢出說(shuō)明及參數(shù)調(diào)整

    老生常談JVM的內(nèi)存溢出說(shuō)明及參數(shù)調(diào)整

    下面小編就為大家?guī)?lái)一篇老生常談JVM的內(nèi)存溢出說(shuō)明及參數(shù)調(diào)整。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03

最新評(píng)論

浑源县| 冀州市| 霍邱县| 修文县| 周至县| 万源市| 田东县| 湘潭县| 丰顺县| 平湖市| 郑州市| 胶南市| 汾西县| 应用必备| 奉节县| 福泉市| 东明县| 湖州市| 平罗县| 灵武市| 海南省| 射洪县| 黑河市| 专栏| 宁都县| 那坡县| 阿图什市| 方正县| 安仁县| 革吉县| 兴隆县| 东阳市| 泰安市| 江永县| 漳州市| 海丰县| 龙南县| 赤壁市| 黑山县| 开鲁县| 达拉特旗|