亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot2.x整合shiro權(quán)限框架的使用

 更新時(shí)間:2020年09月08日 09:23:17   作者:MobiusStrip  
這篇文章主要介紹了springboot2.x整合shiro權(quán)限框架的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在實(shí)際項(xiàng)目中,經(jīng)常需要用到角色權(quán)限區(qū)分,以此來為不同的角色賦予不同的權(quán)利,分配不同的任務(wù)。比如,普通用戶只能瀏覽;會員可以瀏覽和評論;超級會員可以瀏覽、評論和看視頻課等;實(shí)際應(yīng)用場景很多。毫不夸張的說,幾乎每個(gè)完整的項(xiàng)目都會設(shè)計(jì)到權(quán)限管理。

在 Spring Boot 中做權(quán)限管理,一般來說,主流的方案是 Spring Security ,但是由于 Spring Security 過于龐大和復(fù)雜,只要能滿足業(yè)務(wù)需要,大多數(shù)公司還是會選擇 Apache Shiro 來使用。

一般來說,Spring Security 和 Shiro 的區(qū)別如下:

Spring Security Apache Shiro
重量級的安全管理框架 輕量級的安全管理框架
概念復(fù)雜,配置繁瑣 概念簡單、配置簡單
功能強(qiáng)大 功能簡單

因此,這篇文章,阿淼首先會帶大家了解 Apache Shiro ,然后和大家一起將 shiro 權(quán)限框架整合到 SpringBoot 中,以達(dá)到快速的實(shí)現(xiàn)整合權(quán)限管理的功能。

走進(jìn) Apache Shiro

官網(wǎng)認(rèn)知

照例又去官網(wǎng)扒了扒介紹:

Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro's easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
Apache Shiro™是一個(gè)強(qiáng)大且易用的Java安全框架,能夠用于身份驗(yàn)證、授權(quán)、加密和會話管理。Shiro擁有易于理解的API,您可以快速、輕松地獲得任何應(yīng)用程序——從最小的移動應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序。

簡而言之,Apache Shiro 是一個(gè)強(qiáng)大靈活的開源安全框架,可以完全處理身份驗(yàn)證、授權(quán)、加密和會話管理。

Shiro能到底能做些什么呢?

  • 驗(yàn)證用戶身份
  • 用戶訪問權(quán)限控制,比如:1、判斷用戶是否分配了一定的安全角色。2、判斷用戶是否被授予完成某個(gè)操作的權(quán)限
  • 在非 Web 或 EJB 容器的環(huán)境下可以任意使用Session API
  • 可以響應(yīng)認(rèn)證、訪問控制,或者 Session 生命周期中發(fā)生的事件
  • 可將一個(gè)或以上用戶安全數(shù)據(jù)源數(shù)據(jù)組合成一個(gè)復(fù)合的用戶 “view”(視圖)
  • 支持單點(diǎn)登錄(SSO)功能
  • 支持提供“Remember Me”服務(wù),獲取用戶關(guān)聯(lián)信息而無需登錄
  • ···

為什么今天還要使用Apache Shiro?

對此,官方給出了詳細(xì)的解釋:http://shiro.apache.org/

