Spring Boot聚合項目:達內知道(二)-Mybatis Plus、Spring Security


1.Mybatis Plus

1.1 什么是Mybatis Plus?

  Mybatis Plus是一個對Mybatis框架進行了增強的框架,在保留原有功能的基礎上,又增加了一些實用的功能(mybatis封裝了底層的JDBC代碼,用於對數據庫進行操作,詳見:Mybatis框架 - 夢想家小崔 - 博客園 https://www.cnblogs.com/XiaoCui-blog/p/15110488.html)。

  左側的代表mybatis plus(有個小星星,表示增強),右側的代表mybatis,mybatis plus是mybatis的增強版。

1.2 添加依賴

  我們現在portal項目的依賴都沒有添加版本,因為我們繼承的Spring Boot 2.3.12.RELEASE這個項目中已經定義了開發中常用的框架的版本。但是Mybatis Plus這個框架的版本沒有在Spring Boot 2.3.12中定義,所以我們添加依賴要加版本。但是多個模塊都添加依賴版本會造成版本號維護問題,所以企業中的做法是在父項目中定義一次版本,子項目中來使用,當需要維護版本時,只需要修改父項目中的版本即可。

先在父項目knows中的pom.xml文件中添加mybatis plus版本和依賴:

   <properties>
         <!--java版本-->
         <java.version>1.8</java.version>
         <!--mybatis-plus版本-->
         <mybatis.plus.version>3.3.1</mybatis.plus.version>
     </properties>
  <!--添加依賴管理,管理版本-->
     <dependencyManagement>
         <dependencies>
             <!--${mybatis.plus.version}:取mybatis.plus.version里面的內容-->
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-extension</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-boot-starter</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-generator</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

子項目knows-portal的pom.xml文件的最終依賴:

  <!--添加依賴-->
     <dependencies>
         <!--spring-boot-starter-web-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
 
         <!--測試依賴-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
             <exclusions>
                 <exclusion>
                     <groupId>org.junit.vintage</groupId>
                     <artifactId>junit-vintage-engine</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <!--添加lombok工具依賴,簡化get、set、toString方法等書寫-->
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
 
         <!--mybatis-plus框架,版本已在父版本中定義-->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
         </dependency>
 
         <!-- 連接MySQL數據庫的依賴,版本在SpringBoot已定義 -->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
     </dependencies>

1.3 Mybatis Plus功能一:自動生成方法

  Mybatis Plus 框架主要新增了兩個實用的功能,第一是可以通過實現一個接口自動實現基本增刪改查方法。

為了測試,我們新建一個對應Tag表的實體類

 @Data
 public class Tag {
     private Integer id;
     private String name;
     private String createby;
     private String createtime;
 
 }

創建mapper包,包中新建TagMapper:

 // 我們連接操作數據庫的Mapper接口要繼承一個父接口BaseMapper
 // BaseMapper這個接口中已經編寫好了基本的增刪改查方法,無需我們編寫
 // <Tag>:表示當前在這個Mapper對哪個表生成代碼
 @Repository //@Component注解會將對象存儲到Spring容器中,但@Repository不僅可以進行存儲對象,還可以進行數據庫操作
 public interface TagMapper extends BaseMapper<Tag> {
 }

在SpringBoot啟動類中,添加掃描包的代碼:

 package cn.tedu.knows.portal;
 
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
 //mybatis-plus框架指定掃描的包,定位到mapper
 //效果是將指定的包中的所有類都具備相當於添加了@Mapper注解的效果
 @MapperScan("cn.tedu.knows.portal.mapper")
 public class KnowsPortalApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(KnowsPortalApplication.class, args);
    }
 
 }
 

注意:如果啟動類沒有添加@MapperScan(“cn.tedu.know.portal.mapper”),報如下異常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cn.tedu.know.portal.KnowPortalApplicationTests': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.tedu.know.portal.mapper.TagMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

在application.properties文件中進行數據庫配置:

 # 連接數據庫,注意數據庫名為knows、MariaDB端口號為3307
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.datasource.url=jdbc:mysql://localhost:3307/knows?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
 spring.datasource.username=root
 spring.datasource.password=root

