日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

2021最新Spring Security知识梳理

發(fā)布時(shí)間:2024/3/13 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021最新Spring Security知识梳理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2021最新Spring Security知識(shí)梳理

一、SpringSecurity 框架簡介

Spring 是非常流行和成功的 Java 應(yīng)用開發(fā)框架,Spring Security 正是 Spring 家族中的成員。Spring Security 基于 Spring 框架,提供了一套 Web 應(yīng)用安全性的完整解決方案。 正如你可能知道的關(guān)于安全方面的兩個(gè)主要區(qū)域是“認(rèn)證”和“授權(quán)”(或者訪問控制),一般來說,Web 應(yīng)用的安全性包括用戶認(rèn)證(Authentication)和用戶授權(quán)(Authorization)兩個(gè)部分,這兩點(diǎn)也是 Spring Security 重要核心功能。

1、用戶認(rèn)證指的是:驗(yàn)證某個(gè)用戶是否為系統(tǒng)中的合法主體,也就是說用戶能否訪問該系統(tǒng)。用戶認(rèn)證一般要求用戶提供用戶名和密碼。系統(tǒng)通過校驗(yàn)用戶名和密碼來完成認(rèn)證過程。通俗點(diǎn)說就是系統(tǒng)認(rèn)為用戶是否能登錄。

2、用戶授權(quán)指的是驗(yàn)證某個(gè)用戶是否有權(quán)限執(zhí)行某個(gè)操作。在一個(gè)系統(tǒng)中,不同用戶所具有的權(quán)限是不同的。比如對(duì)一個(gè)文件來說,有的用戶只能進(jìn)行讀取,而有的用戶可以進(jìn)行修改。一般來說,系統(tǒng)會(huì)為不同的用戶分配不同的角色,而每個(gè)角色則對(duì)應(yīng)一系列的權(quán)限。通俗點(diǎn)講就是系統(tǒng)判斷用戶是否有權(quán)限去做某些事情。

整理了spring全家桶學(xué)習(xí)筆記,spring家族成員的學(xué)習(xí)資料都系統(tǒng)整理好了,需要的話可以直接點(diǎn)擊領(lǐng)取

二、SpringSecurity與shiro

1、SpringSecurity特點(diǎn)

(1)和 Spring 無縫整合。

(2)全面的權(quán)限控制。

(3)專門為 Web 開發(fā)而設(shè)計(jì)。

  • 舊版本不能脫離 Web 環(huán)境使用。
  • 新版本對(duì)整個(gè)框架進(jìn)行了分層抽取,分成了核心模塊和 Web 模塊。單獨(dú)
  • 引入核心模塊就可以脫離 Web 環(huán)境。
  • 重量級(jí)

2、shiro特點(diǎn)

Apache 旗下的輕量級(jí)權(quán)限控制框架。

(1)輕量級(jí)

Shiro 主張的理念是把復(fù)雜的事情變簡單。針對(duì)對(duì)性能有更高要求的互聯(lián)網(wǎng)應(yīng)用有更好表現(xiàn)。

(2)通用性

好處:不局限于 Web 環(huán)境,可以脫離 Web 環(huán)境使用。

缺陷:在 Web 環(huán)境下一些特定的需求需要手動(dòng)編寫代碼定制。

3、SpringSecurity與shiro總結(jié)

相對(duì)于 Shiro,在 SSM 中整合 Spring Security 都是比較麻煩的操作,所以,SpringSecurity 雖然功能比 Shiro 強(qiáng)大,但是使用反而沒有 Shiro 多(Shiro 雖然功能沒有Spring Security 多,但是對(duì)于大部分項(xiàng)目而言,Shiro 也夠用了)。自從有了 Spring Boot 之后,Spring Boot 對(duì)于 Spring Security 提供了自動(dòng)化配置方案,可以使用更少的配置來使用 Spring Security。因此,一般來說,常見的安全管理技術(shù)棧的組合是這樣的:

(1)SSM + Shiro

(2)Spring Boot/Spring Cloud + Spring Security

以上只是一個(gè)推薦的組合而已,如果單純從技術(shù)上來說,無論怎么組合,都是可以運(yùn)行的。

三、Spring Security過濾器