自2003年以來,框架環(huán)境發(fā)生了很大變化,因此今天仍然有充分的理由使用Shiro。實(shí)際上有很多原因。Apache Shiro是:

  • 易于使用 -易于使用是該項(xiàng)目的最終目標(biāo)。應(yīng)用程序安全性可能非常令人困惑和沮喪,并被視為“必要的邪惡”。如果您使它易于使用,以使新手程序員可以開始使用它,那么就不必再痛苦了。
  • 全面 -Apache Shiro聲稱沒有其他具有范圍廣度的安全框架,因此它可能是滿足安全需求的“一站式服務(wù)”。
  • 靈活 -Apache Shiro可以在任何應(yīng)用程序環(huán)境中工作。盡管它可以在Web,EJB和IoC環(huán)境中運(yùn)行,但并不需要它們。Shiro也不要求任何規(guī)范,甚至沒有很多依賴性。
  • 具有Web功能 -Apache Shiro具有出色的Web應(yīng)用程序支持,使您可以基于應(yīng)用程序URL和Web協(xié)議(例如REST)創(chuàng)建靈活的安全策略,同時(shí)還提供一組JSP庫來控制頁面輸出。
  • 可插拔 -Shiro干凈的API和設(shè)計(jì)模式使它易于與許多其他框架和應(yīng)用程序集成。您會看到Shiro與Spring,Grails,Wicket,Tapestry,Mule,Apache Camel,Vaadin等框架無縫集成。
  • 受支持 -Apache Shiro是Apache Software Foundation(Apache軟件基金會)的一部分,該組織被證明以其社區(qū)的最大利益行事。項(xiàng)目開發(fā)和用戶群體友好的公民隨時(shí)可以提供幫助。如果需要,像Katasoft這樣的商業(yè)公司也可以提供專業(yè)的支持和服務(wù)。

Shiro 核心概念

Apache Shiro 是一個(gè)全面的、蘊(yùn)含豐富功能的安全框架。

下圖為描述 Shiro 功能的框架圖:

如圖所示,功能包括:

  • Authentication(認(rèn)證):用戶身份識別,通常被稱為用戶“登錄”
  • Authorization(授權(quán)):訪問控制。比如某個(gè)用戶是否具有某個(gè)操作的使用權(quán)限。
  • Session Management(會話管理):特定于用戶的會話管理,甚至在非web 或 EJB 應(yīng)用程序。
  • Cryptography(加密):在對數(shù)據(jù)源使用加密算法加密的同時(shí),保證易于使用。

并且 Shiro 還有通過增加其他的功能來支持和加強(qiáng)這些不同應(yīng)用環(huán)境下安全領(lǐng)域的關(guān)注點(diǎn)。

特別是對以下的功能支持:

  • Web支持:Shiro 提供的 Web 支持 api ,可以很輕松的保護(hù) Web 應(yīng)用程序的安全。
  • 緩存:緩存是 Apache Shiro 保證安全操作快速、高效的重要手段。
  • 并發(fā):Apache Shiro 支持多線程應(yīng)用程序的并發(fā)特性。
  • 測試:支持單元測試和集成測試,確保代碼和預(yù)想的一樣安全。
  • “Run As”:這個(gè)功能允許用戶假設(shè)另一個(gè)用戶的身份(在許可的前提下)。
  • “Remember Me”:跨 session 記錄用戶的身份,只有在強(qiáng)制需要時(shí)才需要登錄。

注意: Shiro 不會去維護(hù)用戶、維護(hù)權(quán)限,這些需要我們自己去設(shè)計(jì)/提供,然后通過相應(yīng)的接口注入給 Shiro

使用案例 Demo

1.新建 maven 項(xiàng)目

為方便我們初始化項(xiàng)目,Spring Boot給我們提供一個(gè)項(xiàng)目模板生成網(wǎng)站。

1、打開瀏覽器,訪問:https://start.spring.io/

2、根據(jù)頁面提示,選擇構(gòu)建工具,開發(fā)語言,項(xiàng)目信息等。

2.導(dǎo)入 springboot 父依賴

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.0.2.RELEASE</version>
</parent>

3.相關(guān) jar 包

web 包

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

shiro-spring 包就是此篇文章的核心

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring</artifactId>
	<version>1.4.0</version>
</dependency>
shiro 注解會用到 aop
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
數(shù)據(jù)庫相關(guān)包使用的是mybatisplus
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.12</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.1.0</version>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-generator</artifactId>
	<version>3.1.0</version>
</dependency>
	<dependency>
	<groupId>org.apache.velocity</groupId>
	<artifactId>velocity-engine-core</artifactId>
	<version>2.0</version>