在測試類中測試功能:

 @Autowired //自動裝配(相當於從Spring容器中取出來用)
 TagMapper tagMapper;
 //新增一個Tag
 @Test
 public void testTag(){
     Tag tag=new Tag();
     tag.setId(21);
     tag.setName("微服務");
     tag.setCreateby("tom");
     tag.setCreatetime("2021-08-23 11:23:00");//注意時間格式嚴格書寫
     //使用BaseMapper提供的方法執行新增操作
     tagMapper.insert(tag);
     System.out.println("ok");
 }
 
 //按id查詢Tag
 @Test
 public void testId(){
     Tag tag=tagMapper.selectById(21);
     System.out.println(tag);
 }
 
 // 全查所有Tag
 @Test
 public void testAll(){
     List<Tag> tags=tagMapper.selectList(null);//null處添加條件,為null表示查詢所有
     for(Tag tag: tags){
         System.out.println(tag);
    }
 }
 
 //修改一個標簽對象
 @Test
 public void testUpdate(){
     //修改一個對象要先查出來
     Tag tag=tagMapper.selectById(21);
     //將想修改的屬性進行修改(不能改id)
     tag.setCreateby("admin");
     //執行修改
     tagMapper.updateById(tag);
     System.out.println("ok");
 }
 
 //按id刪除
 @Test
 public void testDelete(){
     //刪除我們測試時新增的標簽
     tagMapper.deleteById(21);
     System.out.println("ok");
 }

注意:如果使用mapper時沒有先添加@Autowired,報如下異常:

java.lang.NullPointerException

at cn.tedu.know.portal.KnowPortalApplicationTests.testId(KnowPortalApplicationTests.java:38)

1.4 顯示Sql語句在控制台

  上面經過測試,我們驗證了Mybatis Plus框架是可以自動生成基本操作語句的,但是運行了什么樣的語句,我們不知道。如果想觀察sql語句的運行,我們需要配置日志級別。

首先了解日志級別分級:

  • trace 痕跡 低重要級別

  • debug 打樁輸出(調試)

  • info 信息

  • warn 警告

  • error 錯誤 高重要級別

  SpringBoot框架默認顯示的是Info以上級別的信息,Mybatis框架把sql語句的運行信息放在了debug級別,所以我們只需要將SpringBoot輸出日志的級別修改為debug,就可以看到Mybatis運行的sql語句了。

需要在application.properties文件中添加日志配置:

 # 設置cn.tedu.konws.portal包中的所有類的日志輸出級別:
 # debug級別及以上級別信息會輸出到控制台顯示,也叫設置門檻
 logging.level.cn.tedu.knows.portal = debug

測試代碼:

 @SpringBootTest
 @Slf4j //注意:使用log.debug或info等要先引入@Slf4j
 class KnowPortalApplicationTests {
     @Autowired
     TagMapper mapper;
 
  //按id查詢tag
     @Test
     public void testId(){
         Tag tag = mapper.selectById(1);
         System.out.println(tag);
         //log.debug("debug");//此處寫不寫在控制台都會輸出對應sql語句的日志信息,因為已在配置文件中設置日志門檻
         //log.info("info");
    }
 }

顯示結果:

1.5 Mybatis Plus功能二:代碼生成器

  在實際開發中,數據庫中每個表都要有對應的實體類 \ 控制器 \ 數據訪問層 \ 業務邏輯層的代碼,項目越大,表越多,這個步驟就越繁瑣。為了減輕這個負擔,Mybatis Plus提供了代碼生成器,能夠根據數據庫中的表自動生成這一系列的數據。

創建項目

  因為代碼生成是需要一些指令和配置的,但是這些指令和配置是只運行一次的,所以最好單獨放在一個項目中。

創建父項目knows的子項目knows-generator:

父項目的pom.xml添加子項目:

 <modules>
     <module>knows-portal</module>
     <module>knows-generator</module>
 </modules>

子項目的knows-generator的pom.xml:進行父子相認、添加依賴

 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <!--父子相認-->
         <groupId>cn.tedu</groupId>
         <artifactId>knows</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>knows-generator</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>knows-generator</name>
     <description>Demo project for Spring Boot</description>
     <!--添加依賴-->
     <dependencies>
         <!--springboot啟動類-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
         
         <!--springboot代碼生成器-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-freemarker</artifactId>
         </dependency>
         
         <!--mybatis-plus啟動類-->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
         </dependency>
 
         <!--mybatis代碼生成器-->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-generator</artifactId>
         </dependency>
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-extension</artifactId>
         </dependency>
 
         <!--數據庫連接-->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
 
         <!--lombok簡化方法-->
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
     </dependencies>
 </project>

