Rumah  >  Artikel  >  Java  >  Cara SpringBoot menggunakan Sa-Token untuk melaksanakan pengesahan kebenaran

Cara SpringBoot menggunakan Sa-Token untuk melaksanakan pengesahan kebenaran

PHPz
PHPzke hadapan
2023-05-16 13:19:131153semak imbas

1. Idea Reka Bentuk

Apa yang dipanggil pengesahan kebenaran, logik teras adalah untuk menentukan sama ada akaun mempunyai kebenaran yang ditentukan:

  • Jika ya, anda akan dibenarkan lulus.

  • Tidak? Kemudian akses adalah dilarang!

Sedalam dalam data asas, setiap akaun akan mempunyai set kod kebenaran dan rangka kerja akan mengesahkan sama ada set ini mengandungi kod kebenaran yang ditentukan.

Contohnya: akaun semasa mempunyai kod kebenaran yang ditetapkan ["user-add", "user-delete", "user-get"], dan kemudian saya mengesahkan kebenaran "user-update", hasilnya ialah: Gagal untuk mengesahkan, akses dilarang.

Jadi inti masalahnya sekarang ialah:

  • Bagaimana untuk mendapatkan set kod kebenaran yang dimiliki oleh akaun?

  • Apakah kod kebenaran yang perlu disahkan untuk operasi ini?

Seterusnya, kami akan memperkenalkan cara menggunakan Sa-Token untuk melengkapkan operasi pengesahan kebenaran dalam SpringBoot.

Sa-Token ialah rangka kerja pengesahan kebenaran java ringan yang terutamanya menyelesaikan satu siri isu berkaitan kebenaran seperti pengesahan log masuk, pengesahan kebenaran, log masuk tunggal, OAuth3, pengesahan get laluan mikroperkhidmatan, dsb.

Mula-mula perkenalkan pergantungan Sa-Token ke dalam projek:

<!-- Sa-Token 权限认证 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

Nota: Jika anda menggunakan SpringBoot 3.x, cuma tukar sa-token-spring-boot-starter kepada sa-token-spring-boot3-starter .

2. Dapatkan set kod kebenaran akaun semasa

Oleh kerana setiap projek mempunyai keperluan yang berbeza dan reka bentuk kebenarannya juga sentiasa berubah, oleh itu [Dapatkan set kod kebenaran akaun semasa] Operasi ini tidak boleh dibina ke dalam rangka kerja, jadi Sa-Token mendedahkan operasi ini kepada anda dalam bentuk antara muka, supaya anda boleh menulis semula mengikut logik perniagaan anda sendiri.

Apa yang anda perlu lakukan ialah mencipta kelas baharu dan melaksanakan antara muka StpInterface, contohnya kod berikut:

/**
 * 自定义权限验证接口扩展
 */
@Component	// 保证此类被SpringBoot扫描,完成Sa-Token的自定义权限验证扩展 
public class StpInterfaceImpl implements StpInterface {

	/**
	 * 返回一个账号所拥有的权限码集合 
	 */
	@Override
	public List<String> getPermissionList(Object loginId, String loginType) {
		// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
		List<String> list = new ArrayList<String>();	
		list.add("101");
		list.add("user.add");
		list.add("user.update");
		list.add("user.get");
		// list.add("user.delete");
		list.add("art.*");
		return list;
	}

	/**
	 * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
	 */
	@Override
	public List<String> getRoleList(Object loginId, String loginType) {
		// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
		List<String> list = new ArrayList<String>();	
		list.add("admin");
		list.add("super-admin");
		return list;
	}

}

Penjelasan parameter:

  • loginId: id akaun, iaitu nilai pengenalan yang anda tulis semasa memanggil StpUtil.login(id).

  • loginType: Pengecam sistem akaun, yang boleh diabaikan buat sementara waktu di sini Konsep ini akan diterangkan secara terperinci di bawah bab [Pengesahan Akaun Berbilang].

Nota: Kelas mesti diberi anotasi dengan @Component untuk memastikan komponen diimbas oleh Springboot dan berjaya disuntik ke dalam rangka kerja Sa-Token.

3. Pengesahan kebenaran

Kelas permulaan:

@SpringBootApplication
public class SaTokenCaseApplication {
	public static void main(String[] args) {
		SpringApplication.run(SaTokenCaseApplication.class, args); 
		System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
	}	
}

Kemudian anda boleh menggunakan api berikut untuk mengesahkan

// 获取:当前账号所拥有的权限集合
StpUtil.getPermissionList();

// 判断:当前账号是否含有指定权限, 返回 true 或 false
StpUtil.hasPermission("user.add");		

// 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException 
StpUtil.checkPermission("user.add");		

// 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过]
StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");		

// 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");	