</dependency>

4.數(shù)據(jù)庫

建表語句在項(xiàng)目中有,項(xiàng)目地址: https://github.com/mmzsblog/mmzsblog-util

5.自定義 realm

public class MyShiroRealm extends AuthorizingRealm {
	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PermissionService permissionService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils
		// .getSubject()).getServletRequest();//這個(gè)可以用來獲取在登錄的時(shí)候提交的其他額外的參數(shù)信息
		String username = (String) principals.getPrimaryPrincipal();
		// 受理權(quán)限
		// 角色
		Set<String> roles = new HashSet<String>();
		Role role = roleService.getRoleByUserName(username);
		System.out.println(role.getRoleName());
		roles.add(role.getRoleName());
		authorizationInfo.setRoles(roles);
		// 權(quán)限
		Set<String> permissions = new HashSet<String>();
		List<Permission> querypermissions = permissionService.getPermissionsByRoleId(role.getId());
		for (Permission permission : querypermissions) {
			permissions.add(permission.getPermissionName());
		}
		authorizationInfo.setStringPermissions(permissions);
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		String loginName = (String) authcToken.getPrincipal();
		// 獲取用戶密碼
		User user = userService.getOne(new QueryWrapper<User>().eq("username", loginName));
		if (user == null) {
			// 沒找到帳號
			throw new UnknownAccountException();
		}
		String password = new String((char[]) authcToken.getCredentials());
		String inpass = (new Md5Hash(password, user.getUsername())).toString();
		if (!user.getPassword().equals(inpass)) {
			throw new IncorrectCredentialsException();
		}
		// 交給AuthenticatingRealm使用CredentialsMatcher進(jìn)行密碼匹配
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(loginName, user.getPassword(),
				ByteSource.Util.bytes(loginName), getName());

		return authenticationInfo;
	}

}

6.shiro 配置類