在cn.tedu.knows.generator下創建包code,包中創建類CodeGenerator,復制蒼老師網站的CodeGenerator類中的代碼(代碼生成器現成代碼),修改類的屬性位置:

 //數據庫連接參數
 public static String driver = "com.mysql.cj.jdbc.Driver";
 //                                             ↓↓↓端口號、數據庫名↓↓↓
 public static String url = "jdbc:mysql://localhost:3306/knows?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
 public static String username="root";
 //                       ↓↓↓數據庫密碼↓↓↓
 public static String password="root";
 //父級別包名稱                               ↓↓↓數據庫名↓↓↓
 public static String parentPackage = "cn.tedu.knows";
 //代碼生成的目標路徑               ↓↓↓數據庫名↓↓↓
 public static String generateTo = "/knows-generator/src/main/java";
 //mapper.xml的生成路徑               ↓↓↓數據庫名↓↓↓
 public static String mapperXmlPath = "/knows-generator/src/main/resources/mapper";
 //控制器的公共基類,用於抽象控制器的公共方法,null值表示沒有父類
 public static String baseControllerClassName ;// = "cn.tedu.straw.portal.base.BaseController";
 //業務層的公共基類,用於抽象公共方法
 public static String baseServiceClassName ;   // = "cn.tedu.straw.portal.base.BaseServiceImpl";
 //作者名
 public static String author = "tedu.cn";
 //模塊名稱,用於組成包名
 public static String modelName = "portal";
 //Mapper接口的模板文件,不用寫后綴 .ftl
 public static String mapperTempalte = "/ftl/mapper.java";

刪除knows-generator項目的src下的test文件夾,否則報錯(一定要先刪除test文件夾,在進行下面操作,否則在portal進行測試時會出現各種各樣的錯誤)。

在src/main/resources文件夾下創建ftl文件夾,在ftl文件夾中創建文件mapper.java.ftl(前面即文件全稱),代碼從蒼老師網站復制。

 import ${package.Entity}.${entity};
 import ${superMapperClassPackage};
 import org.springframework.stereotype.Repository;
 
 /**
 * <p>
    * ${table.comment!} Mapper 接口
    * </p>
 *
 * @author ${author}
 * @since ${date}
 */
 <#if kotlin>
    interface ${table.mapperName} : ${superMapperClass}<${entity}>
 <#else>
    @Repository
    public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
 
    }
 </#if>
 Spring-Security starter
 <!-- Spring Security -->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
 </dependency>
 <!-- Spring Security Test -->
 <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
 </dependency>

然后運行CodeGenerator中的main 方法,運行后輸入表名:all,其中,"all"表示所有,然后回車:

運行完成后觀察控制台輸出:

得到上面結果,表示一切正常。將knows-generator項目的cn.tedu.knows.portal包中生成的四個包:mapper、controller、model 、service復制到knows-portal項目中:

然后刪除knows-generator項目的cn.tedu.knows.portal包:

最后測試生成的代碼是否可用:

(1)測試mapper是否可用:

在knows-portal項目的test文件夾下新建一個測試類TestMapper,代碼如下:

 package cn.tedu.knows.portal;
 
 import cn.tedu.knows.portal.mapper.TagMapper;
 import cn.tedu.knows.portal.model.Tag;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
 //新建的測試類必須加這個@SpringBootTest注解,不加這個注解運行就是空指針異常
 @SpringBootTest
 public class TestMapper {
     @Autowired
     TagMapper tagMapper;
     @Test
     public void mapper(){
         Tag tag = tagMapper.selectById(1);
         System.out.println(tag);
    }
 }
 

輸出結果:

前面進行日志配置后,可以顯示sql語句:

查詢結果:

(2)測試controller是否可用:

在controller包中修改UserController,代碼如下:

 package cn.tedu.knows.portal.controller;
 
 
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
  * 前端控制器
  * </p>
  *
  * @author tedu.cn
  * @since 2021-08-23
  */
 @RestController
 //為今后微服務項目方便起見,根據微服務標准,
 //將@RequestMapping("/portal/user")改為@RequestMapping("/v1/users")
 @RequestMapping("/v1/users")
 public class UserController {
     // 類上編寫RequestMapping,表示這個類中的所有控制器方法路徑都以/v1/users開頭
     // 企業中開發要求確定請求是get還是post,不推薦直接使用RequestMapping
     // get請求用@GetMapping
     // post請求用@PostMapping
     //下面的這個方法請求的全路徑為:"http://localhost:8080/v1/users/get"
     @GetMapping("/get")
     public String get(){
         System.out.println("運行了get方法");
         return "運行了get方法";
    }
 }
 