Sambungan: NotPermissionException Objek Khusus getLoginType() pengecualian boleh diperolehi melalui kaedah StpLogic

4. Pengesahan peranan

Dalam Sa-Token, peranan dan kebenaran boleh disahkan secara bebas

// 获取:当前账号所拥有的角色集合
StpUtil.getRoleList();

// 判断:当前账号是否拥有指定角色, 返回 true 或 false
StpUtil.hasRole("super-admin");		

// 校验:当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
StpUtil.checkRole("super-admin");		

// 校验:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
StpUtil.checkRoleAnd("super-admin", "shop-admin");		

// 校验:当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可] 
StpUtil.checkRoleOr("super-admin", "shop-admin");		

Sambungan: NotRoleException objek boleh diperolehi melalui kaedah getLoginType() yang StpLogic pengecualian dilemparkan

5. Pemintasan pengecualian global

Sesetengah pelajar ingin bertanya tentang pengesahan Gagal, melontar pengecualian , dan kemudian apa? Perlukah pengecualian dipaparkan kepada pengguna? Sudah tentu tidak!

Anda boleh mencipta pemintas pengecualian global untuk menyatukan format yang dikembalikan ke bahagian hadapan Rujukan:

@RestControllerAdvice
public class GlobalExceptionHandler {
    // 全局异常拦截 
    @ExceptionHandler
    public SaResult handlerException(Exception e) {
        e.printStackTrace(); 
        return SaResult.error(e.getMessage());
    }
}

6. Kad bebas kebenaran

Sa-Token membenarkan anda. kepada Wildcards tentukan kebenaran am Contohnya, apabila akaun mempunyai kebenaran art.*, art.add, art.delete dan art.update semuanya akan sepadan dengan kebenaran yang diluluskan oleh

rreee<. . tahap>

Kebenaran tepat kepada tahap butang bermaksud: "*"Skop kebenaran boleh mengawal sama ada setiap butang pada halaman memaparkan

.

Idea: Kawalan julat tepat sedemikian sukar dicapai dengan hanya bergantung pada bahagian belakang Pada masa ini, bahagian hadapan perlu membuat pertimbangan logik tertentu.

Jika ia merupakan projek bahagian hadapan dan bahagian belakang bersepadu, anda boleh merujuk kepada: Dialek tag Thymeleaf Jika ia adalah projek yang dipisahkan di bahagian hadapan dan bahagian belakang, maka:

Apabila log masuk, letakkan maklumat yang dimiliki oleh akaun semasa Semua kod kebenaran dikembalikan ke bahagian hadapan sekali gus.

    Hujung hadapan menyimpan koleksi kod kebenaran dalam
  • atau objek pengurusan keadaan global yang lain.

  • Pada butang yang memerlukan kawalan kebenaran, gunakan js untuk membuat pertimbangan logik Contohnya, dalam rangka kerja

    kita boleh menggunakan tulisan berikut: localStorage

    // 当拥有 art.* 权限时
    StpUtil.hasPermission("art.add");        // true
    StpUtil.hasPermission("art.update");     // true
    StpUtil.hasPermission("goods.add");      // false
    
    // 当拥有 *.delete 权限时
    StpUtil.hasPermission("art.delete");      // true
    StpUtil.hasPermission("user.delete");     // true
    StpUtil.hasPermission("user.update");     // false
    
    // 当拥有 *.js 权限时
    StpUtil.hasPermission("index.js");        // true
    StpUtil.hasPermission("index.css");       // false
    StpUtil.hasPermission("index.html");      // false
  • Antaranya:
  • ialah susunan kod kebenaran yang dimiliki oleh pengguna semasa,

    ialah kod kebenaran yang diperlukan untuk memaparkan butang dan Vue ialah kandungan yang pengguna hanya boleh lihat jika dia mempunyai kod kebenaran.

  • Nota: Kaedah penulisan di atas hanyalah untuk memberikan contoh rujukan Rangka kerja yang berbeza mempunyai kaedah penulisan yang berbeza Anda boleh merangkum dan memanggil secara fleksibel mengikut susunan teknologi projek.

8. Jika bahagian hadapan mempunyai pengesahan, adakah bahagian belakang masih memerlukan pengesahan? arruser.delete删除按钮Diperlukan!

前端的鉴权只是一个辅助功能,对于专业人员这些限制都是可以轻松绕过的,为保证服务器安全,无论前端是否进行了权限校验,后端接口都需要对会话请求再次进行权限校验!

九、来个小示例,加深一下印象

新建 JurAuthController,复制以下代码

package com.pj.cases.use;

import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;

/**
 * Sa-Token 权限认证示例 
 * 
 * @author kong
 * @since 2022-10-13
 */
@RestController
@RequestMapping("/jur/")
public class JurAuthController {