@Configuration
public class ShiroConfiguration {
	private static final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);

	/**
	 * Shiro的Web過濾器Factory 命名:shiroFilter
	 */
	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		// Shiro的核心安全接口,這個(gè)屬性是必須的
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		//需要權(quán)限的請求,如果沒有登錄則會跳轉(zhuǎn)到這里設(shè)置的url
		shiroFilterFactoryBean.setLoginUrl("/login.html");
		//設(shè)置登錄成功跳轉(zhuǎn)url,一般在登錄成功后自己代碼設(shè)置跳轉(zhuǎn)url,此處基本沒用
		shiroFilterFactoryBean.setSuccessUrl("/main.html");
		//設(shè)置無權(quán)限跳轉(zhuǎn)界面,此處一般不生效,一般自定義異常
		shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
		Map<String, Filter> filterMap = new LinkedHashMap<>();
		// filterMap.put("authc", new AjaxPermissionsAuthorizationFilter());
		shiroFilterFactoryBean.setFilters(filterMap);
		/*
		 * 定義shiro過濾鏈 Map結(jié)構(gòu)
		 * Map中key(xml中是指value值)的第一個(gè)'/'代表的路徑是相對于HttpServletRequest.getContextPath()的值來的
		 * anon:它對應(yīng)的過濾器里面是空的,什么都沒做,這里.do和.jsp后面的*表示參數(shù),比方說login.jsp?main這種
		 * authc:該過濾器下的頁面必須驗(yàn)證后才能訪問,它是Shiro內(nèi)置的一個(gè)攔截器org.apache.shiro.web.filter.authc.
		 * FormAuthenticationFilter
		 */
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		/*
		 * 過濾鏈定義,從上向下順序執(zhí)行,一般將 /**放在最為下邊; authc:所有url都必須認(rèn)證通過才可以訪問;
		 * anon:所有url都都可以匿名訪問
		 */
		filterChainDefinitionMap.put("/login.html", "authc");
		filterChainDefinitionMap.put("/login", "anon");
		filterChainDefinitionMap.put("/js/**", "anon");
		filterChainDefinitionMap.put("/css/**", "anon");
		filterChainDefinitionMap.put("/logout", "logout");
		filterChainDefinitionMap.put("/**", "authc");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	/**
	 * 權(quán)限管理
	 */
	@Bean
	public SecurityManager securityManager() {
		logger.info("=======================shiro=======================");
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(MyShiroRealm());
		// securityManager.setRememberMeManager(rememberMeManager);
		return securityManager;
	}

	/**
	 * Shiro Realm 繼承自AuthorizingRealm的自定義Realm,即指定Shiro驗(yàn)證用戶登錄的類為自定義的
	 */
	@Bean
	public MyShiroRealm MyShiroRealm() {
		MyShiroRealm userRealm = new MyShiroRealm();
		userRealm.setCredentialsMatcher(hashedCredentialsMatcher());
		return userRealm;
	}

	/**
	 * 憑證匹配器 密碼驗(yàn)證
	 */
	@Bean(name = "credentialsMatcher")
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		// 散列算法:這里使用MD5算法;
		hashedCredentialsMatcher.setHashAlgorithmName("md5");
		// 散列的次數(shù),比如散列兩次,相當(dāng)于 md5(md5(""));
		hashedCredentialsMatcher.setHashIterations(1);
		// storedCredentialsHexEncoded默認(rèn)是true,此時(shí)用的是密碼加密用的是Hex編碼;false時(shí)用Base64編碼
		hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
		return hashedCredentialsMatcher;
	}

	/**
	 * 開啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用Shiro注解的類,并在必要時(shí)進(jìn)行安全邏輯驗(yàn)證
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
		return authorizationAttributeSourceAdvisor;
	}

}

7.測試類

@RestController
public class UserController {
	@PostMapping("login")
	public String name(String username, String password) {
		String result = "已登錄";
		Subject currentUser = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		if (!currentUser.isAuthenticated()) {
			try {
				currentUser.login(token);// 會觸發(fā)com.shiro.config.MyShiroRealm的doGetAuthenticationInfo方法
				result = "登錄成功";
			} catch (UnknownAccountException e) {
				result = "用戶名錯(cuò)誤";
			} catch (IncorrectCredentialsException e) {
				result = "密碼錯(cuò)誤";
			}
		}
		return result;
	}

	@GetMapping("logout")
	public void logout() {
		Subject currentUser = SecurityUtils.getSubject();
		currentUser.logout();
	}

	@RequiresPermissions("role:update")
	@GetMapping("/role")
	public String name() {
		return "hello";
	}

	@RequiresPermissions("user:select")
	@GetMapping("/role2")
	public String permission() {
		return "hello sel";
	}

}

7.1 登錄測試

數(shù)據(jù)庫賬號(密碼經(jīng)過md5加鹽加密)

7.2 權(quán)限測試

8.說明

8.1 無權(quán)限時(shí)的處理

無權(quán)限時(shí)自定義了一個(gè)異常。所以,權(quán)限測試的時(shí)候沒有權(quán)限就會提示配置的提示語 “沒有權(quán)限”。

@ControllerAdvice
public class ShiroException {
	@ExceptionHandler(value = UnauthorizedException.class)
	@ResponseBody
	public String name() {
		return "沒有權(quán)限";
	}
}

8.2 角色權(quán)限測試與權(quán)限測試相同

權(quán)限設(shè)置可在shiro配置類中shiro過濾鏈設(shè)置,也可用注解方式設(shè)置,本文使用注解方式。

8.3 shiro 的 session 和 cache

shiro 的 session 和 cache 管理可以自定義,本文用的是默認(rèn)的,推薦自定義,方便管理。

小結(jié)

  • Apache Shiro是Java的一個(gè)安全框架
  • Shiro是一個(gè)強(qiáng)大的簡單易用的Java安全框架,主要用來更便捷的認(rèn)證、授權(quán)、加密、會話管理、與Web集成、緩存等
  • Shiro使用起來小而簡單
  • spring中有spring security ,是一個(gè)權(quán)限框架,它和spring依賴過于緊密,沒有shiro使用簡單。
  • shiro不依賴于spring,shiro不僅可以實(shí)現(xiàn)web應(yīng)用的權(quán)限管理,還可以實(shí)現(xiàn)c/s系統(tǒng),分布式系統(tǒng)權(quán)限管理,
  • shiro屬于輕量框架,越來越多企業(yè)項(xiàng)目開始使用shiro.

參考:

http://shiro.apache.org/

https://www.cnblogs.com/joker-dj/archive/2020/04/13/12690648.html 

到此這篇關(guān)于springboot2.x整合shiro權(quán)限框架的使用的文章就介紹到這了,更多相關(guān)springboot2.x整合shiro內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的logback標(biāo)記日志過濾器MarkerFilter詳解

    Java中的logback標(biāo)記日志過濾器MarkerFilter詳解

    這篇文章主要介紹了Java中的logback標(biāo)記日志過濾器MarkerFilter詳解,在logback-classic中存在一個(gè)全局過濾器TurboFilter,TurboFilter是與LoggerContext綁定,會在會在其它過濾器之前執(zhí)行,需要的朋友可以參考下
    2023-11-11
  • JavaEE idea的smart tomcat插件使用

    JavaEE idea的smart tomcat插件使用

    這篇文章主要介紹了JavaEE idea的smart tomcat插件使用,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • Java 替換字符串右側(cè)出現(xiàn)的第一個(gè)子串方式

    Java 替換字符串右側(cè)出現(xiàn)的第一個(gè)子串方式

    這篇文章主要介紹了Java 替換字符串右側(cè)出現(xiàn)的第一個(gè)子串方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例

    Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例

    這篇文章主要介紹了Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例,在一些業(yè)務(wù)需求中我們經(jīng)常需要使用郵箱進(jìn)行驗(yàn)證碼的收取,本文通過簡單的代碼實(shí)例來說明,需要的朋友可以參考下
    2024-01-01
  • java導(dǎo)出生成word的簡單方法

    java導(dǎo)出生成word的簡單方法

    這篇文章主要為大家詳細(xì)介紹了java導(dǎo)出生成word的簡單方法,感興趣的朋友可以參考一下
    2016-03-03
  • Java編程中使用throw關(guān)鍵字拋出異常的用法簡介

    Java編程中使用throw關(guān)鍵字拋出異常的用法簡介

    這篇文章主要介紹了Java編程中使用throw關(guān)鍵字拋出異常的用法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • java中fork-join的原理解析

    java中fork-join的原理解析

    Fork/Join框架是Java7提供用于并行執(zhí)行任務(wù)的框架,是一個(gè)把大任務(wù)分割成若干個(gè)小任務(wù),今天通過本文給大家分享java中fork join原理,感興趣的朋友一起看看吧
    2021-04-04
  • IntelliJ IDEA基于Scala實(shí)現(xiàn)Git檢查工具

    IntelliJ IDEA基于Scala實(shí)現(xiàn)Git檢查工具

    這篇文章主要介紹了如何使用Scala實(shí)現(xiàn)自定義的Git檢查工具,大家可以基于本文的示例進(jìn)行擴(kuò)展與實(shí)現(xiàn),也可以進(jìn)行其他應(yīng)用方向的嘗試,感興趣的可以了解下
    2023-08-08
  • 使用RestTemplate訪問https實(shí)現(xiàn)SSL請求操作

    使用RestTemplate訪問https實(shí)現(xiàn)SSL請求操作

    這篇文章主要介紹了使用RestTemplate訪問https實(shí)現(xiàn)SSL請求操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java實(shí)現(xiàn)坦克大戰(zhàn)游戲

    java實(shí)現(xiàn)坦克大戰(zhàn)游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)坦克大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09

最新評論