啟動項目KnowsPortalApplication,瀏覽器輸入地址,http://localhost:8080/v1/users/get,得到輸出結果!

(1)瀏覽器(注意自己的端口為8888)

(2)控制台

 

2.Spring 安全框架

2.1 Spring 安全框架概述

  我們要先完成達內知道項目的登錄功能,我們自己編寫登錄的安全性是非常不可靠的。菜鳥程序員要想寫出企業級的安全登錄,就需要依靠框架來實現。

  Spring-Security是Spring提供的安全管理框架,是Spring生態系統提供的關於安全方面的框架,它能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案。這個框架中包含了登錄部分的核心代碼,非常安全,我們只需要按照框架要求的數據編寫傳入即可。Spring-Security框架不止完成登錄功能,還能幫我們實現項目中的權限管理等功能。

2.2 初步使用Spring-Security

  要想使用Spring-Security,需要添加依賴,在knows-portal項目的pom.xml添加如下依賴:

 <!-- Spring Security -->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-security</artifactId>
 </dependency>

  Spring-Security的使用相當便捷,只要添加依賴,當前項目的所有資源就被它保護起來了。重啟portal服務,訪問任何路徑,都需要先登錄才能訪問:

  用戶名是user,密碼在啟動服務的控制台中以隨機UUID給出,只有輸入此UUID密碼才能正確登錄。

  如果想自定義用戶名密碼,需要在application.properties進行配置:

 # 設置Spring-Security框架的用戶名和密碼
 spring.security.user.name=admin
 spring.security.user.password=123456

  重啟服務,使用我們自定義的用戶名密碼來登錄。同時你會發現,控制台就沒有再出現那個隨機的密碼了。

2.3 密碼加密

  如果按照上面的配置,任何人看到這個配置文件都可以登錄這個系統,安全性沒有保證。我們要做到,即使有人看到了我們的密碼,它也無法登錄,這個功能實現就需要密碼加密。我們使用bcrypt加密規則,將我們的密碼加密之后保存,保證安全。

  我們創建一個測試類TestPwd來學習密碼加密的過程:

 package cn.tedu.knows.portal;
 
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 
 //測試類添加@SpringBootTest注解
 @SpringBootTest
 public class TestPwd {
     //利用bcrypt加密算法進行密碼編碼       提示鍵:BPE
     PasswordEncoder encoder = new BCryptPasswordEncoder();
     //加密方法
     @Test
     public void encoder(){
         //與application.properties里面配置的密碼一致
         String str = "123456";
         //對上面的密碼進行加密
         String pwd = encoder.encode(str);
         //輸出加密后的密碼
         System.out.println(pwd);
         //輸出結果:每次生成結果不一樣,這是加密算法故意的,這種現象叫“隨機加鹽”技術
         //$2a$10$KJepr.ccS6tVn8wBabdww.AS4LRKMOlk7Dqgo6DxZjq80EUWGl2q6
         //$2a$10$6Jksgy0cmEqWrNjNSlbuFOjcSwwIk7CabzfNBgv3KUM1E86.eWiH2
         //$2a$10$9H/IgyoaDC6O02aE4oShvOFgZ1i6lREVENhEj5KRVM4VdDNkrh/Uu
    }
 
     //驗證字符串是否匹配加密結果
     @Test
     public void matchTest(){
         //測試我們的密碼123456是否匹配上面方法生成的加密字符串
         //matches([明文字符串],[加密結果])返回是否匹配
         boolean b = encoder.matches("123456","$2a$10$9H/IgyoaDC6O02aE4oShvOFgZ1i6lREVENhEj5KRVM4VdDNkrh/Uu");
         System.out.println(b);//輸出true,與上面的密碼不一樣時返回false
    }
 }
 

  把加密結果(加密后的加密字符串)應用到配置文件中,使用密文密碼替換原始密碼進行保存,其中,password屬性后面多了{bcrypt},表示該密碼是用bcrypt加密算法加密后的字符串。

 # 設置Spring-Security框架的用戶名和密碼
 spring.security.user.name=admin
 spring.security.user.password={bcrypt}$2a$10$oHmgE95Z0pzIo0hKPF8L/ufqvD1D51y9waiLjx6xDX60cktZ7pFL.

  再次啟動服務,用設定前的用戶名和密碼(admin、123456)進行登錄即可。

2.3 使用java代碼配置權限管理

  登錄這個網站的用戶肯定是數據庫中的用戶,那么必須在java代碼中進行登錄而不是在配置文件中。我們先體會一下怎么在java代碼中設置用戶名和密碼,以體驗登錄效果。