1、Spring Security中常見過濾器

  • FilterSecurityInterceptor:是一個(gè)方法級(jí)的權(quán)限過濾器, 基本位于過濾鏈的最底部。
  • ExceptionTranslationFilter:是個(gè)異常過濾器,用來處理在認(rèn)證授權(quán)過程中拋出的異常。
  • UsernamePasswordAuthenticationFilter :對(duì)/login 的 POST 請(qǐng)求做攔截,校驗(yàn)表單中用戶
  • 名,密碼。

    2、15種過濾器

    SpringSecurity 采用的是責(zé)任鏈的設(shè)計(jì)模式,它有一條很長的過濾器鏈。現(xiàn)在對(duì)這條過濾器鏈的 15 個(gè)過濾器進(jìn)行說明:

    (1) WebAsyncManagerIntegrationFilter:將 Security 上下文與 Spring Web 中用于處理異步請(qǐng)求映射的 WebAsyncManager 進(jìn)行集成。

    (2) SecurityContextPersistenceFilter:在每次請(qǐng)求處理之前將該請(qǐng)求相關(guān)的安全上下文信息加載到 SecurityContextHolder 中,然后在該次請(qǐng)求處理完成之后,將SecurityContextHolder 中關(guān)于這次請(qǐng)求的信息存儲(chǔ)到一個(gè)“倉儲(chǔ)”中,然后將SecurityContextHolder 中的信息清除,例如Session 中維護(hù)一個(gè)用戶的安全信息就是這個(gè)過濾器處理的。

    (3) HeaderWriterFilter:用于將頭信息加入響應(yīng)中。

    (4) CsrfFilter:用于處理跨站請(qǐng)求偽造。

    (5)LogoutFilter:用于處理退出登錄。

    (6)UsernamePasswordAuthenticationFilter:用于處理基于表單的登錄請(qǐng)求,從表單中獲取用戶名和密碼。默認(rèn)情況下處理來自 /login 的請(qǐng)求。從表單中獲取用戶名和密碼時(shí),默認(rèn)使用的表單 name 值為 username 和 password,這兩個(gè)值可以通過設(shè)置這個(gè)過濾器的 usernameParameter 和 passwordParameter 兩個(gè)參數(shù)的值進(jìn)行修改。

    (7)DefaultLoginPageGeneratingFilter:如果沒有配置登錄頁面,那系統(tǒng)初始化時(shí)就會(huì)配置這個(gè)過濾器,并且用于在需要進(jìn)行登錄時(shí)生成一個(gè)登錄表單頁面。

    (8)BasicAuthenticationFilter:檢測(cè)和處理 http basic 認(rèn)證。

    (9)RequestCacheAwareFilter:用來處理請(qǐng)求的緩存。

    (10)SecurityContextHolderAwareRequestFilter:主要是包裝請(qǐng)求對(duì)象 request。

    (11)AnonymousAuthenticationFilter:檢測(cè) SecurityContextHolder 中是否存在Authentication 對(duì)象,如果不存在為其提供一個(gè)匿名 Authentication。

    (12)SessionManagementFilter:管理 session 的過濾器

    (13)ExceptionTranslationFilter:處理 AccessDeniedException 和AuthenticationException 異常。

    (14)FilterSecurityInterceptor:可以看做過濾器鏈的出口。

    (15)RememberMeAuthenticationFilter:當(dāng)用戶沒有登錄而直接訪問資源時(shí), 從 cookie里找出用戶的信息, 如果 Spring Security 能夠識(shí)別出用戶提供的 remember me cookie,用戶將不必填寫用戶名和密碼, 而是直接登錄進(jìn)入系統(tǒng),該過濾器默認(rèn)不開啟。

    3、SpringSecurity 基本流程

    Spring Security 采取過濾鏈實(shí)現(xiàn)認(rèn)證與授權(quán),只有當(dāng)前過濾器通過,才能進(jìn)入下一個(gè)過濾器:

    綠色部分是認(rèn)證過濾器,需要我們自己配置,可以配置多個(gè)認(rèn)證過濾器。認(rèn)證過濾器可以使用 Spring Security 提供的認(rèn)證過濾器,也可以自定義過濾器(例如:短信驗(yàn)證)。認(rèn)證過濾器要在 configure(HttpSecurity http)方法中配置,沒有配置不生效。

    下面會(huì)重點(diǎn)介紹以下三個(gè)過濾器: UsernamePasswordAuthenticationFilter 過濾器:該過濾器會(huì)攔截前端提交的 POST 方式的登錄表單請(qǐng)求,并進(jìn)行身份認(rèn)證。ExceptionTranslationFilter 過濾器:該過濾器不需要我們配置,對(duì)于前端提交的請(qǐng)求會(huì)直接放行,捕獲后續(xù)拋出的異常并進(jìn)行處理(例如:權(quán)限訪問限制)。FilterSecurityInterceptor 過濾器:該過濾器是過濾器鏈的最后一個(gè)過濾器,根據(jù)資源權(quán)限配置來判斷當(dāng)前請(qǐng)求是否有權(quán)限訪問對(duì)應(yīng)的資源。如果訪問受限會(huì)拋出相關(guān)異常,并 由 ExceptionTranslationFilter 過濾器進(jìn)行捕獲和處理。

    4、SpringSecurity 認(rèn)證流程

    認(rèn)證流程是在 UsernamePasswordAuthenticationFilter 過濾器中處理的,具體流程如下所示:

    四、PasswordEncoder 接口

    // 表示把參數(shù)按照特定的解析規(guī)則進(jìn)行解析 String encode(CharSequence rawPassword);// 表示驗(yàn)證從存儲(chǔ)中獲取的編碼密碼與編碼后提交的原始密碼是否匹配。如果密碼匹 配,則返回 true;如果不匹配,則返回 false。第一個(gè)參數(shù)表示需要被解析的密碼。第二個(gè) 參數(shù)表示存儲(chǔ)的密碼。 boolean matches(CharSequence rawPassword, String encodedPassword);// 表示如果解析的密碼能夠再次進(jìn)行解析且達(dá)到更安全的結(jié)果則返回 true,否則返回 false。默認(rèn)返回 false。 default boolean upgradeEncoding(String encodedPassword) {return false; }復(fù)制代碼

    BCryptPasswordEncoder 是 Spring Security 官方推薦的密碼解析器,平時(shí)多使用這個(gè)解析器。 BCryptPasswordEncoder 是對(duì) bcrypt 強(qiáng)散列方法的具體實(shí)現(xiàn)。是基于 Hash 算法實(shí)現(xiàn)的單向加密。可以通過 strength 控制加密強(qiáng)度,默認(rèn) 10。

    五、SpringBoot整合Spring Security入門

    1、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>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.guor</groupId><artifactId>securityProject</artifactId><version>0.0.1-SNAPSHOT</version><name>securityProject</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--lombok用來簡化實(shí)體類--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project> 復(fù)制代碼

    2、application.properties

    server.port=8111 #spring.security.user.name=root #spring.security.user.password=root#mysql數(shù)據(jù)庫連接 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=root 復(fù)制代碼

    3、SecurityConfig

    package com.guor.security.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String password = passwordEncoder.encode("123");auth.inMemoryAuthentication().withUser("zs").password(password).roles("admin");}@BeanPasswordEncoder password() {return new BCryptPasswordEncoder();} } 復(fù)制代碼 package com.guor.security.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.csrf.CookieCsrfTokenRepository;import javax.sql.DataSource;@Configuration public class UserSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserService userService;//注入數(shù)據(jù)源@Autowiredprivate DataSource dataSource;//配置對(duì)象@Beanpublic PersistentTokenRepository persistentTokenRepository() {JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();jdbcTokenRepository.setDataSource(dataSource);//jdbcTokenRepository.setCreateTableOnStartup(true);return jdbcTokenRepository;}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userService(userService).passwordEncoder(password());}@BeanPasswordEncoder password() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {//退出http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/hello").permitAll();//配置沒有權(quán)限訪問跳轉(zhuǎn)自定義頁面http.exceptionHandling().accessDeniedPage("/unauth.html");http.formLogin() //自定義自己編寫的登錄頁面.loginPage("/on.html") //登錄頁面設(shè)置.loginProcessingUrl("/user/login") //登錄訪問路徑.defaultSuccessUrl("/success.html").permitAll() //登錄成功之后,跳轉(zhuǎn)路徑.failureUrl("/unauth.html").and().authorizeRequests().antMatchers("/","/test/hello","/user/login").permitAll() //設(shè)置哪些路徑可以直接訪問,不需要認(rèn)證//當(dāng)前登錄用戶,只有具有admins權(quán)限才可以訪問這個(gè)路徑//1 hasAuthority方法// .antMatchers("/test/index").hasAuthority("admins")//2 hasAnyAuthority方法// .antMatchers("/test/index").hasAnyAuthority("admins,manager")//3 hasRole方法 ROLE_sale.antMatchers("/test/index").hasRole("sale").anyRequest().authenticated().and().rememberMe().tokenRepository(persistentTokenRepository()).tokenValiditySeconds(60)//設(shè)置有效時(shí)長,單位秒.userDetailsService(userService);// .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());// .and().csrf().disable(); //關(guān)閉csrf防護(hù)} } 復(fù)制代碼

    4、啟動(dòng)類

    package com.guor.security;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;@SpringBootApplication @MapperScan("com.guor.security.mapper") @EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled = true) public class SecurityProjectApplication {public static void main(String[] args) {SpringApplication.run(SecurityProjectApplication.class, args);}} 復(fù)制代碼

    5、User

    package com.guor.security.entity;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;@Data public class User {private Integer id;private String username;private String password; } 復(fù)制代碼

    6、UserService

    package com.guor.security.service;import com.guor.security.entity.User; import com.guor.security.mapper.UsersMapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service;import java.util.List;@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//調(diào)用usersMapper方法,根據(jù)用戶名查詢數(shù)據(jù)庫QueryWrapper<Users> wrapper = new QueryWrapper();// where username=?wrapper.eq("username",username);User user = userMapper.selectOne(wrapper);//判斷if(user == null) {//數(shù)據(jù)庫沒有用戶名,認(rèn)證失敗throw new UsernameNotFoundException("用戶名不存在!");}List<GrantedAuthority> auths =AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");//從查詢數(shù)據(jù)庫返回users對(duì)象,得到用戶名和密碼,返回return new User(user.getUsername(),new BCryptPasswordEncoder().encode(user.getPassword()),auths);} } 復(fù)制代碼

    7、UserMapper

    package com.guor.security.mapper;import com.guor.security.entity.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.springframework.stereotype.Repository;@Repository public interface UserMapper extends BaseMapper<User> { } 復(fù)制代碼

    8、UserController

    package com.guor.security.controller;import com.guor.security.entity.User; import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PostFilter; 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;import java.util.ArrayList; import java.util.List;@RestController @RequestMapping("/test") public class UserController {@GetMapping("hello")public String hello() {return "hello security";}@GetMapping("index")public String index() {return "hello index";}@GetMapping("update")//@Secured({"ROLE_sale","ROLE_manager"})//@PreAuthorize("hasAnyAuthority('admins')")@PostAuthorize("hasAnyAuthority('admins')")public String update() {System.out.println("update......");return "hello update";}@GetMapping("getAll")@PostAuthorize("hasAnyAuthority('admins')")@PostFilter("filterObject.username == 'admin1'")public List<Users> getAllUser(){ArrayList<Users> list = new ArrayList<>();list.add(new Users(11,"admin1","6666"));list.add(new Users(21,"admin2","888"));System.out.println(list);return list;}}復(fù)制代碼

    六、微服務(wù)認(rèn)證與授權(quán)實(shí)現(xiàn)思路

    1、如果是基于 Session,那么 Spring-security 會(huì)對(duì) cookie 里的 sessionid 進(jìn)行解析,找到服務(wù)器存儲(chǔ)的 session 信息,然后判斷當(dāng)前用戶是否符合請(qǐng)求的要求。

    2、如果是 token,則是解析出 token,然后將當(dāng)前請(qǐng)求加入到 Spring-security 管理的權(quán)限信息中去。

    如果系統(tǒng)的模塊眾多,每個(gè)模塊都需要進(jìn)行授權(quán)與認(rèn)證,所以我們選擇基于 token 的形式進(jìn)行授權(quán)與認(rèn)證,用戶根據(jù)用戶名密碼認(rèn)證成功,然后獲取當(dāng)前用戶角色的一系列權(quán)限值,并以用戶名為 key,權(quán)限列表為 value 的形式存入 redis 緩存中,根據(jù)用戶名相關(guān)信息生成 token 返回,瀏覽器將 token 記錄到 cookie 中,每次調(diào)用 api 接口都默認(rèn)將 token 攜帶到 header 請(qǐng)求頭中,Spring-security 解析 header 頭獲取 token 信息,解析 token 獲取當(dāng)前用戶名,根據(jù)用戶名就可以從 redis中獲取權(quán)限列表,這樣 Spring-security 就能夠判斷當(dāng)前請(qǐng)求是否有權(quán)限訪問。

    七、微服務(wù)代碼實(shí)例

    1、父工程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><modules><module>common</module><module>infrastructure</module><module>service</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>acl_parent</artifactId><packaging>pom</packaging><version>0.0.1-SNAPSHOT</version><name>acl_parent</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><mybatis-plus.version>3.0.5</mybatis-plus.version><velocity.version>2.0</velocity.version><swagger.version>2.7.0</swagger.version><jwt.version>0.7.0</jwt.version><fastjson.version>1.2.28</fastjson.version><gson.version>2.8.2</gson.version><json.version>20170516</json.version><cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version></properties><dependencyManagement><dependencies><!--Spring Cloud--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!--mybatis-plus 持久層--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- velocity 模板引擎, Mybatis Plus 代碼生成器需要 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>${velocity.version}</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>${gson.version}</version></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version></dependency><!--swagger ui--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency><!-- JWT --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>${json.version}</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project> 復(fù)制代碼

    2、common模塊

    common模塊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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>acl_parent</artifactId><groupId>com.atguigu</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common</artifactId><packaging>pom</packaging><modules><module>service_base</module><module>spring_security</module></modules><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>provided </scope></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><scope>provided </scope></dependency><!--lombok用來簡化實(shí)體類:需要安裝lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided </scope></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><scope>provided </scope></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><scope>provided </scope></dependency><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- spring2.X集成redis所需common-pool2--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version></dependency></dependencies></project> 復(fù)制代碼

    3、common模塊 -> SpringSecurity子模塊

    (1)核心配置類

    Spring Security 的核心配置就是繼承 WebSecurityConfigurerAdapter 并注解@EnableWebSecurity 的配置。這個(gè)配置指明了用戶名密碼的處理方式、請(qǐng)求路徑、登錄登出控制等和安全相關(guān)的配置

    package com.atguigu.security.config;import com.atguigu.security.filter.TokenAuthFilter; import com.atguigu.security.filter.TokenLoginFilter; import com.atguigu.security.security.DefaultPasswordEncoder; import com.atguigu.security.security.TokenLogoutHandler; import com.atguigu.security.security.TokenManager; import com.atguigu.security.security.UnauthEntryPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; 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.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService;@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {private TokenManager tokenManager;private RedisTemplate redisTemplate;private DefaultPasswordEncoder defaultPasswordEncoder;private UserDetailsService userDetailsService;@Autowiredpublic TokenWebSecurityConfig(UserDetailsService userDetailsService, DefaultPasswordEncoder defaultPasswordEncoder,TokenManager tokenManager, RedisTemplate redisTemplate) {this.userDetailsService = userDetailsService;this.defaultPasswordEncoder = defaultPasswordEncoder;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}/*** 配置設(shè)置* @param http* @throws Exception*///設(shè)置退出的地址和token,redis操作地址@Overrideprotected void configure(HttpSecurity http) throws Exception {http.exceptionHandling().authenticationEntryPoint(new UnauthEntryPoint())//沒有權(quán)限訪問.and().csrf().disable().authorizeRequests().anyRequest().authenticated().and().logout().logoutUrl("/admin/acl/index/logout")//退出路徑.addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate)).and().addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate)).addFilter(new TokenAuthFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();}//調(diào)用userDetailsService和密碼處理@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(defaultPasswordEncoder);}//不進(jìn)行認(rèn)證的路徑,可以直接訪問@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/api/**");} } 復(fù)制代碼

    (2)實(shí)體類

    package com.atguigu.security.entity;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;import java.io.Serializable;@Data @ApiModel(description = "用戶實(shí)體類") public class User implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "微信openid")private String username;@ApiModelProperty(value = "密碼")private String password;@ApiModelProperty(value = "昵稱")private String nickName;@ApiModelProperty(value = "用戶頭像")private String salt;@ApiModelProperty(value = "用戶簽名")private String token;} 復(fù)制代碼

    (3)過濾器

    package com.atguigu.security.filter;import com.atguigu.security.security.TokenManager; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List;public class TokenAuthFilter extends BasicAuthenticationFilter {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenAuthFilter(AuthenticationManager authenticationManager,TokenManager tokenManager,RedisTemplate redisTemplate) {super(authenticationManager);this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {//獲取當(dāng)前認(rèn)證成功用戶權(quán)限信息UsernamePasswordAuthenticationToken authRequest = getAuthentication(request);//判斷如果有權(quán)限信息,放到權(quán)限上下文中if(authRequest != null) {SecurityContextHolder.getContext().setAuthentication(authRequest);}chain.doFilter(request,response);}private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {//從header獲取tokenString token = request.getHeader("token");if(token != null) {//從token獲取用戶名String username = tokenManager.getUserInfoFromToken(token);//從redis獲取對(duì)應(yīng)權(quán)限列表List<String> permissionValueList = (List<String>)redisTemplate.opsForValue().get(username);Collection<GrantedAuthority> authority = new ArrayList<>();for(String permissionValue : permissionValueList) {SimpleGrantedAuthority auth = new SimpleGrantedAuthority(permissionValue);authority.add(auth);}return new UsernamePasswordAuthenticationToken(username,token,authority);}return null;}}復(fù)制代碼 package com.atguigu.security.filter;import com.atguigu.security.entity.SecurityUser; import com.atguigu.security.entity.User; import com.atguigu.security.security.TokenManager; import com.atguigu.utils.utils.R; import com.atguigu.utils.utils.ResponseUtil; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList;public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {private TokenManager tokenManager;private RedisTemplate redisTemplate;private AuthenticationManager authenticationManager;public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate) {this.authenticationManager = authenticationManager;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;this.setPostOnly(false);this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));}//1 獲取表單提交用戶名和密碼@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)throws AuthenticationException {//獲取表單提交數(shù)據(jù)try {User user = new ObjectMapper().readValue(request.getInputStream(), User.class);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),new ArrayList<>()));} catch (IOException e) {e.printStackTrace();throw new RuntimeException();}}//2 認(rèn)證成功調(diào)用的方法@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)throws IOException, ServletException {//認(rèn)證成功,得到認(rèn)證成功之后用戶信息SecurityUser user = (SecurityUser)authResult.getPrincipal();//根據(jù)用戶名生成tokenString token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());//把用戶名稱和用戶權(quán)限列表放到redisredisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(),user.getPermissionValueList());//返回tokenResponseUtil.out(response, R.ok().data("token",token));}//3 認(rèn)證失敗調(diào)用的方法protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)throws IOException, ServletException {ResponseUtil.out(response, R.error());} }復(fù)制代碼

    (4)security

    package com.atguigu.security.security;import com.atguigu.utils.utils.MD5; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component;@Component public class DefaultPasswordEncoder implements PasswordEncoder {public DefaultPasswordEncoder() {this(-1);}public DefaultPasswordEncoder(int strength) {}//進(jìn)行MD5加密@Overridepublic String encode(CharSequence charSequence) {return MD5.encrypt(charSequence.toString());}//進(jìn)行密碼比對(duì)@Overridepublic boolean matches(CharSequence charSequence, String encodedPassword) {return encodedPassword.equals(MD5.encrypt(charSequence.toString()));} }復(fù)制代碼 package com.atguigu.security.security;import com.atguigu.utils.utils.R; import com.atguigu.utils.utils.ResponseUtil; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutHandler;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //退出處理器 public class TokenLogoutHandler implements LogoutHandler {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenLogoutHandler(TokenManager tokenManager,RedisTemplate redisTemplate) {this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {//1 從header里面獲取token//2 token不為空,移除token,從redis刪除tokenString token = request.getHeader("token");if(token != null) {//移除tokenManager.removeToken(token);//從token獲取用戶名String username = tokenManager.getUserInfoFromToken(token);redisTemplate.delete(username);}ResponseUtil.out(response, R.ok());} } 復(fù)制代碼 package com.atguigu.security.security;import io.jsonwebtoken.CompressionCodecs; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component;import java.util.Date;@Component public class TokenManager {//token有效時(shí)長private long tokenEcpiration = 24*60*60*1000;//編碼秘鑰private String tokenSignKey = "123456";//1 使用jwt根據(jù)用戶名生成tokenpublic String createToken(String username) {String token = Jwts.builder().setSubject(username).setExpiration(new Date(System.currentTimeMillis()+tokenEcpiration)).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}//2 根據(jù)token字符串得到用戶信息public String getUserInfoFromToken(String token) {String userinfo = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getSubject();return userinfo;}//3 刪除tokenpublic void removeToken(String token) { } } 復(fù)制代碼 package com.atguigu.security.security;import com.atguigu.utils.utils.R; import com.atguigu.utils.utils.ResponseUtil; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class UnauthEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {ResponseUtil.out(httpServletResponse, R.error());} } 復(fù)制代碼

    4、common模塊 -> service_base

    (1)RedisConfig

    package com.atguigu.utils;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@EnableCaching //開啟緩存 @Configuration //配置類 public class RedisConfig extends CachingConfigurerSupport {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//解決查詢緩存轉(zhuǎn)換異常的問題ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// 配置序列化(解決亂碼的問題),過期時(shí)間600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;} } 復(fù)制代碼

    (2)SwaggerConfig

    package com.atguigu.utils;import com.google.common.base.Predicates; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration//配置類 @EnableSwagger2 //swagger注解 public class SwaggerConfig {@Beanpublic Docket webApiConfig(){return new Docket(DocumentationType.SWAGGER_2).groupName("webApi").apiInfo(webApiInfo()).select()//.paths(Predicates.not(PathSelectors.regex("/admin/.*"))).paths(Predicates.not(PathSelectors.regex("/error.*"))).build();}private ApiInfo webApiInfo(){return new ApiInfoBuilder().title("網(wǎng)站-課程中心API文檔").description("本文檔描述了課程中心微服務(wù)接口定義").version("1.0").contact(new Contact("java", "http://atguigu.com", "1123@qq.com")).build();} } 復(fù)制代碼

    (3)工具類

    package com.atguigu.utils.utils;import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;public final class MD5 {public static String encrypt(String strSrc) {try {char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9', 'a', 'b', 'c', 'd', 'e', 'f' };byte[] bytes = strSrc.getBytes();MessageDigest md = MessageDigest.getInstance("MD5");md.update(bytes);bytes = md.digest();int j = bytes.length;char[] chars = new char[j * 2];int k = 0;for (int i = 0; i < bytes.length; i++) {byte b = bytes[i];chars[k++] = hexChars[b >>> 4 & 0xf];chars[k++] = hexChars[b & 0xf];}return new String(chars);} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RuntimeException("MD5加密出錯(cuò)!!+" + e);}}public static void main(String[] args) {System.out.println(MD5.encrypt("111111"));}}復(fù)制代碼 package com.atguigu.utils.utils;import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType;import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class ResponseUtil {public static void out(HttpServletResponse response, R r) {ObjectMapper mapper = new ObjectMapper();response.setStatus(HttpStatus.OK.value());response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);try {mapper.writeValue(response.getWriter(), r);} catch (IOException e) {e.printStackTrace();}} } 復(fù)制代碼 package com.atguigu.utils.utils;import lombok.Data; import java.util.HashMap; import java.util.Map;//統(tǒng)一返回結(jié)果的類 @Data public class R {private Boolean success;private Integer code;private String message;private Map<String, Object> data = new HashMap<String, Object>();//把構(gòu)造方法私有private R() {}//成功靜態(tài)方法public static R ok() {R r = new R();r.setSuccess(true);r.setCode(20000);r.setMessage("成功");return r;}//失敗靜態(tài)方法public static R error() {R r = new R();r.setSuccess(false);r.setCode(20001);r.setMessage("失敗");return r;}public R success(Boolean success){this.setSuccess(success);return this;}public R message(String message){this.setMessage(message);return this;}public R code(Integer code){this.setCode(code);return this;}public R data(String key, Object value){this.data.put(key, value);return this;}public R data(Map<String, Object> map){this.setData(map);return this;} } 復(fù)制代碼

    5、gateway模塊

    (1)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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>infrastructure</artifactId><groupId>com.atguigu</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>api_gateway</artifactId><dependencies><dependency><groupId>com.atguigu</groupId><artifactId>service_base</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--gson--><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId></dependency><!--服務(wù)調(diào)用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies> </project> 復(fù)制代碼

    (2)application.properties

    # 端口號(hào) server.port=8222 # 服務(wù)名 spring.application.name=service-gateway # nacos服務(wù)地址 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 # 使用服務(wù)發(fā)現(xiàn)路由 spring.cloud.gateway.discovery.locator.enabled=true# 配置路由規(guī)則 spring.cloud.gateway.routes[0].id=service-acl # 設(shè)置路由uri lb://注冊(cè)服務(wù)名稱 spring.cloud.gateway.routes[0].uri=lb://service-acl # 具體路徑規(guī)則 spring.cloud.gateway.routes[0].predicates= Path=/*/acl/** 復(fù)制代碼

    (3)解決跨域

    package com.atguigu.gateway.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import org.springframework.web.util.pattern.PathPatternParser;@Configuration public class CorsConfig {//解決跨域@Beanpublic CorsWebFilter corsWebFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**",config);return new CorsWebFilter(source);} } 復(fù)制代碼

    (4)啟動(dòng)類

    package com.atguigu.gateway;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication @EnableDiscoveryClient public class ApiGatewayApplication {public static void main(String[] args) {SpringApplication.run(ApiGatewayApplication.class, args);} } 復(fù)制代碼

    6、service模塊

    (1)pom.xml

    (2)application.properties

    以菜單權(quán)限管理CRUD為例:

    (3)Permission

    (4)PermissionController

    (5)PermissionService

    (6)PermissionMapper

    (7)PermissionMapper.xml

    (8)PermissionHelper

    (9)啟動(dòng)類

    最后:

    最近我整理了整套**《JAVA核心知識(shí)點(diǎn)總結(jié)》**,說實(shí)話 ,作為一名Java程序員,不論你需不需要面試都應(yīng)該好好看下這份資料。拿到手總是不虧的~我的不少粉絲也因此拿到騰訊字節(jié)快手等公司的Offer

    進(jìn)[Java架構(gòu)資源交流群] ,找管理員獲取哦-!

    rn.PathPatternParser;

    @Configuration
    public class CorsConfig {

    //解決跨域 @Bean public CorsWebFilter corsWebFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**",config);return new CorsWebFilter(source); }

    }
    復(fù)制代碼

    (4)啟動(dòng)類

    package com.atguigu.gateway;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ApiGatewayApplication {
    public static void main(String[] args) {
    SpringApplication.run(ApiGatewayApplication.class, args);
    }
    }
    復(fù)制代碼

    ### 6、service模塊(1)pom.xml(2)application.properties以菜單權(quán)限管理CRUD為例:(3)Permission(4)PermissionController(5)PermissionService (6)PermissionMapper(7)PermissionMapper.xml(8)PermissionHelper(9)啟動(dòng)類# 最后:最近我整理了整套**《JAVA核心知識(shí)點(diǎn)總結(jié)》**,說實(shí)話 ,作為一名Java程序員,不論你需不需要面試都應(yīng)該好好看下這份資料。拿到手總是不虧的~我的不少粉絲也因此拿到騰訊字節(jié)快手等公司的Offer> <font color=Blue size=5> 進(jìn)[[Java架構(gòu)資源交流群](https://jq.qq.com/?_wv=1027&k=bH7VlCjB)] ,找管理員獲取哦-!![](https://img-blog.csdnimg.cn/20210603175857532.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phdmFfY29sYQ==,size_16,color_FFFFFF,t_70#pic_center)

    總結(jié)

    以上是生活随笔為你收集整理的2021最新Spring Security知识梳理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。