springboot系列(十)springboot整合shiro實現登錄認證

關于shiro的概念和知識本篇不做詳細介紹,但是shiro的概念還是需要做做功課的要不無法理解它的運作原理就無法理解使用shiro;

本篇主要講解如何使用shiro實現登錄認證,下篇講解使用shiro實現權限控制

要實現shiro和springboot的整合需要以下幾大步驟:

  1. 生成用戶表
  2. 引入shiro依賴
  3. 添加shiro配置文件
  4. 添加自定義的realm
  5. 登錄操作觸發驗證
  6. 細節處理

下面我們一步步的詳細介紹:

一、生成用戶表

CREATE TABLE `sys_user` (`user_id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL COMMENT '用戶名',`password` varchar(100) DEFAULT NULL COMMENT '密碼',`salt` varchar(20) DEFAULT NULL COMMENT '',`email` varchar(100) DEFAULT NULL COMMENT '郵箱',`mobile` varchar(100) DEFAULT NULL COMMENT '手機號',`status` tinyint(4) DEFAULT NULL COMMENT '狀態  0:禁用   1:正常',`dept_id` bigint(20) DEFAULT NULL COMMENT '部門ID',`create_time` datetime DEFAULT NULL COMMENT '創建時間',PRIMARY KEY (`user_id`),UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='系統用戶';

二、引入shiro依賴

<!-- Apache shiro依賴 只需要引入本依賴 shiro-spring 會自動引入shiro-web和shiro-core依賴-->
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.3.2</version>
</dependency>        

三、添加shiro的配置文件(本篇使用的是@Configuration注解java類的方式,也可以使用xml的方式)

package com.chuhouqi.demo.shiro;import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;@Configuration
public class ShiroConfig {@Bean("sessionManager")public SessionManager sessionManager(){DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setSessionIdUrlRewritingEnabled(false);//sessionManager.setSessionIdCookieEnabled(false);return sessionManager;}@Bean("securityManager")public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(userRealm);securityManager.setSessionManager(sessionManager);return securityManager;}@Bean("shiroFilter")public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();shiroFilter.setSecurityManager(securityManager);shiroFilter.setLoginUrl("/login");shiroFilter.setSuccessUrl("/index");shiroFilter.setUnauthorizedUrl("/403");Map<String, String> filterMap = new LinkedHashMap<>();filterMap.put("/druid/**", "anon");filterMap.put("/api/**", "anon");filterMap.put("/login", "anon");filterMap.put("/registe", "anon");filterMap.put("/registe.html", "anon");filterMap.put("/**/*.css", "anon");filterMap.put("/**/*.js", "anon");// filterMap.put("/login.html", "anon");filterMap.put("/fonts/**", "anon");filterMap.put("/plugins/**", "anon");filterMap.put("/swagger/**", "anon");filterMap.put("/favicon.ico", "anon");filterMap.put("/captcha.jpg", "anon");filterMap.put("/", "anon");filterMap.put("/**", "authc");shiroFilter.setFilterChainDefinitionMap(filterMap);return shiroFilter;}@Bean("lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();proxyCreator.setProxyTargetClass(true);return proxyCreator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();advisor.setSecurityManager(securityManager);return advisor;}}

四、添加自定義的realm(實現認證和授權)

package com.chuhouqi.demo.shiro;import com.chuhouqi.demo.common.utils.ShiroUtil;
import com.chuhouqi.demo.entity.User;
import com.chuhouqi.demo.service.IUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserRealm extends AuthorizingRealm {@Autowiredprivate IUserService userService;@Override/***  權限授權*/protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}@Override/***  登錄認證*/protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//獲取用戶輸入的用戶名String username = (String) token.getPrincipal();//根據用戶名查詢用戶信息User user = userService.getUser(username);// 賬號不存在if (user == null) {throw new UnknownAccountException("賬號不存在");}// 賬號鎖定if (user.getStatus() == 0) {throw new LockedAccountException("賬號已被鎖定,請聯系管理員");}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),ByteSource.Util.bytes(user.getSalt()),getName());return info;}/*** 設置密碼比較器為HashedCredentialsMatcher* @param credentialsMatcher*/@Overridepublic void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();shaCredentialsMatcher.setHashAlgorithmName(ShiroUtil.hashAlgorithmName);shaCredentialsMatcher.setHashIterations(ShiroUtil.hashIterations);super.setCredentialsMatcher(shaCredentialsMatcher);}}

五、登錄操作觸發驗證

package com.chuhouqi.demo.controller;import com.chuhouqi.demo.common.utils.ShiroUtil;
import com.chuhouqi.demo.entity.User;
import com.chuhouqi.demo.service.IUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class LoginController {private static Logger logger = LoggerFactory.getLogger(LoginController.class);@Autowiredprivate IUserService userService;@GetMapping("/login")String login() {return "login";}@RequestMapping("/login")public String login(String username, String password, Model model){try {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);subject.login(token);}catch (UnknownAccountException e) {logger.error(e.getMessage());model.addAttribute("msg",e.getMessage());return "login";}catch (IncorrectCredentialsException e) {logger.error(e.getMessage());model.addAttribute("msg","賬號或密碼不正確");return "login";}catch (LockedAccountException e) {logger.error(e.getMessage());model.addAttribute("msg","賬號已被鎖定,請聯系管理員");return "login";}catch (AuthenticationException e) {logger.error(e.getMessage());model.addAttribute("msg","賬戶驗證失敗");return "login";}return  "index";}@RequestMapping("/registe")public String registe(User user){userService.saveUser(user);return "ok";}@RequestMapping("/logout")public String logout(){ShiroUtil.logout();return "redirect:/login";}}

驗證:

啟動項目,然后隨便請求一個路徑都會被shiro配置的filter攔截器進行攔截,如果請求的路徑需要權限認證就會進入shiro的認證管理中,如果當前用戶沒有登錄就會調整到登錄頁面;

六、細節處理:

  上面的介紹只是給出了一個大概的流程,其中有很多細節還是要特比注意的要不會導致認證失敗,下面我們看一下有哪些細節需要處理

1、用戶密碼加密處理

  在數據庫中存儲的用戶密碼不應該是123456這樣的密碼明文,被不法分子看到是很危險的,所以數據庫中的密碼應該是對密碼進行加密后的密文,而且還要求這個加密算法是不可逆的,即由加密后的字符串不能反推回來原來的密碼,如果能反推回來那這個加密是沒有意義的。

現在常用的加密算法有:?MD5,SHA1

而且shiro提供了SimpleHash這個加密工具來實現密碼加密:

public final static String hashAlgorithmName = "SHA-256";//加密算法
public final static int hashIterations = 16;//hash加密次數

public static String encrypt(String pwd,String salt){
String newPassword = new SimpleHash(hashAlgorithmName,pwd,salt,hashIterations).toHex();
return newPassword;
}

如果兩個人的密碼一樣,即存在數據表里中的兩個加密后的字符串一樣,然而我們希望即使兩個人的密碼一樣,加密后的兩個字符串也不一樣。即需要用到MD5鹽值加密。

鹽值需要唯一: 一般使用隨機字符串或 user id  

這里提供一個工具:

String salt = RandomStringUtils.randomAlphanumeric(20);//使用隨機數函數生成salt

2、配置shiro的密碼比較器

上面我們用加密算法實現了密碼的明文加密,現在數據庫中存儲的是密碼密文,用戶登錄時使用的密碼原文,如果不告訴shiro我們的密碼加密算法邏輯,shiro是使用默認的比較器

進行的簡單的密碼比較(即使用數據庫中的密碼密文和用戶登錄時輸入的密碼明文進行比較),顯而易見這樣比較是不會成功的所以我們要告訴shiro 我們是使用的加密算法,

實現過程很簡單:在我們自定義的UserRealm中添加如下配置

  /*** 設置密碼比較器為HashedCredentialsMatcher* @param credentialsMatcher*/@Overridepublic void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();shaCredentialsMatcher.setHashAlgorithmName(ShiroUtil.hashAlgorithmName);//這里就是我們進行密碼加密的算法shaCredentialsMatcher.setHashIterations(ShiroUtil.hashIterations);//加密循環次數super.setCredentialsMatcher(shaCredentialsMatcher);}

?

轉載于:https://www.cnblogs.com/keepruning/p/9305596.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538267.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

recyclerview item動畫_這可能是你見過的迄今為止最簡單的RecyclerView Item加載動畫...

如何實現RecyclerView Item動畫&#xff1f; 這個問題想必有很多人都會講&#xff0c;我可以用ItemAnimator實現啊&#xff0c;這是RecyclerView官方定義的接口&#xff0c;專門擴展Item動畫的&#xff0c;那我為什么要尋求另外一種方法實現呢&#xff1f;因為最近反思了一個問…

群暉編譯LCD4Linux,LCD4LINUX配置文件一些參數使用解釋。

#LCD顯示配置Display dpf {Driver DPF #LCD驅動類型Port usb0 #連接端口Font 6x8 #字體大小Foreground ffffff #字體…

VBoxManage: error: Nonexistent host networking interface, name 'vboxnet0' (VERR_INTERNAL_ERROR)

錯誤&#xff1a; VBoxManage: error: Nonexistent host networking interface, name vboxnet0 (VERR_INTERNAL_ERROR) 原因&#xff1a; 原來配置的網卡發生了變更&#xff0c;找不到了&#xff0c;啟動失敗。 解決方法&#xff1a; 第一步&#xff0c;命令&#xff1a; V…

捷信達溫泉管理軟件員工卡SQL查詢

捷信達溫泉管理軟件員工卡SQL查詢 select * from snkey where v_name2 like %員工% 網名&#xff1a;浩秦; 郵箱&#xff1a;root#landv.pw; 只要我能控制一個國家的貨幣發行&#xff0c;我不在乎誰制定法律。金錢一旦作響&#xff0c;壞話隨之戛然而止。

Linux 軟件安裝到 /usr,/usr/local/ 還是 /opt 目錄?

Linux 的軟件安裝目錄是也是有講究的&#xff0c;理解這一點&#xff0c;在對系統管理是有益的 /usr&#xff1a;系統級的目錄&#xff0c;可以理解為C:/Windows/&#xff0c;/usr/lib理解為C:/Windows/System32。 /usr/local&#xff1a;用戶級的程序目錄&#xff0c;可以理解…

winpe裝雙系統linux_使用syslinux在u盤安裝pubbylinux和winpe雙系統

使用syslinux在u盤安裝pubbylinux和winpe雙系統1,在u盤里安裝winpe,請參見"比較簡單的制作U盤winpe啟動盤方法"比較簡單的制作U盤winpe啟動盤方法 收藏1,下載一個深度winpev3.iso2,用winrar或ultraISO解壓深度winpev3.iso3,進入解壓出來的文件夾下&#xff0c;找到se…

esp32 嵌入式linux,初體驗樂鑫 ESP32 AT 指令-嵌入式系統-與非網

樂鑫 AT 固件初體驗初步體驗 AT 指令下 TCP 數傳&#xff0c;為了驗證 AT 命令解析器。前往樂鑫官網 下載最新版本 AT 固件和 AT 指令集手冊。硬件準備本文使用樂鑫的 ESP-WROOM-32(ESP-WROOM-32 是 ESP32-WROOM-32 的曾用名)模塊&#xff0c;4MB Flash&#xff0c;無 PSRAM。E…

主機ping不通Virtualbox里的虛擬機

在redhat上安裝了VirtualBox&#xff0c;虛擬了三臺Linux機器。 宿主機網卡更換過了。三臺虛擬機無法啟動了&#xff0c;搭建虛擬機的運維離職了。 VirtualBox的圖形界面壞了&#xff0c;啟動不了。只能用命令行&#xff0c;今天時間就花在命令行上了。 第一個問題是&#xf…

python后端開發靠譜嗎_【后端開發】python有這么強大嗎

因為Python是一種代表簡單主義思想的語言。除此之外&#xff0c;Python所擁有的標準庫更是金融、營銷類人群選擇它的理由。Python 易于學習可靠且高效(推薦學習&#xff1a;Python視頻教程)好吧&#xff0c;相較于其它許多你可以拿來用的編程語言而言&#xff0c;它“更容易一些…

linux 卸載 openldap,Linux下安裝openldap

Ubuntu apt-getinstall安裝參考&#xff1a;http://dongwang.wordpress.com/category/uncategorized/普通linux安裝,以XXX用戶身份安裝&#xff1a;1、安裝BerkeleyDB 4.7.25&#xff1a;伯克利大學嵌入式數據庫解決方案,openldap拿它作為存儲方案。http://download.oracle.com…

Git之原有基礎開發新功能

場景描述 當一個項目已經上線&#xff0c;同時又在原有基礎上新增功能模塊&#xff0c;于是乎就要在原有代碼的基礎上進行開發&#xff0c;在新增模塊功能的開發的過程中&#xff0c;項目發現了一個緊急Bug&#xff0c;需要修復。操作流程如下&#xff1a; -------------------…

pantum打印機驅動安裝m6506_奔圖Pantum M6506NW 驅動

這是奔圖Pantum M6506NW 驅動&#xff0c;是M6506NW奔圖打印機驅動&#xff0c;此設備內置WIFI熱點&#xff0c;安裝驅動可以幫助用戶解決打印機連接和工作中出現的問題&#xff0c;非常方便&#xff0c;需要的朋友快來本站下載吧&#xff01;驅動介紹奔圖M6506NW一體機驅動專為…

linux kvm查看線程狀態,kvm線程-005-線程狀態-THREAD_JUST_BORN

在kvm內部定義了線程狀態,如下:enum {THREAD_JUST_BORN 1, /* 還沒有啟動*/THREAD_ACTIVE 2, /* 當前正在運行,或者在等待運行的隊列中*/THREAD_SUSPENDED 4, /* 等待monitor或者alarm */THREAD_DEAD 8, /* 線程退出 */THREAD_MONITOR_WAIT 16, // 等待鎖THREAD_CONVAR_WA…

詳解VirtualBox虛擬機網絡環境解析和搭建-NAT、橋接、Host-Only、Internal、端口映射

原文鏈接&#xff1a;http://www.jb51.net/article/98575.htm -------------------------------------------------- 本文以VirtualBox為例 如果出現主機無法ping通虛擬機的情況&#xff0c;請首先確認虛擬機防火墻已關閉。 一、NAT模式 特點&#xff1a; 1、如果主機可以上網…

os.popen read()報編碼錯誤_數據科學家易犯的十大編碼錯誤,你中招了嗎?

選自 Medium作者&#xff1a;Norm Niemer機器之心編譯參與&#xff1a;李詩萌、王淑婷數據科學家比軟件工程師擅長統計&#xff0c;又比統計學家擅長軟件工程。聽起來牛逼轟轟&#xff0c;事實卻是&#xff0c;許多數據科學家有統計學背景&#xff0c;卻沒有什么軟件工程方面的…

linux怎么添加工作組,linux 用戶與工作組

在linux 里面&#xff0c;用戶的編號UID &#xff0c;也就是用戶的ID號。工作組的編號為GID 也就是工作組的ID 號 。1、用戶的分類超級用戶&#xff1a;root用戶&#xff0c;系統安裝過程中自動創建&#xff0c;UID 為0。普通用戶&#xff1a;操作權限受到限制的用戶id在 500-6…

MySQL5.7.12新密碼登錄方式及密碼策略

原文鏈接&#xff1a;http://www.cnblogs.com/jonsea/p/5510219.html --------------------------------------------------------------------------- 松門一枝花補充 最簡單的方法&#xff1a; 1、配置文件中把密碼策略關了。本文中間部分有介紹。 2、重啟服務 3、用my…

聚類分析在用戶行為中的實例_聚類分析案例之市場細分

聚類是將數據分類到不同的類或者簇這樣的一個過程&#xff0c;所以同一個簇中的對象有很大的相似性&#xff0c;而不同簇間的對象有很大的相異性。從統計學的觀點看&#xff0c;聚類分析是通過數據建模簡化數據的一種方法。傳統的統計聚類分析方法包括系統聚類法、分解法、加入…

linux 編譯system.img,android生成sysytem.img的命令過程

Fromhttp://xianghuaclm.blog.163.com/blog/static/6668783201110221486240/使用#file system.img輸出&#xff1a;system.img: Linux rev 0.0 ext2 filesystem data,UUID4eb0489c-647d-49d8-9111-94657b5fd342, volume name"system"。然而本人使用命令#mkyaffs2imag…

Hive的hiveserver2后臺開啟和關閉

前提&#xff1a;hive/bin配置了環境變量。如果沒有配置&#xff0c;cd到 hive目錄下的bin里&#xff0c;再執行。 開啟命令&#xff1a; nohup hive --service hiveserver2 & 產生的日志&#xff1a; 默認在&#xff1a; 用戶文件夾里 [rootmaster ~]# ll total 80 …