在cn.tedu.knows.portal下面新建包security,包中新建類SecurityConfig,代碼如下:

 package cn.tedu.knows.portal.security;
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
 @Configuration
 //提示鍵:EGMS 啟動SpringBoot的權限管理功能,設置prePostEnabled = true,此處必須要設置
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
     //編寫一個方法,java代碼中設置用戶名密碼實現登錄
 
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.inMemoryAuthentication()
                .withUser("tom")
                .password("{bcrypt}$2a$10$9H/IgyoaDC6O02aE4oShvOFgZ1i6lREVENhEj5KRVM4VdDNkrh/Uu")
                .authorities("get");//只有擁有了此訪問資格才能訪問,否則不能訪問。一般頁面登錄后就可以訪問。
         //此處設置了新的用戶名tom和剛才密碼生成的密碼串,此級別高於application.properties里面設置的用戶名和密碼,使用此用戶名和密碼才能登錄成功
    }
 }
 

重啟服務,用tom登錄測試

(1)用戶名:admin、密碼:123456登錄,提示登錄失敗

(2)用戶名:tom、密碼:123456,登陸成功

 

  上面的.authorities中可以指定當前用戶都擁有什么資格,里面的內容可以是一個字符串,也可以是一個字符串數組,內容不固定。.authorities("get")設置了當前用戶的資格,不一定是get,也可以是 abc 等一些隨機的內容。修改SecurityConfig:

 package cn.tedu.know.portal.security;
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
 @Configuration
 //提示鍵:EGMS 啟動SpringBoot的權限管理功能,設置prePostEnabled = true,此處必須要設置
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 //繼承WebSecurityConfigurerAdapter
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
     //編寫一個方法,java代碼中設置用戶名密碼實現登錄
     //重寫configure(AuthenticationManagerBuilder auth)方法
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.inMemoryAuthentication()
                .withUser("tom") //設置用戶名
                .password("{bcrypt}$2a$10$9H/IgyoaDC6O02aE4oShvOFgZ1i6lREVENhEj5KRVM4VdDNkrh/Uu")//設置密碼
                .authorities("bbb");//此處里面的內容是資格,具有該資格才能訪問
         //此處設置了新的用戶名tom和剛才密碼生成的密碼串,此級別高於application.properties里面設置的用戶名和密碼,使用此用戶名和密碼才能登錄成功。
    }
 }

  達內知道項目需要設置這樣的資格,約束哪些用戶有哪些功能,我們需要在控制器方法中進行設置,例如下面代碼:UserController.java 。

 package cn.tedu.know.portal.controller;
 
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
  * 前端控制器
  * </p>
  *
  * @author tedu.cn
  * @since 2021-08-28
  */
 @RestController
 //為今后微服務項目方便起見,根據微服務標准,
 //將@RequestMapping("/portal/user")改為@RequestMapping("/v1/users")
 @RequestMapping("/v1/users")
 public class UserController {
     // 類上編寫RequestMapping,表示這個類中的所有控制器方法路徑都以/v1/users開頭
     // 企業中開發要求確定請求是get還是post,不推薦直接使用RequestMapping
     // get請求用@GetMapping
     // post請求用@PostMapping
     //下面的這個方法請求的全路徑為:"http://localhost:8080/v1/users/get"
     @GetMapping("/get")
     //設置要訪問這個方法需要aaa資格
     @PreAuthorize("hasAuthority('aaa')")
     public String get(){
         System.out.println("擁有aaa資格訪問的get");
         return "擁有bbb資格訪問的get";
    }
 
     /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
     //測試用戶擁有指定資格才可以訪問的方法
     //如果沒有指定特殊資格,默認登錄成功就可以訪問
     //下面的這個方法請求的全路徑為:"http://localhost:8080/v1/users/info"
     @GetMapping("/info")
     //設置要訪問這個方法需要bbb資格,和.authorities("bbb")對應
     @PreAuthorize("hasAuthority('bbb')")
     public String info(){
         System.out.println("擁有bbb資格訪問的info");
         return "擁有bbb資格訪問的info";
    }
 }

重啟啟動服務

  • 如果當前用戶擁有bbb資格,登錄后正常訪問/v1/users/info;

  • 如果當前用戶不擁有aaa資格,登錄后訪問/v1/users/get提示403錯誤

    • 403錯誤就是表示當前用戶權限不足或者沒有權限,不能訪問的意思,和404不一樣

 


免責聲明!

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



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