	/*
	 * 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述 
	 * 		---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
	 * 
	 * 前提2:项目实现 StpInterface 接口,代码在  com.pj.satoken.StpInterfaceImpl
	 * 		Sa-Token 将从此实现类获取 每个账号拥有哪些权限。
	 * 
	 * 然后我们就可以使用以下示例中的代码进行鉴权了 
	 */
	
	// 查询权限   ---- http://localhost:8081/jur/getPermission
	@RequestMapping("getPermission")
	public SaResult getPermission() {
		// 查询权限信息 ,如果当前会话未登录,会返回一个空集合 
		List<String> permissionList = StpUtil.getPermissionList();
		System.out.println("当前登录账号拥有的所有权限:" + permissionList);
		
		// 查询角色信息 ,如果当前会话未登录,会返回一个空集合 
		List<String> roleList = StpUtil.getRoleList();
		System.out.println("当前登录账号拥有的所有角色:" + roleList);
		
		// 返回给前端 
		return SaResult.ok()
				.set("roleList", roleList)
				.set("permissionList", permissionList);
	}
	
	// 权限校验  ---- http://localhost:8081/jur/checkPermission
	@RequestMapping("checkPermission")
	public SaResult checkPermission() {
		
		// 判断:当前账号是否拥有一个权限,返回 true 或 false
		// 		如果当前账号未登录,则永远返回 false 
		StpUtil.hasPermission("user.add");
		StpUtil.hasPermissionAnd("user.add", "user.delete", "user.get");  // 指定多个,必须全部拥有才会返回 true 
		StpUtil.hasPermissionOr("user.add", "user.delete", "user.get");	 // 指定多个,只要拥有一个就会返回 true 
		
		// 校验:当前账号是否拥有一个权限,校验不通过时会抛出 `NotPermissionException` 异常 
		// 		如果当前账号未登录,则永远校验失败 
		StpUtil.checkPermission("user.add");
		StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");  // 指定多个,必须全部拥有才会校验通过 
		StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");  // 指定多个,只要拥有一个就会校验通过 
		
		return SaResult.ok();
	}

	// 角色校验  ---- http://localhost:8081/jur/checkRole
	@RequestMapping("checkRole")
	public SaResult checkRole() {
		
		// 判断:当前账号是否拥有一个角色,返回 true 或 false
		// 		如果当前账号未登录,则永远返回 false 
		StpUtil.hasRole("admin");
		StpUtil.hasRoleAnd("admin", "ceo", "cfo");  // 指定多个,必须全部拥有才会返回 true 
		StpUtil.hasRoleOr("admin", "ceo", "cfo");	  // 指定多个,只要拥有一个就会返回 true 
		
		// 校验:当前账号是否拥有一个角色,校验不通过时会抛出 `NotRoleException` 异常 
		// 		如果当前账号未登录,则永远校验失败 
		StpUtil.checkRole("admin");
		StpUtil.checkRoleAnd("admin", "ceo", "cfo");  // 指定多个,必须全部拥有才会校验通过 
		StpUtil.checkRoleOr("admin", "ceo", "cfo");  // 指定多个,只要拥有一个就会校验通过 
		
		return SaResult.ok();
	}

	// 权限通配符  ---- http://localhost:8081/jur/wildcardPermission
	@RequestMapping("wildcardPermission")
	public SaResult wildcardPermission() {
		
		// 前提条件:在 StpInterface 实现类中,为账号返回了 "art.*" 泛权限
		StpUtil.hasPermission("art.add");  // 返回 true 
		StpUtil.hasPermission("art.delete");  // 返回 true 
		StpUtil.hasPermission("goods.add");  // 返回 false,因为前缀不符合  
		
		// * 符合可以出现在任意位置,比如权限码的开头,当账号拥有 "*.delete" 时  
		StpUtil.hasPermission("goods.add");        // false
		StpUtil.hasPermission("goods.delete");     // true
		StpUtil.hasPermission("art.delete");      // true
		
		// 也可以出现在权限码的中间,比如当账号拥有 "shop.*.user" 时  
		StpUtil.hasPermission("shop.add.user");  // true
		StpUtil.hasPermission("shop.delete.user");  // true
		StpUtil.hasPermission("shop.delete.goods");  // false,因为后缀不符合 

		// 注意点:
		// 1、上帝权限:当一个账号拥有 "*" 权限时,他可以验证通过任何权限码
		// 2、角色校验也可以加 * ,指定泛角色,例如: "*.admin",暂不赘述 
		
		return SaResult.ok();
	}
}

代码注释已针对每一步操作做出详细解释,大家可根据可参照注释中的访问链接进行逐步测试。

Atas ialah kandungan terperinci Cara SpringBoot menggunakan Sa-Token untuk melaksanakan pengesahan kebenaran. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam